diff --git a/.github/workflows/automated_integration_test.yml b/.github/workflows/automated_integration_test.yml index 1ed5baf9f..84c680dda 100644 --- a/.github/workflows/automated_integration_test.yml +++ b/.github/workflows/automated_integration_test.yml @@ -12,7 +12,7 @@ on: jobs: Automated_integration_test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/no_print_in_dart.yaml b/.github/workflows/no_print_in_dart.yaml index b321a9cc9..9c3d82bc2 100644 --- a/.github/workflows/no_print_in_dart.yaml +++ b/.github/workflows/no_print_in_dart.yaml @@ -4,14 +4,14 @@ on: [pull_request] jobs: PR_test_build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Check for print() statements in dart code (use printV() instead) if: github.event_name == 'pull_request' run: | - GIT_GREP_OUT="$(git grep ' print(' | (grep .dart: || test $? = 1) | (grep -v print_verbose.dart || test $? = 1) || true)" + GIT_GREP_OUT="$(git grep ' print(' | (grep .dart: || test $? = 1) | (grep -v print_verbose.dart || test $? = 1) | (grep -v print_verbose_dummy.dart || test $? = 1) || true)" [[ "x$GIT_GREP_OUT" == "x" ]] && exit 0 echo "$GIT_GREP_OUT" echo "There are .dart files which use print() statements" diff --git a/.github/workflows/no_restricted_imports.yaml b/.github/workflows/no_restricted_imports.yaml index 4b17de31a..03c3de018 100644 --- a/.github/workflows/no_restricted_imports.yaml +++ b/.github/workflows/no_restricted_imports.yaml @@ -4,7 +4,7 @@ on: [pull_request] jobs: check_restricted_imports: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml index 6c72b587d..8f6139747 100644 --- a/.github/workflows/pr_test_build_android.yml +++ b/.github/workflows/pr_test_build_android.yml @@ -9,7 +9,7 @@ jobs: PR_test_build: runs-on: linux-amd64 container: - image: ghcr.io/cake-tech/cake_wallet:3.27.4-linux + image: ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.4-go1.24.1 env: STORE_PASS: test@cake_wallet KEY_PASS: test@cake_wallet @@ -274,7 +274,7 @@ jobs: - name: Build run: | - flutter build apk --release --split-per-abi + flutter build apk --dart-define=hasDevOptions=true --release --split-per-abi - name: Rename apk file run: | diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml index 9317aab34..a341aed0d 100644 --- a/.github/workflows/pr_test_build_linux.yml +++ b/.github/workflows/pr_test_build_linux.yml @@ -9,7 +9,7 @@ jobs: PR_test_build: runs-on: linux-amd64 container: - image: ghcr.io/cake-tech/cake_wallet:3.27.4-linux + image: ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.4-go1.24.1 env: STORE_PASS: test@cake_wallet KEY_PASS: test@cake_wallet @@ -22,9 +22,6 @@ jobs: - /opt/cw_cache_linux/root/.pub-cache/:/root/.pub-cache - /opt/cw_cache_linux/root/go/pkg:/root/go/pkg - /opt/cw_cache_linux/opt/generic_cache:/opt/generic_cache - strategy: - matrix: - api-level: [29] steps: - name: Fix github actions messing up $HOME... @@ -228,7 +225,7 @@ jobs: - name: Build linux run: | - flutter build linux --release + flutter build linux --dart-define=hasDevOptions=true --release - name: Compress release run: | diff --git a/.gitignore b/.gitignore index 1a11e030e..304ffe1c7 100644 --- a/.gitignore +++ b/.gitignore @@ -187,3 +187,26 @@ ios/MoneroWallet.framework/MoneroWallet ios/WowneroWallet.framework/WowneroWallet ios/ZanoWallet.framework/ZanoWallet *_libwallet2_api_c.dylib + +.flatpak-builder +cake_wallet.flatpak +flatpak-build/ + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/ephemeral/ +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/ephemeral/ +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake diff --git a/Dockerfile b/Dockerfile index d9c99da0b..84179d645 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -# docker build . -f Dockerfile -t ghcr.io/cake-tech/cake_wallet:3.27.4-linux -# docker push ghcr.io/cake-tech/cake_wallet:3.27.4-linux +# docker buildx build --push --pull --platform linux/amd64,linux/arm64 . -f Dockerfile -t ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.4-go1.24.1 # Heavily inspired by cirrusci images # https://github.com/cirruslabs/docker-images-android/blob/master/sdk/tools/Dockerfile @@ -7,13 +6,13 @@ # https://github.com/cirruslabs/docker-images-android/blob/master/sdk/34-ndk/Dockerfile # https://github.com/cirruslabs/docker-images-flutter/blob/master/sdk/Dockerfile -FROM --platform=linux/amd64 docker.io/debian:12 +FROM docker.io/debian:12 LABEL org.opencontainers.image.source=https://github.com/cake-tech/cake_wallet # Set necessary environment variables # Set Go version to latest known-working version -ENV GOLANG_VERSION=1.23.4 +ENV GOLANG_VERSION=1.24.1 # Pin Flutter version to latest known-working version ENV FLUTTER_VERSION=3.27.4 @@ -60,11 +59,20 @@ RUN set -o xtrace \ ffmpeg network-manager x11-utils xvfb psmisc \ # aarch64-linux-gnu dependencies g++-aarch64-linux-gnu gcc-aarch64-linux-gnu \ + # x86_64-linux-gnu dependencies + g++-x86-64-linux-gnu gcc-x86-64-linux-gnu \ + # flatpak dependencies + flatpak flatpak-builder binutils elfutils patch unzip xz-utils zstd \ && apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ && sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' \ && locale-gen \ && update-locale LANG=en_US.UTF-8 +ENV FLATPAK_RUNTIME_VERSION=24.08 +RUN flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo \ + && flatpak install -y flathub org.freedesktop.Platform//${FLATPAK_RUNTIME_VERSION} \ + && flatpak install -y flathub org.freedesktop.Sdk//${FLATPAK_RUNTIME_VERSION} + # Install nodejs for Github Actions RUN curl -fsSL https://deb.nodesource.com/setup_23.x | bash - && \ apt-get install -y --no-install-recommends nodejs && \ @@ -74,14 +82,28 @@ RUN curl -fsSL https://deb.nodesource.com/setup_23.x | bash - && \ ENV PATH=${PATH}:/usr/local/go/bin:${HOME}/go/bin ENV GOROOT=/usr/local/go ENV GOPATH=${HOME}/go -RUN wget https://go.dev/dl/go${GOLANG_VERSION}.linux-amd64.tar.gz &&\ - rm -rf /usr/local/go &&\ - tar -C /usr/local -xzf go${GOLANG_VERSION}.linux-amd64.tar.gz && \ +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + wget https://go.dev/dl/go${GOLANG_VERSION}.linux-amd64.tar.gz -O go.tar.gz; \ + elif [ "$ARCH" = "aarch64" ]; then \ + wget https://go.dev/dl/go${GOLANG_VERSION}.linux-arm64.tar.gz -O go.tar.gz; \ + else \ + echo "Unsupported architecture: $ARCH"; exit 1; \ + fi && \ + rm -rf /usr/local/go && \ + tar -C /usr/local -xzf go.tar.gz && \ + rm go.tar.gz && \ go install golang.org/x/mobile/cmd/gomobile@latest && \ gomobile init +RUN git config --global user.email "czarek@cakewallet.com" \ + && git config --global user.name "CakeWallet CI" + + # Install Android SDK commandline tools and emulator -RUN wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip -O android-sdk-tools.zip \ +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" != "x86_64" ]; then exit 0; fi \ + && wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip -O android-sdk-tools.zip \ && mkdir -p ${ANDROID_HOME}/cmdline-tools/ \ && unzip -q android-sdk-tools.zip -d ${ANDROID_HOME}/cmdline-tools/ \ && mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \ @@ -94,14 +116,17 @@ RUN wget -q https://dl.google.com/android/repository/commandlinetools-linux-${AN && sdkmanager platform-tools \ && mkdir -p ${HOME}/.android \ && touch ${HOME}/.android/repositories.cfg \ - && git config --global user.email "czarek@cakewallet.com" \ - && git config --global user.name "CakeWallet CI" + # Handle emulator not being available on linux/arm64 (https://issuetracker.google.com/issues/227219818) -RUN if [ $(uname -m) == "x86_64" ]; then sdkmanager emulator ; fi +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" != "x86_64" ]; then exit 0; fi \ + && sdkmanager emulator # Pre-install extra Android SDK dependencies in order to not have to download them for each build -RUN yes | sdkmanager \ +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" != "x86_64" ]; then exit 0; fi \ + && yes | sdkmanager \ "platforms;android-$ANDROID_PLATFORM_VERSION" \ "build-tools;$ANDROID_BUILD_TOOLS_VERSION" \ "platforms;android-33" \ @@ -114,12 +139,16 @@ RUN yes | sdkmanager \ # Install extra NDK dependency for sp_scanner ENV ANDROID_NDK_VERSION=27.2.12479018 -RUN yes | sdkmanager "ndk;$ANDROID_NDK_VERSION" \ +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" != "x86_64" ]; then exit 0; fi \ + && yes | sdkmanager "ndk;$ANDROID_NDK_VERSION" \ "ndk;27.0.12077973" # Install dependencies for tests # Comes from https://github.com/ReactiveCircus/android-emulator-runner -RUN yes | sdkmanager \ +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" != "x86_64" ]; then exit 0; fi \ + && yes | sdkmanager \ "system-images;android-29;default;x86_64" \ "system-images;android-31;default;x86_64" \ "platforms;android-29" \ @@ -135,7 +164,7 @@ RUN (addgroup kvm || true) && \ ENV PATH=${HOME}/.cargo/bin:${PATH} RUN curl https://sh.rustup.rs -sSf | bash -s -- -y && \ cargo install cargo-ndk && \ - for target in aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android x86_64-unknown-linux-gnu; \ + for target in aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu aarch64-unknown-linux-gnu; \ do \ rustup target add --toolchain stable $target; \ done diff --git a/assets/faq/faq_pl.json b/assets/faq/faq_pl.json index a38d79068..b41841cd8 100644 --- a/assets/faq/faq_pl.json +++ b/assets/faq/faq_pl.json @@ -13,7 +13,7 @@ }, { "question" : "Co oznaczają słowa „seed” i „keys”?", - "answer" : "Twoje klucze kodują prywatne informacje w twoim portfelu i pozwalają wydać monety i zobaczyć przychodzące transakcje.\nTwoje ziarno to tylko wersja twojego klucza prywatnego napisana w sposób, który łatwiej Ci zapisać. Wasze nasiona i klucze są w rzeczywistości takie same, tylko w różnych formach!\nNigdy nie dawaj nikomu swojego ziarna ani kluczy. Twoje fundusze zostaną skradzione, jeśli wydasz swoje nasiona lub klucze. Zapisz jednak swoje ziarno i przechowuj je w bezpiecznym miejscu (pozwoli to przywrócić portfel, jeśli zgubisz telefon).\n" + "answer" : "Twoje klucze i fraza seed zawierają prywatne informacje o twoim portfelu i pozwalają wysyłać kryptowalutę oraz zobaczyć przychodzące transakcje.\nFraza „seed” to wersja twojego klucza prywatnego napisana w sposób, który łatwiej Ci zapisać. Wasze frazy seed i klucze są w rzeczywistości takie same, tylko w różnych formach zapisu!\nNigdy nie dawaj nikomu swojej frazy seed ani swoich kluczy. Twoje fundusze zostaną skradzione, jeśli upublicznisz frazę seed lub klucze. Zapisz jednak swoją frazę seed i przechowuj ją w bezpiecznym miejscu (pozwoli to przywrócić portfel, jeśli zgubisz telefon).\n" }, { "question" : "Ile portfeli mogę utworzyć?", @@ -24,11 +24,11 @@ "answer" : "Stuknij menu •••, wybierz „Portfele”, a następnie „Przywróć portfel”. Następnie wprowadź dane początkowe (lub klucze) i opcjonalnie wprowadź datę przed pierwszą transakcją w portfelu (przyspieszy to proces synchronizacji .) Może być konieczne pozostawienie aplikacji otwartej przez 15-30 minut, aby całkowicie przywrócić portfel.\n" }, { - "question" : "Co mogę zrobić, jeśli stracę nasiona?", - "answer" : "Jeśli zapomniałeś o nasieniu, prawdopodobnie gdzieś je zapisałeś. Sprawdź swoje notatki i rozejrzyj się po komputerze. Jeśli nie możesz go nigdzie znaleźć, być może utworzono kopię zapasową Cake Wallet (w takim przypadku będziesz mógł przywrócić dane z tej kopii zapasowej). Jeśli żadna z tych czynności nie działa, niestety nic nie możemy zrobić.\n" + "question" : "Co mogę zrobić, jeśli zapomniałem frazę seed?", + "answer" : "Jeśli zapomniałeś swoją frazę seed, prawdopodobnie gdzieś je zapisałeś. Sprawdź swoje notatki i rozejrzyj się po komputerze. Jeśli nie możesz go nigdzie znaleźć, być może utworzono kopię zapasową Cake Wallet (w takim przypadku będziesz mógł przywrócić dane z tej kopii zapasowej). Jeśli żadna z tych czynności nie działa, niestety nic nie możemy zrobić.\n" }, { - "question" : "Czy zbierasz jakieś informacje o moim portfelu?", + "question" : "Czy zbieracie jakieś informacje o moim portfelu?", "answer" : "Portfel Cake NIE gromadzi ani nie rejestruje żadnych informacji o Twoim portfelu. Dbamy o Twoją prywatność.\n" }, { @@ -37,7 +37,7 @@ }, { "question" : "Co to są „podadresy” i jak z nich korzystać?", - "answer" : "Podadres jest w zasadzie unikalnym adresem, który można wygenerować w dowolnym momencie. Monety wysłane do niego nadal będą pojawiać się w głównym portfelu, ale osoba wysyłająca monety nie może podać Twojego głównego adresu. Podadresy zawsze zaczynają się od „8”.\nMożesz utworzyć nowy podadres na ekranie Odbieranie, dotykając „+” obok przycisku Podadresy. Wprowadź nazwę podadresu i dotknij „Dodaj”. Następnie dotknij nazwy podadresu, gdy chcesz go użyć!\nJeśli jesteś paranoikiem, prawdopodobnie za każdym razem, gdy otrzymasz Monero, powinieneś utworzyć nowy podadres.\n" + "answer" : "Podadres jest w unikalnym adresem, który można wygenerować w dowolnym momencie. Monety wysłane do niego nadal będą pojawiać się w głównym portfelu, ale osoba wysyłająca monety nie zna Twojego głównego adresu. Podadresy zawsze zaczynają się od „8”.\nMożesz utworzyć nowy podadres na ekranie Odbieranie, dotykając „+” obok przycisku Podadresy. Wprowadź nazwę podadresu i dotknij „Dodaj”. Następnie dotknij nazwy podadresu, gdy chcesz go użyć!\nJeśli jesteś paranoikiem, prawdopodobnie za każdym razem, gdy otrzymasz Monero, powinieneś utworzyć nowy podadres.\n" }, { "question" : "Co to jest ID transakcji?", diff --git a/assets/images/cake_logo.png b/assets/images/cake_logo.png index 8a85bf225..abbb4e62b 100644 Binary files a/assets/images/cake_logo.png and b/assets/images/cake_logo.png differ diff --git a/assets/images/cakewallet_android_icon.png b/assets/images/cakewallet_android_icon.png old mode 100755 new mode 100644 index 59cc69414..7f15c62f5 Binary files a/assets/images/cakewallet_android_icon.png and b/assets/images/cakewallet_android_icon.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-anydpi-v26/ic_launcher.xml b/assets/images/cakewallet_android_icon/mipmap-anydpi-v26/ic_launcher.xml index c8bd4b26c..345888d26 100644 --- a/assets/images/cakewallet_android_icon/mipmap-anydpi-v26/ic_launcher.xml +++ b/assets/images/cakewallet_android_icon/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,6 @@ - - - + + + \ No newline at end of file diff --git a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher.png b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher.png index 10d0a1a82..89c9b0571 100644 Binary files a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher.png and b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_back.png b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_back.png deleted file mode 100644 index 5b0fde827..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_back.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_fore.png b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_fore.png deleted file mode 100644 index 9c16f0a27..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_fore.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_mono.png deleted file mode 100644 index 27f939b41..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_mono.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_background.png b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_background.png new file mode 100644 index 000000000..19669488f Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_background.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_foreground.png b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..1411a5da5 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_monochrome.png b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_monochrome.png new file mode 100644 index 000000000..1411a5da5 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_monochrome.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher.png b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher.png index 8c59ec33e..8f1d1c28b 100644 Binary files a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher.png and b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_back.png b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_back.png deleted file mode 100644 index 5d25e42e7..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_back.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_fore.png b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_fore.png deleted file mode 100644 index 021fe65de..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_fore.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_mono.png deleted file mode 100644 index 7bdb298c1..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_mono.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_background.png b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_background.png new file mode 100644 index 000000000..75025cfd5 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_background.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_foreground.png b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..e8c47adb3 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_monochrome.png b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_monochrome.png new file mode 100644 index 000000000..e8c47adb3 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_monochrome.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher.png b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher.png index 10c3acd7f..f775a8fac 100644 Binary files a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher.png and b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_back.png b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_back.png deleted file mode 100644 index c4b66dc58..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_back.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_fore.png b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_fore.png deleted file mode 100644 index b440b154d..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_fore.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_mono.png deleted file mode 100644 index 79e9df08d..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_mono.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_background.png b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_background.png new file mode 100644 index 000000000..9784f16c8 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_background.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_foreground.png b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..6ba8eb301 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_monochrome.png b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_monochrome.png new file mode 100644 index 000000000..6ba8eb301 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_monochrome.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher.png b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher.png index 813a3678d..31458fa02 100644 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher.png and b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_back.png b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_back.png deleted file mode 100644 index 75dc0219d..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_back.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_fore.png b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_fore.png deleted file mode 100644 index 90afb19e8..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_fore.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_mono.png deleted file mode 100644 index 0bb1c7430..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_mono.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_background.png b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_background.png new file mode 100644 index 000000000..04ef206c8 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_background.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_foreground.png b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..cc93d633b Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_monochrome.png b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_monochrome.png new file mode 100644 index 000000000..cc93d633b Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_monochrome.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher.png b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher.png index 671422b96..158afbbf9 100644 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher.png and b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_back.png b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_back.png deleted file mode 100644 index 46b1e2cb1..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_back.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png deleted file mode 100644 index 0a2025220..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png deleted file mode 100644 index 205f2ad2a..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png and /dev/null differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_background.png b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_background.png new file mode 100644 index 000000000..66a5487a2 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_background.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_foreground.png b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..0ecd56e8c Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_monochrome.png b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_monochrome.png new file mode 100644 index 000000000..0ecd56e8c Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_monochrome.png differ diff --git a/assets/images/cakewallet_app_logo.png b/assets/images/cakewallet_app_logo.png deleted file mode 100644 index 59cc69414..000000000 Binary files a/assets/images/cakewallet_app_logo.png and /dev/null differ diff --git a/assets/images/cakewallet_icon_1024.png b/assets/images/cakewallet_icon_1024.png index 64682cd1d..35cf42245 100644 Binary files a/assets/images/cakewallet_icon_1024.png and b/assets/images/cakewallet_icon_1024.png differ diff --git a/assets/images/cakewallet_icon_120.png b/assets/images/cakewallet_icon_120.png index 1a2c1b99c..6e45f6423 100644 Binary files a/assets/images/cakewallet_icon_120.png and b/assets/images/cakewallet_icon_120.png differ diff --git a/assets/images/cakewallet_icon_180.png b/assets/images/cakewallet_icon_180.png index ff69a866a..da585ca42 100644 Binary files a/assets/images/cakewallet_icon_180.png and b/assets/images/cakewallet_icon_180.png differ diff --git a/assets/images/cakewallet_logo.png b/assets/images/cakewallet_logo.png index bf6896ad2..c465fa26c 100644 Binary files a/assets/images/cakewallet_logo.png and b/assets/images/cakewallet_logo.png differ diff --git a/assets/images/deuro_icon.png b/assets/images/deuro_icon.png new file mode 100644 index 000000000..4dc068ff8 Binary files /dev/null and b/assets/images/deuro_icon.png differ diff --git a/assets/nano_node_list.yml b/assets/nano_node_list.yml index be550177e..cda931b5e 100644 --- a/assets/nano_node_list.yml +++ b/assets/nano_node_list.yml @@ -1,9 +1,9 @@ - uri: nano.nownodes.io useSSL: true - is_default: true - uri: rpc.nano.to + is_default: true useSSL: true - uri: node.nautilus.io diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt index d1f91139b..5b2a9f873 100644 --- a/assets/text/Monerocom_Release_Notes.txt +++ b/assets/text/Monerocom_Release_Notes.txt @@ -1,3 +1,5 @@ -UI/UX enhancements -Stability improvements +Add background sync to Monero +Enhance Backup files +Improve app usability and user experience +User interface enhancements Bug fixes \ No newline at end of file diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt index 0f8118b4e..1a5986bd4 100644 --- a/assets/text/Release_Notes.txt +++ b/assets/text/Release_Notes.txt @@ -1 +1,8 @@ -Update for Zano's Hard fork \ No newline at end of file +Add background sync to Monero +Add Decred Wallet +Remove Haven Wallet +Fix and Improve Solana Wallet +Enhance Backup files +Improve app usability and user experience +User interface enhancements +Bug fixes \ No newline at end of file diff --git a/com.cakewallet.CakeWallet.yml b/com.cakewallet.CakeWallet.yml index 83efa1388..98ce19caf 100644 --- a/com.cakewallet.CakeWallet.yml +++ b/com.cakewallet.CakeWallet.yml @@ -1,6 +1,6 @@ app-id: com.cakewallet.CakeWallet runtime: org.freedesktop.Platform -runtime-version: '22.08' +runtime-version: '24.08' sdk: org.freedesktop.Sdk command: cake_wallet separate-locales: false @@ -15,8 +15,6 @@ finish-args: modules: - name: cake_wallet buildsystem: simple - only-arches: - - x86_64 build-commands: - "cp -R bundle /app/cake_wallet" - "chmod +x /app/cake_wallet/cake_wallet" @@ -28,7 +26,7 @@ modules: - "cp com.cakewallet.CakeWallet.desktop /app/share/applications" sources: - type: dir - path: build/linux/x64/release + path: build/linux/current/release - type: file path: assets/images/cakewallet_icon_180.png - type: file diff --git a/cw_bitcoin/lib/electrum_balance.dart b/cw_bitcoin/lib/electrum_balance.dart index 41526dddd..a035393c1 100644 --- a/cw_bitcoin/lib/electrum_balance.dart +++ b/cw_bitcoin/lib/electrum_balance.dart @@ -69,6 +69,6 @@ class ElectrumBalance extends Balance { 'unconfirmed': unconfirmed, 'frozen': frozen, 'secondConfirmed': secondConfirmed, - 'secondUnconfirmed': secondUnconfirmed + 'secondUnconfirmed': secondUnconfirmed, }); } diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart index 00d49c288..cb8485ec5 100644 --- a/cw_core/lib/crypto_currency.dart +++ b/cw_core/lib/crypto_currency.dart @@ -110,7 +110,8 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen CryptoCurrency.wow, CryptoCurrency.zano, CryptoCurrency.ton, - CryptoCurrency.flip + CryptoCurrency.flip, + CryptoCurrency.deuro ]; static const havenCurrencies = [ @@ -231,6 +232,7 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen static const ton = CryptoCurrency(title: 'TON', fullName: 'Toncoin', raw: 95, name: 'ton', iconPath: 'assets/images/ton_icon.png', decimals: 8); static const zano = CryptoCurrency(title: 'ZANO', tag: 'ZANO', fullName: 'Zano', raw: 96, name: 'zano', iconPath: 'assets/images/zano_icon.png', decimals: 12); static const flip = CryptoCurrency(title: 'FLIP', tag: 'ETH', fullName: 'Chainflip', raw: 97, name: 'flip', iconPath: 'assets/images/flip_icon.png', decimals: 18); + static const deuro = CryptoCurrency(title: 'DEURO', tag: 'ETH', fullName: 'Digital Euro', raw: 98, name: 'deuro', iconPath: 'assets/images/deuro_icon.png', decimals: 18); static final Map _rawCurrencyMap = [...all, ...havenCurrencies].fold>({}, (acc, item) { diff --git a/cw_core/lib/erc20_token.dart b/cw_core/lib/erc20_token.dart index f8c2afc06..e47488143 100644 --- a/cw_core/lib/erc20_token.dart +++ b/cw_core/lib/erc20_token.dart @@ -20,6 +20,8 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin { final String? iconPath; @HiveField(6) final String? tag; + @HiveField(7, defaultValue: false) + final bool isPotentialScam; bool get enabled => _enabled; @@ -33,14 +35,17 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin { bool enabled = true, this.iconPath, this.tag, + this.isPotentialScam = false, }) : _enabled = enabled, super( - name: symbol.toLowerCase(), - title: symbol.toUpperCase(), - fullName: name, - tag: tag, - iconPath: iconPath, - decimals: decimal); + name: symbol.toLowerCase(), + title: symbol.toUpperCase(), + fullName: name, + tag: tag, + iconPath: iconPath, + decimals: decimal, + isPotentialScam: isPotentialScam, + ); Erc20Token.copyWith(Erc20Token other, String? icon, String? tag) : this.name = other.name, @@ -50,6 +55,7 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin { this._enabled = other.enabled, this.tag = tag, this.iconPath = icon, + this.isPotentialScam = other.isPotentialScam, super( name: other.name, title: other.symbol.toUpperCase(), @@ -57,6 +63,7 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin { tag: tag, iconPath: icon, decimals: other.decimal, + isPotentialScam: other.isPotentialScam, ); static const typeId = ERC20_TOKEN_TYPE_ID; diff --git a/cw_core/lib/utils/print_verbose.dart b/cw_core/lib/utils/print_verbose.dart index de7cc8557..42014d609 100644 --- a/cw_core/lib/utils/print_verbose.dart +++ b/cw_core/lib/utils/print_verbose.dart @@ -1,4 +1,5 @@ import 'dart:math'; +import 'package:flutter/foundation.dart'; void printV(dynamic content) { CustomTrace programInfo = CustomTrace(StackTrace.current); @@ -20,7 +21,7 @@ class CustomTrace { try { _parseTrace(); } catch (e) { - print("Unable to parse trace (printV): $e"); + if (kDebugMode) print("Unable to parse trace (printV): $e"); } } @@ -80,7 +81,7 @@ class CustomTrace { columnStr = columnStr.replaceFirst(")", ""); this.columnNumber = int.tryParse(columnStr); } catch (e) { - print("Unable to parse trace (printV): $e"); + if (kDebugMode) print("Unable to parse trace (printV): $e"); } } } diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart index 6ac2458b7..c36537594 100644 --- a/cw_core/lib/wallet_base.dart +++ b/cw_core/lib/wallet_base.dart @@ -39,6 +39,8 @@ abstract class WalletBase get balance; + String formatCryptoAmount(String amount) => amount; + SyncStatus get syncStatus; set syncStatus(SyncStatus status); diff --git a/cw_decred/lib/api/libdcrwallet.dart b/cw_decred/lib/api/libdcrwallet.dart index 6a26e64c6..b5e5bbe73 100644 --- a/cw_decred/lib/api/libdcrwallet.dart +++ b/cw_decred/lib/api/libdcrwallet.dart @@ -3,7 +3,6 @@ import 'dart:ffi'; import 'dart:io'; import 'dart:async'; import 'dart:isolate'; -import 'package:flutter/foundation.dart'; import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_decred/api/libdcrwallet_bindings.dart'; import 'package:cw_decred/api/util.dart'; @@ -79,10 +78,12 @@ class Libwallet { switch (method) { case "initlibdcrwallet": final logDir = args["logdir"] ?? ""; + final level = args["level"] ?? ""; final cLogDir = logDir.toCString(); + final cLevel = level.toCString(); executePayloadFn( - fn: () => dcrwalletApi.initialize(cLogDir), - ptrsToFree: [cLogDir], + fn: () => dcrwalletApi.initialize(cLogDir, cLevel), + ptrsToFree: [cLogDir, cLevel], ); break; case "createwallet": @@ -300,7 +301,7 @@ class Libwallet { break; case "shutdown": final name = args["name"] ?? ""; - final cName = name.toCString(); + // final cName = name.toCString(); executePayloadFn( fn: () => dcrwalletApi.shutdown(), ptrsToFree: [], @@ -326,8 +327,8 @@ class Libwallet { // initLibdcrwallet initializes libdcrwallet using the provided logDir and gets // it ready for use. This must be done before attempting to create, load or use - // a wallet. - Future initLibdcrwallet(String logDir) async { + // a wallet. An empty string can be used to log to stdout and create no log files. + Future initLibdcrwallet(String logDir, String level) async { if (_closed) throw StateError('Closed'); final completer = Completer.sync(); final id = _idCounter++; @@ -335,6 +336,7 @@ class Libwallet { final req = { "method": "initlibdcrwallet", "logdir": logDir, + "level": level, }; _commands.send((id, req)); await completer.future; @@ -463,7 +465,11 @@ class Libwallet { }; _commands.send((id, req)); final res = await completer.future as PayloadResult; - return jsonDecode(res.payload); + try { + return jsonDecode(res.payload); + } catch (_) { + return {}; + } } Future estimateFee(String walletName, int numBlocks) async { diff --git a/cw_decred/lib/wallet.dart b/cw_decred/lib/wallet.dart index 5ffa2023a..c94f5425d 100644 --- a/cw_decred/lib/wallet.dart +++ b/cw_decred/lib/wallet.dart @@ -380,7 +380,7 @@ abstract class DecredWalletBase extends WalletBase> fetchFiveTransactions(int from) async { - final res = await _libwallet.listTransactions(walletInfo.name, from.toString(), "5"); - final decoded = json.decode(res); - var txs = {}; - for (final d in decoded) { - final txid = uniqueTxID(d["txid"] ?? "", d["vout"] ?? 0); - var direction = TransactionDirection.outgoing; - if (d["category"] == "receive") { - direction = TransactionDirection.incoming; + try { + final res = await _libwallet.listTransactions(walletInfo.name, from.toString(), "5"); + final decoded = json.decode(res); + var txs = {}; + for (final d in decoded) { + final txid = uniqueTxID(d["txid"] ?? "", d["vout"] ?? 0); + var direction = TransactionDirection.outgoing; + if (d["category"] == "receive") { + direction = TransactionDirection.incoming; + } + final amountDouble = d["amount"] ?? 0.0; + final amount = (amountDouble * 1e8).round().abs(); + final feeDouble = d["fee"] ?? 0.0; + final fee = (feeDouble * 1e8).round().abs(); + final confs = d["confirmations"] ?? 0; + final sendTime = d["time"] ?? 0; + final height = d["height"] ?? 0; + final txInfo = DecredTransactionInfo( + id: txid, + amount: amount, + fee: fee, + direction: direction, + isPending: confs == 0, + date: DateTime.fromMillisecondsSinceEpoch(sendTime * 1000, isUtc: false), + height: height, + confirmations: confs, + to: d["address"] ?? "", + ); + txs[txid] = txInfo; } - final amountDouble = d["amount"] ?? 0.0; - final amount = (amountDouble * 1e8).toInt().abs(); - final feeDouble = d["fee"] ?? 0.0; - final fee = (feeDouble * 1e8).toInt().abs(); - final confs = d["confirmations"] ?? 0; - final sendTime = d["time"] ?? 0; - final height = d["height"] ?? 0; - final txInfo = DecredTransactionInfo( - id: txid, - amount: amount, - fee: fee, - direction: direction, - isPending: confs == 0, - date: DateTime.fromMillisecondsSinceEpoch(sendTime * 1000, isUtc: false), - height: height, - confirmations: confs, - to: d["address"] ?? "", - ); - txs[txid] = txInfo; + return txs; + } catch (e) { + printV(e); + return {}; } - return txs; } // uniqueTxID combines the tx id and vout to create a unique id. @@ -612,21 +617,25 @@ abstract class DecredWalletBase extends WalletBase fetchUnspents() async { - final res = await _libwallet.listUnspents(walletInfo.name); - final decoded = json.decode(res); - var unspents = []; - for (final d in decoded) { - final spendable = d["spendable"] ?? false; - if (!spendable) { - continue; + try { + final res = await _libwallet.listUnspents(walletInfo.name); + final decoded = json.decode(res); + var unspents = []; + for (final d in decoded) { + final spendable = d["spendable"] ?? false; + if (!spendable) { + continue; + } + final amountDouble = d["amount"] ?? 0.0; + final amount = (amountDouble * 1e8).round().abs(); + final utxo = Unspent(d["address"] ?? "", d["txid"] ?? "", amount, d["vout"] ?? 0, null); + utxo.isChange = d["ischange"] ?? false; + unspents.add(utxo); } - final amountDouble = d["amount"] ?? 0.0; - final amount = (amountDouble * 1e8).toInt().abs(); - final utxo = Unspent(d["address"] ?? "", d["txid"] ?? "", amount, d["vout"] ?? 0, null); - utxo.isChange = d["ischange"] ?? false; - unspents.add(utxo); + _unspents = unspents; + } catch (e) { + printV(e); } - _unspents = unspents; } List unspents() { diff --git a/cw_decred/lib/wallet_addresses.dart b/cw_decred/lib/wallet_addresses.dart index 10970b2d6..860a576d9 100644 --- a/cw_decred/lib/wallet_addresses.dart +++ b/cw_decred/lib/wallet_addresses.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:cw_core/utils/print_verbose.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/address_info.dart'; @@ -103,13 +104,18 @@ abstract class DecredWalletAddressesBase extends WalletAddresses with Store { if (this.isEnabledAutoGenerateSubaddress) { nUnused = "3"; } - final res = await _libwallet.addresses(walletInfo.name, nUsed, nUnused); - final decoded = json.decode(res); - final usedAddrs = List.from(decoded["used"] ?? []); - final unusedAddrs = List.from(decoded["unused"] ?? []); - // index is the index of the first unused address. - final index = decoded["index"] ?? 0; - return new LibAddresses(usedAddrs, unusedAddrs, index); + try { + final res = await _libwallet.addresses(walletInfo.name, nUsed, nUnused); + final decoded = json.decode(res); + final usedAddrs = List.from(decoded["used"] ?? []); + final unusedAddrs = List.from(decoded["unused"] ?? []); + // index is the index of the first unused address. + final index = decoded["index"] ?? 0; + return new LibAddresses(usedAddrs, unusedAddrs, index); + } catch (e) { + printV(e); + return LibAddresses([], [], 0); + } } Future generateNewAddress(String label) async { diff --git a/cw_decred/lib/wallet_service.dart b/cw_decred/lib/wallet_service.dart index a54833321..161184b0a 100644 --- a/cw_decred/lib/wallet_service.dart +++ b/cw_decred/lib/wallet_service.dart @@ -27,17 +27,16 @@ class DecredWalletService extends WalletService< static final pubkeyRestorePathTestnet = "m/44'/1'/0'"; final mainnet = "mainnet"; final testnet = "testnet"; - Libwallet? libwallet; + static Libwallet? libwallet; Future init() async { if (libwallet != null) { return; } libwallet = await Libwallet.spawn(); - // Use the general path for all dcr wallets as the general log directory. - // Individual wallet paths may be removed if the wallet is deleted. - final dcrLogDir = await pathForWalletDir(name: '', type: WalletType.decred); - libwallet!.initLibdcrwallet(dcrLogDir); + // Init logging with no directory to force printing to stdout and only + // print ERROR level logs. + libwallet!.initLibdcrwallet("", "err"); } void closeLibwallet() { diff --git a/cw_ethereum/lib/default_ethereum_erc20_tokens.dart b/cw_ethereum/lib/default_ethereum_erc20_tokens.dart index ee60a3d6c..8381744d6 100644 --- a/cw_ethereum/lib/default_ethereum_erc20_tokens.dart +++ b/cw_ethereum/lib/default_ethereum_erc20_tokens.dart @@ -17,6 +17,13 @@ class DefaultEthereumErc20Tokens { decimal: 6, enabled: true, ), + Erc20Token( + name: "Digital Euro", + symbol: "DEURO", + contractAddress: "0xbA3f535bbCcCcA2A154b573Ca6c5A49BAAE0a3ea", + decimal: 18, + enabled: true, + ), Erc20Token( name: "Dai", symbol: "DAI", diff --git a/cw_ethereum/lib/ethereum_wallet.dart b/cw_ethereum/lib/ethereum_wallet.dart index 765ace052..ae6158557 100644 --- a/cw_ethereum/lib/ethereum_wallet.dart +++ b/cw_ethereum/lib/ethereum_wallet.dart @@ -115,6 +115,7 @@ class EthereumWallet extends EVMChainWallet { enabled: token.enabled, tag: token.tag ?? "ETH", iconPath: iconPath, + isPotentialScam: token.isPotentialScam, ); } diff --git a/cw_evm/lib/evm_chain_wallet.dart b/cw_evm/lib/evm_chain_wallet.dart index 8b858286e..800bf745b 100644 --- a/cw_evm/lib/evm_chain_wallet.dart +++ b/cw_evm/lib/evm_chain_wallet.dart @@ -628,13 +628,13 @@ abstract class EVMChainWalletBase extends WalletBase< Future addErc20Token(Erc20Token token) async { String? iconPath; - if (token.iconPath == null || token.iconPath!.isEmpty) { + if ((token.iconPath == null || token.iconPath!.isEmpty) && !token.isPotentialScam) { try { iconPath = CryptoCurrency.all .firstWhere((element) => element.title.toUpperCase() == token.symbol.toUpperCase()) .iconPath; } catch (_) {} - } else { + } else if (!token.isPotentialScam) { iconPath = token.iconPath; } diff --git a/cw_monero/example/linux/flutter/generated_plugin_registrant.cc b/cw_monero/example/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 1936c88a6..000000000 --- a/cw_monero/example/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include - -void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) cw_monero_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "CwMoneroPlugin"); - cw_monero_plugin_register_with_registrar(cw_monero_registrar); -} diff --git a/cw_monero/example/linux/flutter/generated_plugin_registrant.h b/cw_monero/example/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47bc..000000000 --- a/cw_monero/example/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/cw_monero/example/linux/flutter/generated_plugins.cmake b/cw_monero/example/linux/flutter/generated_plugins.cmake deleted file mode 100644 index efcc9a8f9..000000000 --- a/cw_monero/example/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - cw_monero -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/cw_monero/lib/api/account_list.dart b/cw_monero/lib/api/account_list.dart index 0e55ce15c..28b00c925 100644 --- a/cw_monero/lib/api/account_list.dart +++ b/cw_monero/lib/api/account_list.dart @@ -7,7 +7,8 @@ bool get isViewOnly => int.tryParse(monero.Wallet_secretSpendKey(wptr!)) == 0; int _wlptrForW = 0; monero.WalletListener? _wlptr = null; -monero.WalletListener getWlptr() { +monero.WalletListener? getWlptr() { + if (wptr == null) return null; if (wptr!.address == _wlptrForW) return _wlptr!; _wlptrForW = wptr!.address; _wlptr = monero.MONERO_cw_getWalletListener(wptr!); diff --git a/cw_monero/lib/api/coins_info.dart b/cw_monero/lib/api/coins_info.dart index ef7d3cfd6..83382f001 100644 --- a/cw_monero/lib/api/coins_info.dart +++ b/cw_monero/lib/api/coins_info.dart @@ -1,21 +1,42 @@ +import 'dart:ffi'; +import 'dart:isolate'; + import 'package:cw_monero/api/account_list.dart'; import 'package:monero/monero.dart' as monero; +import 'package:mutex/mutex.dart'; monero.Coins? coins = null; +final coinsMutex = Mutex(); -void refreshCoins(int accountIndex) { +Future refreshCoins(int accountIndex) async { + if (coinsMutex.isLocked) { + return; + } coins = monero.Wallet_coins(wptr!); - monero.Coins_refresh(coins!); + final coinsPtr = coins!.address; + await coinsMutex.acquire(); + await Isolate.run(() => monero.Coins_refresh(Pointer.fromAddress(coinsPtr))); + coinsMutex.release(); } -int countOfCoins() => monero.Coins_count(coins!); +Future countOfCoins() async { + await coinsMutex.acquire(); + final count = monero.Coins_count(coins!); + coinsMutex.release(); + return count; +} -monero.CoinsInfo getCoin(int index) => monero.Coins_coin(coins!, index); +Future getCoin(int index) async { + await coinsMutex.acquire(); + final coin = monero.Coins_coin(coins!, index); + coinsMutex.release(); + return coin; +} -int? getCoinByKeyImage(String keyImage) { - final count = countOfCoins(); +Future getCoinByKeyImage(String keyImage) async { + final count = await countOfCoins(); for (int i = 0; i < count; i++) { - final coin = getCoin(i); + final coin = await getCoin(i); final coinAddress = monero.CoinsInfo_keyImage(coin); if (keyImage == coinAddress) { return i; @@ -24,6 +45,16 @@ int? getCoinByKeyImage(String keyImage) { return null; } -void freezeCoin(int index) => monero.Coins_setFrozen(coins!, index: index); +Future freezeCoin(int index) async { + await coinsMutex.acquire(); + final coinsPtr = coins!.address; + await Isolate.run(() => monero.Coins_setFrozen(Pointer.fromAddress(coinsPtr), index: index)); + coinsMutex.release(); +} -void thawCoin(int index) => monero.Coins_thaw(coins!, index: index); +Future thawCoin(int index) async { + await coinsMutex.acquire(); + final coinsPtr = coins!.address; + await Isolate.run(() => monero.Coins_thaw(Pointer.fromAddress(coinsPtr), index: index)); + coinsMutex.release(); +} diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index 854ee01c3..a51e415a9 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -1,6 +1,7 @@ import 'dart:ffi'; import 'dart:isolate'; +import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_monero/api/account_list.dart'; import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart'; import 'package:cw_monero/api/monero_output.dart'; @@ -13,15 +14,23 @@ import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen; import 'package:mutex/mutex.dart'; +Map> txKeys = {}; String getTxKey(String txId) { + txKeys[wptr!.address] ??= {}; + if (txKeys[wptr!.address]![txId] != null) { + return txKeys[wptr!.address]![txId]!; + } final txKey = monero.Wallet_getTxKey(wptr!, txid: txId); final status = monero.Wallet_status(wptr!); if (status != 0) { - final error = monero.Wallet_errorString(wptr!); + monero.Wallet_errorString(wptr!); + txKeys[wptr!.address]![txId] = ""; return ""; } + txKeys[wptr!.address]![txId] = txKey; return txKey; } + final txHistoryMutex = Mutex(); monero.TransactionHistory? txhistory; bool isRefreshingTx = false; @@ -34,6 +43,7 @@ Future refreshTransactions() async { await Isolate.run(() { monero.TransactionHistory_refresh(Pointer.fromAddress(ptr)); }); + await Future.delayed(Duration.zero); txHistoryMutex.release(); isRefreshingTx = false; } @@ -45,8 +55,24 @@ Future> getAllTransactions() async { await txHistoryMutex.acquire(); txhistory ??= monero.Wallet_history(wptr!); + final startAddress = txhistory!.address * wptr!.address; int size = countOfTransactions(); - final list = List.generate(size, (index) => Transaction(txInfo: monero.TransactionHistory_transaction(txhistory!, index: index))); + final list = []; + for (int index = 0; index < size; index++) { + if (index % 25 == 0) { + // Give main thread a chance to do other things. + await Future.delayed(Duration.zero); + } + if (txhistory!.address * wptr!.address != startAddress) { + printV("Loop broken because txhistory!.address * wptr!.address != startAddress"); + break; + } + final txInfo = monero.TransactionHistory_transaction(txhistory!, index: index); + final txHash = monero.TransactionInfo_hash(txInfo); + txCache[wptr!.address] ??= {}; + txCache[wptr!.address]![txHash] = Transaction(txInfo: txInfo); + list.add(txCache[wptr!.address]![txHash]!); + } txHistoryMutex.release(); final accts = monero.Wallet_numSubaddressAccounts(wptr!); for (var i = 0; i < accts; i++) { @@ -79,8 +105,18 @@ Future> getAllTransactions() async { return list; } -Transaction getTransaction(String txId) { - return Transaction(txInfo: monero.TransactionHistory_transactionById(txhistory!, txid: txId)); +Map> txCache = {}; +Future getTransaction(String txId) async { + if (txCache[wptr!.address] != null && txCache[wptr!.address]![txId] != null) { + return txCache[wptr!.address]![txId]!; + } + await txHistoryMutex.acquire(); + final tx = monero.TransactionHistory_transactionById(txhistory!, txid: txId); + final txDart = Transaction(txInfo: tx); + txCache[wptr!.address] ??= {}; + txCache[wptr!.address]![txId] = txDart; + txHistoryMutex.release(); + return txDart; } Future createTransactionSync( @@ -161,31 +197,39 @@ Future createTransactionSync( ); } -PendingTransactionDescription createTransactionMultDestSync( +Future createTransactionMultDest( {required List outputs, required String paymentId, required int priorityRaw, int accountIndex = 0, - List preferredInputs = const []}) { + List preferredInputs = const []}) async { final dstAddrs = outputs.map((e) => e.address).toList(); final amounts = outputs.map((e) => monero.Wallet_amountFromString(e.amount)).toList(); - // printV("multDest: dstAddrs: $dstAddrs"); - // printV("multDest: amounts: $amounts"); + final waddr = wptr!.address; + + // force reconnection in case the os killed the connection + Isolate.run(() async { + monero.Wallet_synchronized(Pointer.fromAddress(waddr)); + }); + + final txptr = Pointer.fromAddress(await Isolate.run(() { + return monero.Wallet_createTransactionMultDest( + Pointer.fromAddress(waddr), + dstAddr: dstAddrs, + isSweepAll: false, + amounts: amounts, + mixinCount: 0, + pendingTransactionPriority: priorityRaw, + subaddr_account: accountIndex, + ).address; + })); - final txptr = monero.Wallet_createTransactionMultDest( - wptr!, - dstAddr: dstAddrs, - isSweepAll: false, - amounts: amounts, - mixinCount: 0, - pendingTransactionPriority: priorityRaw, - subaddr_account: accountIndex, - ); if (monero.PendingTransaction_status(txptr) != 0) { throw CreationTransactionException(message: monero.PendingTransaction_errorString(txptr)); } + return PendingTransactionDescription( amount: monero.PendingTransaction_amount(txptr), fee: monero.PendingTransaction_fee(txptr), @@ -255,21 +299,6 @@ Future _createTransactionSync(Map args) async { preferredInputs: preferredInputs); } -PendingTransactionDescription _createTransactionMultDestSync(Map args) { - final outputs = args['outputs'] as List; - final paymentId = args['paymentId'] as String; - final priorityRaw = args['priorityRaw'] as int; - final accountIndex = args['accountIndex'] as int; - final preferredInputs = args['preferredInputs'] as List; - - return createTransactionMultDestSync( - outputs: outputs, - paymentId: paymentId, - priorityRaw: priorityRaw, - accountIndex: accountIndex, - preferredInputs: preferredInputs); -} - Future createTransaction( {required String address, required int priorityRaw, @@ -286,21 +315,6 @@ Future createTransaction( 'preferredInputs': preferredInputs }); -Future createTransactionMultDest( - {required List outputs, - required int priorityRaw, - String paymentId = '', - int accountIndex = 0, - List preferredInputs = const []}) async => - _createTransactionMultDestSync({ - 'outputs': outputs, - 'paymentId': paymentId, - 'priorityRaw': priorityRaw, - 'accountIndex': accountIndex, - 'preferredInputs': preferredInputs - }); - - class Transaction { final String displayLabel; late final String subaddressLabel = monero.Wallet_getSubaddressLabel( diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index 755887652..f520c6599 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'dart:ffi'; import 'dart:isolate'; -import 'package:cw_core/root_dir.dart'; import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_monero/api/account_list.dart'; import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart'; +import 'package:cw_monero/api/wallet_manager.dart'; import 'package:flutter/foundation.dart'; import 'package:monero/monero.dart' as monero; import 'package:mutex/mutex.dart'; @@ -21,14 +21,18 @@ int getSyncingHeight() { } bool isNeededToRefresh() { - final ret = monero.MONERO_cw_WalletListener_isNeedToRefresh(getWlptr()); - monero.MONERO_cw_WalletListener_resetNeedToRefresh(getWlptr()); + final wlptr = getWlptr(); + if (wlptr == null) return false; + final ret = monero.MONERO_cw_WalletListener_isNeedToRefresh(wlptr); + monero.MONERO_cw_WalletListener_resetNeedToRefresh(wlptr); return ret; } bool isNewTransactionExist() { - final ret = monero.MONERO_cw_WalletListener_isNewTransactionExist(getWlptr()); - monero.MONERO_cw_WalletListener_resetIsNewTransactionExist(getWlptr()); + final wlptr = getWlptr(); + if (wlptr == null) return false; + final ret = monero.MONERO_cw_WalletListener_isNewTransactionExist(wlptr); + monero.MONERO_cw_WalletListener_resetIsNewTransactionExist(wlptr); return ret; } @@ -75,22 +79,28 @@ String? getSeedLanguage(String? language) { String getSeedLegacy(String? language) { final cakepassphrase = getPassphrase(); - var legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase); language = getSeedLanguage(language); + var legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase); if (monero.Wallet_status(wptr!) != 0) { - if (language != null) { - monero.Wallet_setSeedLanguage(wptr!, language: language); - final status = monero.Wallet_status(wptr!); - if (status != 0) { - final err = monero.Wallet_errorString(wptr!); - if (legacy.isNotEmpty) { - return "$err\n\n$legacy"; - } - return err; + if (monero.Wallet_errorString(wptr!).contains("seed_language")) { + monero.Wallet_setSeedLanguage(wptr!, language: "English"); + legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase); + } + } + + if (language != null) { + monero.Wallet_setSeedLanguage(wptr!, language: language); + final status = monero.Wallet_status(wptr!); + if (status != 0) { + final err = monero.Wallet_errorString(wptr!); + if (legacy.isNotEmpty) { + return "$err\n\n$legacy"; } + return err; } legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase); } + if (monero.Wallet_status(wptr!) != 0) { final err = monero.Wallet_errorString(wptr!); if (legacy.isNotEmpty) { @@ -193,12 +203,15 @@ void startRefreshSync() { } -void setRefreshFromBlockHeight({required int height}) => - monero.Wallet_setRefreshFromBlockHeight(wptr!, - refresh_from_block_height: height); +void setRefreshFromBlockHeight({required int height}) { + monero.Wallet_setRefreshFromBlockHeight(wptr!, + refresh_from_block_height: height); +} -void setRecoveringFromSeed({required bool isRecovery}) => - monero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery); +void setRecoveringFromSeed({required bool isRecovery}) { + monero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery); + monero.Wallet_store(wptr!); +} final storeMutex = Mutex(); @@ -388,4 +401,6 @@ String signMessage(String message, {String address = ""}) { bool verifyMessage(String message, String address, String signature) { return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature); -} \ No newline at end of file +} + +Map> debugCallLength() => monero.debugCallLength; diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart index bfebe4247..b43773447 100644 --- a/cw_monero/lib/api/wallet_manager.dart +++ b/cw_monero/lib/api/wallet_manager.dart @@ -89,11 +89,7 @@ void createWalletSync( throw WalletCreationException(message: monero.Wallet_errorString(newWptr)); } - monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: ''); - status = monero.Wallet_status(newWptr); - if (status != 0) { - throw WalletCreationException(message: monero.Wallet_errorString(newWptr)); - } + setupBackgroundSync(password, newWptr); wptr = newWptr; monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase); @@ -141,6 +137,7 @@ void restoreWalletFromSeedSync( wptr = newWptr; setRefreshFromBlockHeight(height: restoreHeight); + setupBackgroundSync(password, newWptr); monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase); @@ -186,13 +183,6 @@ void restoreWalletFromKeysSync( message: monero.Wallet_errorString(newWptr)); } - - monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: ''); - status = monero.Wallet_status(newWptr); - if (status != 0) { - throw WalletCreationException(message: monero.Wallet_errorString(newWptr)); - } - // CW-712 - Try to restore deterministic wallet first, if the view key doesn't // match the view key provided if (spendKey != "") { @@ -216,12 +206,8 @@ void restoreWalletFromKeysSync( throw WalletRestoreFromKeysException( message: monero.Wallet_errorString(newWptr)); } - - monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: ''); - status = monero.Wallet_status(newWptr); - if (status != 0) { - throw WalletCreationException(message: monero.Wallet_errorString(newWptr)); - } + + setupBackgroundSync(password, newWptr); } } @@ -267,12 +253,8 @@ void restoreWalletFromPolyseedWithOffset( monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed); monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: seedOffset); monero.Wallet_store(wptr!); - - monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: ''); - status = monero.Wallet_status(newWptr); - if (status != 0) { - throw WalletCreationException(message: monero.Wallet_errorString(newWptr)); - } + + setupBackgroundSync(password, newWptr); storeSync(); openedWalletsByPath[path] = wptr!; @@ -323,12 +305,8 @@ void restoreWalletFromSpendKeySync( monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed); storeSync(); - - monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: ''); - status = monero.Wallet_status(newWptr); - if (status != 0) { - throw WalletCreationException(message: monero.Wallet_errorString(newWptr)); - } + + setupBackgroundSync(password, newWptr); openedWalletsByPath[path] = wptr!; _lastOpenedWallet = path; @@ -361,13 +339,6 @@ Future restoreWalletFromHardwareWallet( throw WalletRestoreFromSeedException(message: error); } - // TODO: Check with upstream if we can use background sync here - // monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: ''); - // status = monero.Wallet_status(newWptr); - // if (status != 0) { - // throw WalletCreationException(message: monero.Wallet_errorString(newWptr)); - // } - wptr = newWptr; _lastOpenedWallet = path; openedWalletsByPath[path] = wptr!; @@ -437,12 +408,8 @@ Future loadWallet( printV("loadWallet:"+err); throw WalletOpeningException(message: err); } - monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: ''); - status = monero.Wallet_status(newWptr); - if (status != 0) { - final err = monero.Wallet_errorString(newWptr); - printV("loadWallet:"+err); - throw WalletOpeningException(message: err); + if (deviceType == 0) { + setupBackgroundSync(password, newWptr); } wptr = newWptr; @@ -451,6 +418,17 @@ Future loadWallet( } } +void setupBackgroundSync(String password, Pointer? wptrOverride) { + if (isViewOnlyBySpendKey(wptrOverride)) { + return; + } + monero.Wallet_setupBackgroundSync(wptrOverride ?? wptr!, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: ''); + if (monero.Wallet_status(wptrOverride ?? wptr!) != 0) { + // We simply ignore the error. + printV("setupBackgroundSync: ${monero.Wallet_errorString(wptrOverride ?? wptr!)}"); + } +} + void _createWallet(Map args) { final path = args['path'] as String; final password = args['password'] as String; @@ -591,4 +569,4 @@ Future restoreFromSpendKey( bool isWalletExist({required String path}) => _isWalletExist(path); -bool isViewOnlyBySpendKey() => int.tryParse(monero.Wallet_secretSpendKey(wptr!)) == 0; +bool isViewOnlyBySpendKey(Pointer? wptrOverride) => int.tryParse(monero.Wallet_secretSpendKey(wptrOverride ?? wptr!)) == 0; diff --git a/cw_monero/lib/monero_account_list.dart b/cw_monero/lib/monero_account_list.dart index aa23e276f..82a0efd32 100644 --- a/cw_monero/lib/monero_account_list.dart +++ b/cw_monero/lib/monero_account_list.dart @@ -1,5 +1,6 @@ import 'package:cw_core/monero_amount_format.dart'; import 'package:cw_core/utils/print_verbose.dart'; +import 'package:cw_monero/api/wallet_manager.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/account.dart'; import 'package:cw_monero/api/account_list.dart' as account_list; @@ -44,7 +45,18 @@ abstract class MoneroAccountListBase with Store { } } - List getAll() => account_list.getAllAccount().map((accountRow) { + Map> _cachedAccounts = {}; + + List getAll() { + final allAccounts = account_list.getAllAccount(); + final currentCount = allAccounts.length; + _cachedAccounts[account_list.wptr!.address] ??= []; + + if (_cachedAccounts[account_list.wptr!.address]!.length == currentCount) { + return _cachedAccounts[account_list.wptr!.address]!; + } + + _cachedAccounts[account_list.wptr!.address] = allAccounts.map((accountRow) { final balance = monero.SubaddressAccountRow_getUnlockedBalance(accountRow); return Account( @@ -53,6 +65,9 @@ abstract class MoneroAccountListBase with Store { balance: moneroAmountToString(amount: monero.Wallet_amountFromString(balance)), ); }).toList(); + + return _cachedAccounts[account_list.wptr!.address]!; + } Future addAccount({required String label}) async { await account_list.addAccount(label: label); diff --git a/cw_monero/lib/monero_unspent.dart b/cw_monero/lib/monero_unspent.dart index 8a104edf4..292c76dbe 100644 --- a/cw_monero/lib/monero_unspent.dart +++ b/cw_monero/lib/monero_unspent.dart @@ -7,28 +7,33 @@ class MoneroUnspent extends Unspent { MoneroUnspent( String address, String hash, String keyImage, int value, bool isFrozen, this.isUnlocked) : super(address, hash, value, 0, keyImage) { + getCoinByKeyImage(keyImage).then((coinId) { + if (coinId == null) return; + getCoin(coinId).then((coin) { + _frozen = monero.CoinsInfo_frozen(coin); + }); + }); } + bool _frozen = false; + @override set isFrozen(bool freeze) { printV("set isFrozen: $freeze ($keyImage): $freeze"); - final coinId = getCoinByKeyImage(keyImage!); - if (coinId == null) throw Exception("Unable to find a coin for address $address"); - if (freeze) { - freezeCoin(coinId); - } else { - thawCoin(coinId); - } + getCoinByKeyImage(keyImage!).then((coinId) async { + if (coinId == null) return; + if (freeze) { + await freezeCoin(coinId); + _frozen = true; + } else { + await thawCoin(coinId); + _frozen = false; + } + }); } @override - bool get isFrozen { - printV("get isFrozen"); - final coinId = getCoinByKeyImage(keyImage!); - if (coinId == null) throw Exception("Unable to find a coin for address $address"); - final coin = getCoin(coinId); - return monero.CoinsInfo_frozen(coin); - } + bool get isFrozen => _frozen; final bool isUnlocked; } diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart index 224d2cf88..8d5bb154f 100644 --- a/cw_monero/lib/monero_wallet.dart +++ b/cw_monero/lib/monero_wallet.dart @@ -3,6 +3,7 @@ import 'dart:ffi'; import 'dart:io'; import 'dart:isolate'; +import 'package:cw_core/monero_amount_format.dart'; import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/account.dart'; @@ -168,6 +169,7 @@ abstract class MoneroWalletBase extends WalletBase> fetchTransactions() async { - transaction_history.refreshTransactions(); - return (await _getAllTransactionsOfAccount(walletAddresses.account?.id)) + await transaction_history.refreshTransactions(); + final resp = (await _getAllTransactionsOfAccount(walletAddresses.account?.id)) .fold>( {}, (Map acc, MoneroTransactionInfo tx) { acc[tx.id] = tx; return acc; }); + return resp; } Future updateTransactions() async { @@ -708,8 +714,17 @@ abstract class MoneroWalletBase extends WalletBase + transactionHistory.transactions.remove(id)); + + // Add or update transactions + transactions.forEach((key, tx) => + transactionHistory.transactions[key] = tx); await transactionHistory.save(); _isTransactionUpdating = false; } catch (e) { @@ -776,6 +791,7 @@ abstract class MoneroWalletBase extends WalletBase openWallet(String name, String password, {bool? retryOnFailure}) async { + Future openWallet(String name, String password, {OpenWalletTry openWalletTry = OpenWalletTry.initial}) async { try { final path = await pathForWallet(name: name, type: getType()); @@ -153,31 +159,28 @@ class MoneroWalletService extends WalletService< walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource, password: password); - final isValid = wallet.walletAddresses.validate(); if (wallet.isHardwareWallet) { wallet.setLedgerConnection(gLedger!); gLedger = null; } - if (!isValid) { - await restoreOrResetWalletFiles(name); - wallet.close(shouldCleanup: false); - return openWallet(name, password); - } - await wallet.init(); return wallet; } catch (e) { // TODO: Implement Exception for wallet list service. - if (retryOnFailure == false) { - rethrow; + switch (openWalletTry) { + case OpenWalletTry.initial: + await restoreOrResetWalletFiles(name); + return await openWallet(name, password, openWalletTry: OpenWalletTry.cacheRestored); + case OpenWalletTry.cacheRestored: + await removeCache(name); + return await openWallet(name, password, openWalletTry: OpenWalletTry.cacheRemoved); + case OpenWalletTry.cacheRemoved: + rethrow; } - - await restoreOrResetWalletFiles(name); - return await openWallet(name, password, retryOnFailure: false); } } diff --git a/cw_monero/linux/flutter/generated_plugin_registrant.cc b/cw_monero/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index e71a16d23..000000000 --- a/cw_monero/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,11 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - - -void fl_register_plugins(FlPluginRegistry* registry) { -} diff --git a/cw_monero/linux/flutter/generated_plugin_registrant.h b/cw_monero/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47bc..000000000 --- a/cw_monero/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/cw_monero/linux/flutter/generated_plugins.cmake b/cw_monero/linux/flutter/generated_plugins.cmake deleted file mode 100644 index 2e1de87a7..000000000 --- a/cw_monero/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/cw_polygon/lib/polygon_wallet.dart b/cw_polygon/lib/polygon_wallet.dart index 4db24b32a..d2b62ca4d 100644 --- a/cw_polygon/lib/polygon_wallet.dart +++ b/cw_polygon/lib/polygon_wallet.dart @@ -68,6 +68,7 @@ class PolygonWallet extends EVMChainWallet { enabled: token.enabled, tag: token.tag ?? "MATIC", iconPath: iconPath, + isPotentialScam: token.isPotentialScam, ); } diff --git a/cw_solana/lib/spl_token.dart b/cw_solana/lib/spl_token.dart index 97538a706..fe793bbf6 100644 --- a/cw_solana/lib/spl_token.dart +++ b/cw_solana/lib/spl_token.dart @@ -6,6 +6,7 @@ part 'spl_token.g.dart'; @HiveType(typeId: SPLToken.typeId) class SPLToken extends CryptoCurrency with HiveObjectMixin { + @override @HiveField(0) final String name; @@ -24,12 +25,18 @@ class SPLToken extends CryptoCurrency with HiveObjectMixin { @HiveField(5) final String mint; + @override @HiveField(6) final String? iconPath; + @override @HiveField(7) final String? tag; + @override + @HiveField(8, defaultValue: false) + final bool isPotentialScam; + SPLToken({ required this.name, required this.symbol, @@ -39,6 +46,7 @@ class SPLToken extends CryptoCurrency with HiveObjectMixin { this.iconPath, this.tag = 'SOL', bool enabled = true, + this.isPotentialScam = false, }) : _enabled = enabled, super( name: mint.toLowerCase(), @@ -47,6 +55,7 @@ class SPLToken extends CryptoCurrency with HiveObjectMixin { tag: tag, iconPath: iconPath, decimals: decimal, + isPotentialScam: isPotentialScam, ); factory SPLToken.fromMetadata({ @@ -55,6 +64,7 @@ class SPLToken extends CryptoCurrency with HiveObjectMixin { required String symbol, required String mintAddress, String? iconPath, + bool isPotentialScam = false, }) { return SPLToken( name: name, @@ -63,28 +73,14 @@ class SPLToken extends CryptoCurrency with HiveObjectMixin { decimal: 0, mint: mint, iconPath: iconPath, + isPotentialScam: isPotentialScam, ); } - factory SPLToken.cryptoCurrency({ - required String name, - required String symbol, - required int decimals, - required String iconPath, - required String mint, - }) { - return SPLToken( - name: name, - symbol: symbol, - decimal: decimals, - mint: mint, - iconPath: iconPath, - mintAddress: '', - ); - } - + @override bool get enabled => _enabled; + @override set enabled(bool value) => _enabled = value; SPLToken.copyWith(SPLToken other, String? icon, String? tag) @@ -96,6 +92,7 @@ class SPLToken extends CryptoCurrency with HiveObjectMixin { mint = other.mint, tag = other.tag, iconPath = icon, + isPotentialScam = other.isPotentialScam, super( title: other.symbol.toUpperCase(), name: other.symbol.toLowerCase(), @@ -103,6 +100,7 @@ class SPLToken extends CryptoCurrency with HiveObjectMixin { fullName: other.name, tag: other.tag, iconPath: icon, + isPotentialScam: other.isPotentialScam, ); static const typeId = SPL_TOKEN_TYPE_ID; diff --git a/cw_tron/lib/tron_token.dart b/cw_tron/lib/tron_token.dart index 8c45ab486..182b84884 100644 --- a/cw_tron/lib/tron_token.dart +++ b/cw_tron/lib/tron_token.dart @@ -25,10 +25,13 @@ class TronToken extends CryptoCurrency with HiveObjectMixin { @HiveField(5) final String? iconPath; - + @HiveField(6) final String? tag; + @HiveField(7, defaultValue: false) + final bool isPotentialScam; + bool get enabled => _enabled; set enabled(bool value) => _enabled = value; @@ -41,14 +44,17 @@ class TronToken extends CryptoCurrency with HiveObjectMixin { bool enabled = true, this.iconPath, this.tag = 'TRX', + this.isPotentialScam = false, }) : _enabled = enabled, super( - name: symbol.toLowerCase(), - title: symbol.toUpperCase(), - fullName: name, - tag: tag, - iconPath: iconPath, - decimals: decimal); + name: symbol.toLowerCase(), + title: symbol.toUpperCase(), + fullName: name, + tag: tag, + iconPath: iconPath, + decimals: decimal, + isPotentialScam: isPotentialScam, + ); TronToken.copyWith(TronToken other, String? icon, String? tag) : name = other.name, @@ -58,6 +64,7 @@ class TronToken extends CryptoCurrency with HiveObjectMixin { _enabled = other.enabled, tag = tag ?? other.tag, iconPath = icon ?? other.iconPath, + isPotentialScam = other.isPotentialScam, super( name: other.name, title: other.symbol.toUpperCase(), @@ -65,6 +72,7 @@ class TronToken extends CryptoCurrency with HiveObjectMixin { tag: tag ?? other.tag, iconPath: icon ?? other.iconPath, decimals: other.decimal, + isPotentialScam: other.isPotentialScam, ); static const typeId = TRON_TOKEN_TYPE_ID; diff --git a/cw_tron/lib/tron_wallet.dart b/cw_tron/lib/tron_wallet.dart index a25c97e3a..e02bae933 100644 --- a/cw_tron/lib/tron_wallet.dart +++ b/cw_tron/lib/tron_wallet.dart @@ -509,11 +509,15 @@ abstract class TronWalletBase extends WalletBase addTronToken(TronToken token) async { String? iconPath; - try { - iconPath = CryptoCurrency.all - .firstWhere((element) => element.title.toUpperCase() == token.symbol.toUpperCase()) - .iconPath; - } catch (_) {} + if ((token.iconPath == null || token.iconPath!.isEmpty) && !token.isPotentialScam) { + try { + iconPath = CryptoCurrency.all + .firstWhere((element) => element.title.toUpperCase() == token.symbol.toUpperCase()) + .iconPath; + } catch (_) {} + } else if (!token.isPotentialScam) { + iconPath = token.iconPath; + } final newToken = TronToken( name: token.name, @@ -523,6 +527,7 @@ abstract class TronWalletBase extends WalletBase> debugCallLength() => wownero.debugCallLength; \ No newline at end of file diff --git a/cw_wownero/lib/wownero_wallet.dart b/cw_wownero/lib/wownero_wallet.dart index c33231dba..2bb95217e 100644 --- a/cw_wownero/lib/wownero_wallet.dart +++ b/cw_wownero/lib/wownero_wallet.dart @@ -770,4 +770,9 @@ abstract class WowneroWalletBase extends WalletBase _closeWallet(int hWallet) async { }); printV("Closing wallet: $str"); return str; -} \ No newline at end of file +} + +Map> debugCallLength() => zano.debugCallLength; \ No newline at end of file diff --git a/devtools_options.yaml b/devtools_options.yaml deleted file mode 100644 index 7e7e7f67d..000000000 --- a/devtools_options.yaml +++ /dev/null @@ -1 +0,0 @@ -extensions: diff --git a/docs/builds/ANDROID.md b/docs/builds/ANDROID.md index 9e4e75685..226883679 100644 --- a/docs/builds/ANDROID.md +++ b/docs/builds/ANDROID.md @@ -8,8 +8,6 @@ You can find the latest instructions for installing Docker on your given OS on t - -NOTE: If building on a Mac with an M-series CPU (arm64), you may encounter segmentation faults when building. If you do, simply retry the build. - ## Building Cake Wallet or Monero.com ### Using the pre-built builder image @@ -20,8 +18,8 @@ In order to build the latest version of Cake Wallet, simply run the following: git clone --branch main https://github.com/cake-tech/cake_wallet.git # NOTE: Replace `main` with the latest release tag available at https://github.com/cake-tech/cake_wallet/releases/latest. cd cake_wallet -# docker build -t ghcr.io/cake-tech/cake_wallet:main-linux . # Uncomment to build the docker image yourself instead of pulling it from the registry -docker run -v$(pwd):$(pwd) -w $(pwd) -i --rm ghcr.io/cake-tech/cake_wallet:main-linux bash -x << EOF +# docker build -t ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.4-go1.24.1 . # Uncomment to build the docker image yourself instead of pulling it from the registry +docker run -v$(pwd):$(pwd) -w $(pwd) -i --rm ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.4-go1.24.1 bash -x << EOF set -x -e pushd scripts/android source ./app_env.sh cakewallet diff --git a/docs/builds/LINUX.md b/docs/builds/LINUX.md index cd8466e6d..a97a269a5 100644 --- a/docs/builds/LINUX.md +++ b/docs/builds/LINUX.md @@ -20,8 +20,8 @@ In order to build the latest version of Cake Wallet, simply run the following: git clone --branch main https://github.com/cake-tech/cake_wallet.git # NOTE: Replace `main` with the latest release tag available at https://github.com/cake-tech/cake_wallet/releases/latest. cd cake_wallet -# docker build -t ghcr.io/cake-tech/cake_wallet:main-linux . # Uncomment to build the docker image yourself instead of pulling it from the registry -docker run -v$(pwd):$(pwd) -w $(pwd) -i --rm ghcr.io/cake-tech/cake_wallet:main-linux bash -x << EOF +# docker build -t ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.4-go1.24.1 . # Uncomment to build the docker image yourself instead of pulling it from the registry +docker run --privileged -v$(pwd):$(pwd) -w $(pwd) -i --rm ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.4-go1.24.1 bash -x << EOF set -x -e pushd scripts ./gen_android_manifest.sh @@ -37,6 +37,13 @@ flutter clean dart run tool/generate_localization.dart dart run tool/generate_new_secrets.dart flutter build linux +cp -r build/linux/x64 build/linux/current +# use line below if you are building on arm64 +# cp -r build/linux/arm64 build/linux/current +# If you want to build flatpak you need --privileged flag +flatpak-builder --force-clean flatpak-build com.cakewallet.CakeWallet.yml +flatpak build-export export flatpak-build +flatpak build-bundle export build/linux/current/cake_wallet.flatpak com.cakewallet.CakeWallet EOF ``` @@ -51,46 +58,11 @@ Building Linux application... ✓ Built build/linux/x64/release/bundle/cake_wallet ``` -Final builds can be found in `build/linux/x64/release/bundle/` as seen above. +Final builds can be found in `build/linux/current/release/bundle/` as seen above. -## Flatpak (optional) - -To package the built binaries as a flatpak, you need first to install `flatpak` and `flatpak-builder`: - -```bash -sudo apt install flatpak flatpak-builder -``` - -Add the necessary Flathub: - -```bash -flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo -``` - -Then need to install freedesktop runtime and sdk: - -```bash -flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08 -``` - -Next, build the flatpak bundle: - -```bash -flatpak-builder --force-clean flatpak-build com.cakewallet.CakeWallet.yml -``` - -And then export bundle: - -```bash -flatpak build-export export flatpak-build -flatpak build-bundle export cake_wallet.flatpak com.cakewallet.CakeWallet -``` - -The Flatpak file, `cake_wallet.flatpak`, should be generated in the current directory. - To install the newly built Flatpak, run: ```bash -flatpak --user install cake_wallet.flatpak +flatpak --user install build/linux/current/cake_wallet.flatpak ``` diff --git a/ios/Podfile.lock b/ios/Podfile.lock index fc70b4fb6..d3ba59827 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,9 +2,7 @@ PODS: - connectivity_plus (0.0.1): - Flutter - ReachabilitySwift - - CryptoSwift (1.8.3) - - cw_mweb (0.0.1): - - Flutter + - CryptoSwift (1.8.4) - cw_decred (0.0.1): - Flutter - cw_mweb (0.0.1): @@ -80,9 +78,9 @@ PODS: - permission_handler_apple (9.3.0): - Flutter - ReachabilitySwift (5.2.4) - - SDWebImage (5.19.7): - - SDWebImage/Core (= 5.19.7) - - SDWebImage/Core (5.19.7) + - SDWebImage (5.20.0): + - SDWebImage/Core (= 5.20.0) + - SDWebImage/Core (5.20.0) - sensitive_clipboard (0.0.1): - Flutter - share_plus (0.0.1): @@ -106,7 +104,6 @@ PODS: DEPENDENCIES: - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - CryptoSwift - - cw_mweb (from `.symlinks/plugins/cw_mweb/ios`) - cw_decred (from `.symlinks/plugins/cw_decred/ios`) - cw_mweb (from `.symlinks/plugins/cw_mweb/ios`) - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`) @@ -147,8 +144,6 @@ SPEC REPOS: EXTERNAL SOURCES: connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" - cw_mweb: - :path: ".symlinks/plugins/cw_mweb/ios" cw_decred: :path: ".symlinks/plugins/cw_decred/ios" cw_mweb: @@ -203,41 +198,40 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: - connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf - CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483 - cw_decred: a02cf30175a46971c1e2fa22c48407534541edc6 - cw_mweb: 3aea2fb35b2bd04d8b2d21b83216f3b8fb768d85 - device_display_brightness: 04374ebd653619292c1d996f00f42877ea19f17f - device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89 - devicelocale: bd64aa714485a8afdaded0892c1e7d5b7f680cf8 + connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d + CryptoSwift: e64e11850ede528a02a0f3e768cec8e9d92ecb90 + cw_decred: 9c0e1df74745b51a1289ec5e91fb9e24b68fa14a + cw_mweb: 22cd01dfb8ad2d39b15332006f22046aaa8352a3 + device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7 + device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 + devicelocale: 35ba84dc7f45f527c3001535d8c8d104edd5d926 DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 - fast_scanner: 2cb1ad3e69e645e9980fb4961396ce5804caa3e3 - file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517 + fast_scanner: 44c00940355a51258cd6c2085734193cd23d95bc + file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99 - flutter_local_authentication: 989278c681612f1ee0e36019e149137f114b9d7f - flutter_mailer: 3a8cd4f36c960fb04528d5471097270c19fec1c4 - flutter_secure_storage: 2c2ff13db9e0a5647389bff88b0ecac56e3f3418 - fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1 - in_app_review: 5596fe56fab799e8edb3561c03d053363ab13457 - integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e + flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 + flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb + flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83 + flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be + fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f + in_app_review: a31b5257259646ea78e0e35fc914979b0031d011 + integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 - package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 - path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 - permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d + package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda - SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3 - sensitive_clipboard: 161e9abc3d56b3131309d8a321eb4690a803c16b - share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a - shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 - sp_scanner: b1bc9321690980bdb44bba7ec85d5543e716d1b5 + SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8 + sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986 + share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 + sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 - Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e - uni_links: ed8c961e47ed9ce42b6d91e1de8049e38a4b3152 - universal_ble: ff19787898040d721109c6324472e5dd4bc86adc - url_launcher_ios: 694010445543906933d732453a59da0a173ae33d - wakelock_plus: 04623e3f525556020ebd4034310f20fe7fda8b49 + uni_links: d97da20c7701486ba192624d99bffaaffcfc298a + universal_ble: cf52a7b3fd2e7c14d6d7262e9fdadb72ab6b88a6 + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe + wakelock_plus: 373cfe59b235a6dd5837d0fb88791d2f13a90d56 PODFILE CHECKSUM: e448f662d4c41f0c0b1ccbb78afd57dbf895a597 diff --git a/lib/buy/buy_provider.dart b/lib/buy/buy_provider.dart index ea2bcae8f..55ef5e6c3 100644 --- a/lib/buy/buy_provider.dart +++ b/lib/buy/buy_provider.dart @@ -1,6 +1,7 @@ import 'package:cake_wallet/buy/buy_amount.dart'; import 'package:cake_wallet/buy/buy_quote.dart'; import 'package:cake_wallet/buy/order.dart'; +import 'package:cake_wallet/buy/pairs_utils.dart'; import 'package:cake_wallet/buy/payment_method.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart'; @@ -13,11 +14,15 @@ abstract class BuyProvider { required this.wallet, required this.isTestEnvironment, required this.ledgerVM, + required this.supportedCryptoList, + required this.supportedFiatList }); final WalletBase wallet; final bool isTestEnvironment; final LedgerViewModel? ledgerVM; + final List> supportedCryptoList; + final List> supportedFiatList; String get title; diff --git a/lib/buy/dfx/dfx_buy_provider.dart b/lib/buy/dfx/dfx_buy_provider.dart index ac50665f0..267406893 100644 --- a/lib/buy/dfx/dfx_buy_provider.dart +++ b/lib/buy/dfx/dfx_buy_provider.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_quote.dart'; +import 'package:cake_wallet/buy/pairs_utils.dart'; import 'package:cake_wallet/buy/payment_method.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -20,9 +21,19 @@ import 'package:http/http.dart' as http; import 'package:url_launcher/url_launcher.dart'; class DFXBuyProvider extends BuyProvider { - DFXBuyProvider( - {required WalletBase wallet, bool isTestEnvironment = false, LedgerViewModel? ledgerVM}) - : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: ledgerVM); + DFXBuyProvider({ + required WalletBase wallet, + bool isTestEnvironment = false, + LedgerViewModel? ledgerVM, + }) : super( + wallet: wallet, + isTestEnvironment: isTestEnvironment, + ledgerVM: ledgerVM, + supportedCryptoList: supportedCryptoToFiatPairs( + notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat), + supportedFiatList: supportedFiatToCryptoPairs( + notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto) + ); static const _baseUrl = 'api.dfx.swiss'; @@ -30,6 +41,9 @@ class DFXBuyProvider extends BuyProvider { static const _authPath = '/v1/auth'; static const walletName = 'CakeWallet'; + static const List _notSupportedCrypto = []; + static const List _notSupportedFiat = []; + @override String get title => 'DFX.swiss'; diff --git a/lib/buy/kryptonim/kryptonim.dart b/lib/buy/kryptonim/kryptonim.dart index c439fa2f7..6e00a7e07 100644 --- a/lib/buy/kryptonim/kryptonim.dart +++ b/lib/buy/kryptonim/kryptonim.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_quote.dart'; +import 'package:cake_wallet/buy/pairs_utils.dart'; import 'package:cake_wallet/buy/payment_method.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; @@ -16,7 +17,14 @@ import 'package:url_launcher/url_launcher.dart'; class KryptonimBuyProvider extends BuyProvider { KryptonimBuyProvider({required WalletBase wallet, bool isTestEnvironment = false}) - : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: null); + : super( + wallet: wallet, + isTestEnvironment: isTestEnvironment, + ledgerVM: null, + supportedCryptoList: supportedCryptoToFiatPairs( + notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat), + supportedFiatList: supportedFiatToCryptoPairs( + notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto)); static const _isProduction = true; @@ -27,6 +35,9 @@ class KryptonimBuyProvider extends BuyProvider { static String get _kryptonimApiKey => secrets.kryptonimApiKey; + static const List _notSupportedCrypto = []; + static const List _notSupportedFiat = []; + @override String get title => 'Kryptonim'; diff --git a/lib/buy/meld/meld_buy_provider.dart b/lib/buy/meld/meld_buy_provider.dart index 81ad35a40..e96a3575c 100644 --- a/lib/buy/meld/meld_buy_provider.dart +++ b/lib/buy/meld/meld_buy_provider.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_quote.dart'; +import 'package:cake_wallet/buy/pairs_utils.dart'; import 'package:cake_wallet/buy/payment_method.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -18,7 +19,14 @@ import 'package:url_launcher/url_launcher.dart'; class MeldBuyProvider extends BuyProvider { MeldBuyProvider({required WalletBase wallet, bool isTestEnvironment = false}) - : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: null); + : super( + wallet: wallet, + isTestEnvironment: isTestEnvironment, + ledgerVM: null, + supportedCryptoList: supportedCryptoToFiatPairs( + notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat), + supportedFiatList: supportedFiatToCryptoPairs( + notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto)); static const _isProduction = false; @@ -34,6 +42,9 @@ class MeldBuyProvider extends BuyProvider { static String get _testApiKey => secrets.meldTestApiKey; + static const List _notSupportedCrypto = []; + static const List _notSupportedFiat = []; + static String get _testPublicKey => '' ; //secrets.meldTestPublicKey; @override diff --git a/lib/buy/moonpay/moonpay_provider.dart b/lib/buy/moonpay/moonpay_provider.dart index 10148dd30..6c568886f 100644 --- a/lib/buy/moonpay/moonpay_provider.dart +++ b/lib/buy/moonpay/moonpay_provider.dart @@ -7,6 +7,7 @@ import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_provider_description.dart'; import 'package:cake_wallet/buy/buy_quote.dart'; import 'package:cake_wallet/buy/order.dart'; +import 'package:cake_wallet/buy/pairs_utils.dart'; import 'package:cake_wallet/buy/payment_method.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/exchange/trade_state.dart'; @@ -31,7 +32,14 @@ class MoonPayProvider extends BuyProvider { }) : baseSellUrl = isTestEnvironment ? _baseSellTestUrl : _baseSellProductUrl, baseBuyUrl = isTestEnvironment ? _baseBuyTestUrl : _baseBuyProductUrl, this._settingsStore = settingsStore, - super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: null); + super( + wallet: wallet, + isTestEnvironment: isTestEnvironment, + ledgerVM: null, + supportedCryptoList: supportedCryptoToFiatPairs( + notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat), + supportedFiatList: supportedFiatToCryptoPairs( + notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto)); final SettingsStore _settingsStore; @@ -48,6 +56,9 @@ class MoonPayProvider extends BuyProvider { static const _transactionsSuffix = '/v1/transactions'; + static const List _notSupportedCrypto = []; + static const List _notSupportedFiat = []; + final String baseBuyUrl; final String baseSellUrl; diff --git a/lib/buy/onramper/onramper_buy_provider.dart b/lib/buy/onramper/onramper_buy_provider.dart index 5480ab2cd..b48228bd8 100644 --- a/lib/buy/onramper/onramper_buy_provider.dart +++ b/lib/buy/onramper/onramper_buy_provider.dart @@ -4,6 +4,7 @@ import 'dart:developer'; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_quote.dart'; +import 'package:cake_wallet/buy/pairs_utils.dart'; import 'package:cake_wallet/buy/payment_method.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -20,7 +21,13 @@ import 'package:url_launcher/url_launcher.dart'; class OnRamperBuyProvider extends BuyProvider { OnRamperBuyProvider(this._settingsStore, {required WalletBase wallet, bool isTestEnvironment = false}) - : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: null); + : super(wallet: wallet, + isTestEnvironment: isTestEnvironment, + ledgerVM: null, + supportedCryptoList: supportedCryptoToFiatPairs( + notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat), + supportedFiatList: supportedFiatToCryptoPairs( + notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto)); static const _baseUrl = 'buy.onramper.com'; static const _baseApiUrl = 'api.onramper.com'; @@ -28,6 +35,9 @@ class OnRamperBuyProvider extends BuyProvider { static const paymentTypes = '/payment-types'; static const supported = '/supported'; + static const List _notSupportedCrypto = []; + static const List _notSupportedFiat = []; + final SettingsStore _settingsStore; String get _apiKey => secrets.onramperApiKey; @@ -222,8 +232,7 @@ class OnRamperBuyProvider extends BuyProvider { '${prefix}defaultAmount': amount.toString(), if (paymentMethod != null) '${prefix}defaultPaymentMethod': paymentMethod, 'onlyOnramps': quote.rampId, - 'networkWallets': '$defaultCrypto:$cryptoCurrencyAddress', - 'walletAddress': cryptoCurrencyAddress, + 'networkWallets': '${_tagToNetwork(quote.cryptoCurrency.tag ?? quote.cryptoCurrency.title)}:$cryptoCurrencyAddress', 'supportSwap': "false", 'primaryColor': primaryColor, 'secondaryColor': secondaryColor, diff --git a/lib/buy/pairs_utils.dart b/lib/buy/pairs_utils.dart new file mode 100644 index 000000000..093b9846d --- /dev/null +++ b/lib/buy/pairs_utils.dart @@ -0,0 +1,37 @@ +import 'package:cake_wallet/entities/fiat_currency.dart'; +import 'package:cw_core/crypto_currency.dart'; + +class TradePair { + TradePair({required this.from, required this.to}); + + final T from; + final U to; +} + +List> supportedCryptoToFiatPairs({ + required List notSupportedCrypto, + required List notSupportedFiat, +}) { + final supportedCrypto = + CryptoCurrency.all.where((crypto) => !notSupportedCrypto.contains(crypto)).toList(); + final supportedFiat = FiatCurrency.all.where((fiat) => !notSupportedFiat.contains(fiat)).toList(); + + return supportedCrypto + .expand((crypto) => supportedFiat + .map((fiat) => TradePair(from: crypto, to: fiat))) + .toList(); +} + +List> supportedFiatToCryptoPairs({ + required List notSupportedFiat, + required List notSupportedCrypto, +}) { + final supportedFiat = FiatCurrency.all.where((fiat) => !notSupportedFiat.contains(fiat)).toList(); + final supportedCrypto = + CryptoCurrency.all.where((crypto) => !notSupportedCrypto.contains(crypto)).toList(); + + return supportedFiat + .expand((fiat) => supportedCrypto + .map((crypto) => TradePair(from: fiat, to: crypto))) + .toList(); +} diff --git a/lib/buy/robinhood/robinhood_buy_provider.dart b/lib/buy/robinhood/robinhood_buy_provider.dart index b44fab311..90177ec61 100644 --- a/lib/buy/robinhood/robinhood_buy_provider.dart +++ b/lib/buy/robinhood/robinhood_buy_provider.dart @@ -4,6 +4,7 @@ import 'dart:developer'; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_quote.dart'; +import 'package:cake_wallet/buy/pairs_utils.dart'; import 'package:cake_wallet/buy/payment_method.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -23,11 +24,21 @@ import 'package:url_launcher/url_launcher.dart'; class RobinhoodBuyProvider extends BuyProvider { RobinhoodBuyProvider( {required WalletBase wallet, bool isTestEnvironment = false, LedgerViewModel? ledgerVM}) - : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: ledgerVM); + : super( + wallet: wallet, + isTestEnvironment: isTestEnvironment, + ledgerVM: ledgerVM, + supportedCryptoList: supportedCryptoToFiatPairs( + notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat), + supportedFiatList: supportedFiatToCryptoPairs( + notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto)); static const _baseUrl = 'applink.robinhood.com'; static const _cIdBaseUrl = 'exchange-helper.cakewallet.com'; + static const List _notSupportedCrypto = []; + static const List _notSupportedFiat = []; + @override String get title => 'Robinhood Connect'; diff --git a/lib/buy/wyre/wyre_buy_provider.dart b/lib/buy/wyre/wyre_buy_provider.dart index 78b109ac0..7fe6f4be3 100644 --- a/lib/buy/wyre/wyre_buy_provider.dart +++ b/lib/buy/wyre/wyre_buy_provider.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'package:cake_wallet/buy/buy_exception.dart'; -import 'package:flutter/src/widgets/framework.dart'; +import 'package:cake_wallet/buy/pairs_utils.dart'; +import 'package:cake_wallet/entities/fiat_currency.dart'; +import 'package:cw_core/crypto_currency.dart'; import 'package:http/http.dart'; import 'package:cake_wallet/buy/buy_amount.dart'; import 'package:cake_wallet/buy/buy_provider.dart'; @@ -14,7 +16,14 @@ import 'package:cake_wallet/.secrets.g.dart' as secrets; class WyreBuyProvider extends BuyProvider { WyreBuyProvider({required WalletBase wallet, bool isTestEnvironment = false}) : baseApiUrl = isTestEnvironment ? _baseTestApiUrl : _baseProductApiUrl, - super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: null); + super( + wallet: wallet, + isTestEnvironment: isTestEnvironment, + ledgerVM: null, + supportedCryptoList: supportedCryptoToFiatPairs( + notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat), + supportedFiatList: supportedFiatToCryptoPairs( + notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto)); static const _baseTestApiUrl = 'https://api.testwyre.com'; static const _baseProductApiUrl = 'https://api.sendwyre.com'; @@ -30,6 +39,9 @@ class WyreBuyProvider extends BuyProvider { static const _secretKey = secrets.wyreSecretKey; static const _accountId = secrets.wyreAccountId; + static const List _notSupportedCrypto = []; + static const List _notSupportedFiat = []; + @override String get title => 'Wyre'; diff --git a/lib/core/backup_service_v3.dart b/lib/core/backup_service_v3.dart index 5f5e77b00..76798aa64 100644 --- a/lib/core/backup_service_v3.dart +++ b/lib/core/backup_service_v3.dart @@ -198,7 +198,7 @@ class BackupServiceV3 extends $BackupService { final version = getVersionFile(file); switch (version) { case BackupVersion.unknown: - throw Exception('Invalid backup file: unknown version'); + throw Exception('unknown_backup_version'); case BackupVersion.v1: final data = file.readAsBytesSync(); final backupBytes = data.toList()..removeAt(0); diff --git a/lib/di.dart b/lib/di.dart index 51e741ca5..75114d7a1 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -35,6 +35,7 @@ import 'package:cake_wallet/entities/hardware_wallet/require_hardware_wallet_con import 'package:cake_wallet/entities/parse_address_from_domain.dart'; import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart'; import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart'; +import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart'; import 'package:cake_wallet/src/screens/settings/background_sync_page.dart'; import 'package:cake_wallet/view_model/dev/monero_background_sync.dart'; import 'package:cake_wallet/view_model/link_view_model.dart'; @@ -349,7 +350,7 @@ Future setup({ getIt.registerSingleton( OrdersStore(ordersSource: _ordersSource, settingsStore: getIt.get())); getIt.registerSingleton(TradeFilterStore()); - getIt.registerSingleton(TransactionFilterStore()); + getIt.registerSingleton(TransactionFilterStore(getIt.get())); getIt.registerSingleton(FiatConversionStore()); getIt.registerSingleton(SendTemplateStore(templateSource: _templates)); getIt.registerSingleton( @@ -1481,5 +1482,6 @@ Future setup({ getIt.registerFactory(() => SeedVerificationPage(getIt.get())); getIt.registerFactory(() => DevMoneroBackgroundSyncPage(getIt.get())); + getIt.registerFactory(() => DevMoneroCallProfilerPage()); _isSetupFinished = true; } diff --git a/lib/entities/provider_types.dart b/lib/entities/provider_types.dart index 2d2a98379..63918aa8b 100644 --- a/lib/entities/provider_types.dart +++ b/lib/entities/provider_types.dart @@ -7,7 +7,6 @@ import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart'; import 'package:cake_wallet/di.dart'; import 'package:cw_core/wallet_type.dart'; -import 'package:http/http.dart'; enum ProviderType { robinhood, dfx, onramper, moonpay, meld, kriptonim } @@ -48,82 +47,21 @@ extension ProviderTypeName on ProviderType { } class ProvidersHelper { - static List getAvailableBuyProviderTypes(WalletType walletType) { - switch (walletType) { - case WalletType.nano: - case WalletType.banano: - case WalletType.wownero: - return [ProviderType.onramper]; - case WalletType.monero: - return [ProviderType.onramper, ProviderType.dfx]; - case WalletType.bitcoin: - case WalletType.polygon: - case WalletType.ethereum: - return [ - ProviderType.onramper, - ProviderType.dfx, - ProviderType.robinhood, - ProviderType.moonpay, - ProviderType.kriptonim - ]; - case WalletType.litecoin: - case WalletType.bitcoinCash: - case WalletType.solana: - return [ - ProviderType.onramper, - ProviderType.robinhood, - ProviderType.moonpay, - ProviderType.kriptonim - ]; - case WalletType.tron: - return [ - ProviderType.onramper, - ProviderType.robinhood, - ProviderType.moonpay, - ProviderType.kriptonim - ]; - case WalletType.decred: - case WalletType.none: - case WalletType.haven: - case WalletType.zano: - return []; - } - } + static List getAvailableBuyProviderTypes(WalletType walletType) => [ + ProviderType.robinhood, + ProviderType.dfx, + ProviderType.onramper, + ProviderType.moonpay, + ProviderType.kriptonim + ]; - static List getAvailableSellProviderTypes(WalletType walletType) { - switch (walletType) { - case WalletType.bitcoin: - case WalletType.ethereum: - case WalletType.polygon: - return [ - ProviderType.onramper, - ProviderType.moonpay, - ProviderType.dfx, - ]; - case WalletType.litecoin: - case WalletType.bitcoinCash: - return [ProviderType.moonpay]; - case WalletType.solana: - return [ - ProviderType.onramper, - ProviderType.moonpay, - ]; - case WalletType.tron: - return [ - ProviderType.moonpay, - ]; - case WalletType.monero: - return [ProviderType.dfx]; - case WalletType.decred: - case WalletType.nano: - case WalletType.banano: - case WalletType.none: - case WalletType.haven: - case WalletType.wownero: - case WalletType.zano: - return []; - } - } + static List getAvailableSellProviderTypes(WalletType walletType) => [ + ProviderType.robinhood, + ProviderType.dfx, + ProviderType.onramper, + ProviderType.moonpay, + ProviderType.kriptonim + ]; static BuyProvider? getProviderByType(ProviderType type) { switch (type) { diff --git a/lib/exchange/provider/simpleswap_exchange_provider.dart b/lib/exchange/provider/simpleswap_exchange_provider.dart index 2a72ac793..5391d5f89 100644 --- a/lib/exchange/provider/simpleswap_exchange_provider.dart +++ b/lib/exchange/provider/simpleswap_exchange_provider.dart @@ -34,10 +34,10 @@ class SimpleSwapExchangeProvider extends ExchangeProvider { String get title => 'SimpleSwap'; @override - bool get isAvailable => true; + bool get isAvailable => false; @override - bool get isEnabled => true; + bool get isEnabled => false; @override bool get supportsFixedRate => false; diff --git a/lib/exchange/provider/xoswap_exchange_provider.dart b/lib/exchange/provider/xoswap_exchange_provider.dart index 0b3826aa9..5611d6855 100644 --- a/lib/exchange/provider/xoswap_exchange_provider.dart +++ b/lib/exchange/provider/xoswap_exchange_provider.dart @@ -188,12 +188,21 @@ class XOSwapExchangeProvider extends ExchangeProvider { try { final uri = Uri.https(_apiAuthority, '$_apiPath$_orders'); + final curFrom = await _getAssets(request.fromCurrency); + final curTo = await _getAssets(request.toCurrency); + + if (curFrom == null || curTo == null) { + throw TradeNotCreatedException(description); + } + + final pairId = curFrom + '_' + curTo; + final payload = { 'fromAmount': request.fromAmount, 'fromAddress': request.refundAddress, 'toAmount': request.toAmount, 'toAddress': request.toAddress, - 'pairId': '${request.fromCurrency.title}_${request.toCurrency.title}', + 'pairId': pairId, }; final response = await http.post(uri, headers: _headers, body: json.encode(payload)); diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart index aa6fafc6b..6c72cbe67 100644 --- a/lib/monero/cw_monero.dart +++ b/lib/monero/cw_monero.dart @@ -422,6 +422,12 @@ class CWMonero extends Monero { } bool isViewOnly() { - return isViewOnlyBySpendKey(); + return isViewOnlyBySpendKey(null); } + + @override + Map> debugCallLength() { + return monero_wallet_api.debugCallLength(); + } + } diff --git a/lib/router.dart b/lib/router.dart index 6c0445223..28a737ce6 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -37,6 +37,7 @@ import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart'; import 'package:cake_wallet/src/screens/dashboard/sign_page.dart'; import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart'; +import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart'; import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart'; import 'package:cake_wallet/src/screens/exchange/exchange_page.dart'; import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart'; @@ -279,15 +280,17 @@ Route createRoute(RouteSettings settings) { case Routes.restoreWalletFromHardwareWallet: if (isSingleCoin) { return MaterialPageRoute( - builder: (_) => ConnectDevicePage( - ConnectDevicePageParams( - walletType: availableWalletTypes.first, - onConnectDevice: (BuildContext context, _) => Navigator.of(context).pushNamed( - Routes.chooseHardwareWalletAccount, - arguments: [availableWalletTypes.first]), - ), - getIt.get(), - )); + builder: (_) => ConnectDevicePage( + ConnectDevicePageParams( + walletType: availableWalletTypes.first, + onConnectDevice: (BuildContext context, _) => Navigator.of(context).pushNamed( + Routes.chooseHardwareWalletAccount, + arguments: [availableWalletTypes.first]), + isReconnect: false, + ), + getIt.get(), + ), + ); } return CupertinoPageRoute( builder: (_) => getIt.get( @@ -297,6 +300,7 @@ Route createRoute(RouteSettings settings) { walletType: type, onConnectDevice: (BuildContext context, _) => Navigator.of(context) .pushNamed(Routes.chooseHardwareWalletAccount, arguments: [type]), + isReconnect: false, ); Navigator.of(context).pushNamed(Routes.connectDevices, arguments: arguments); @@ -858,6 +862,11 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get(), ); + case Routes.devMoneroCallProfiler: + return MaterialPageRoute( + builder: (_) => getIt.get(), + ); + default: return MaterialPageRoute( builder: (_) => Scaffold( diff --git a/lib/routes.dart b/lib/routes.dart index be5e9f05d..f7f3e2f6f 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -112,7 +112,7 @@ class Routes { static const torPage = '/tor_page'; static const backgroundSync = '/background_sync'; static const devMoneroBackgroundSync = '/dev/monero_background_sync'; - + static const devMoneroCallProfiler = '/dev/monero_call_profiler'; static const signPage = '/sign_page'; static const connectDevices = '/device/connect'; static const urqrAnimatedPage = '/urqr/animated_page'; diff --git a/lib/solana/cw_solana.dart b/lib/solana/cw_solana.dart index 937b5b3bf..9036f5584 100644 --- a/lib/solana/cw_solana.dart +++ b/lib/solana/cw_solana.dart @@ -99,6 +99,7 @@ class CWSolana extends Solana { mint: token.name.toUpperCase(), enabled: token.enabled, iconPath: token.iconPath, + isPotentialScam: token.isPotentialScam, ); await (wallet as SolanaWallet).addSPLToken(splToken); diff --git a/lib/src/screens/buy/buy_sell_page.dart b/lib/src/screens/buy/buy_sell_page.dart index 9d0f17ee3..48334f439 100644 --- a/lib/src/screens/buy/buy_sell_page.dart +++ b/lib/src/screens/buy/buy_sell_page.dart @@ -160,9 +160,45 @@ class BuySellPage extends BasePage { ), ])), bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), - bottomSection: Column(children: [ - Observer( - builder: (_) => LoadingPrimaryButton( + bottomSection: Observer( + builder: (_) => Column(children: [ + buySellViewModel.isBuySellQuotFailed + ? Padding( + padding: EdgeInsets.only(bottom: 15), + child: Row( + children: [ + Expanded( + child: Container( + alignment: Alignment.centerRight, + child: Icon(Icons.warning_amber_rounded, + color: Theme.of(context) + .extension()! + .receiveAmountColor, + size: 26), + ), + ), + Expanded( + flex: 8, + child: Text( + S.of(context).buy_sell_pair_is_not_supported_warning, + textAlign: TextAlign.center, + softWrap: true, + overflow: TextOverflow.ellipsis, + maxLines: 3, + style: TextStyle( + color: Theme.of(context) + .extension()! + .receiveAmountColor, + fontWeight: FontWeight.w500, + fontSize: 12, + ), + ), + ), + ], + ), + ) + : Container(), + LoadingPrimaryButton( text: S.current.choose_a_provider, onPressed: () async { if(!_formKey.currentState!.validate()) return; @@ -172,8 +208,8 @@ class BuySellPage extends BasePage { textColor: Colors.white, isDisabled: buySellViewModel.isBuySellQuotFailed, isLoading: !buySellViewModel.isReadyToTrade && - !buySellViewModel.isBuySellQuotFailed)), - ]), + !buySellViewModel.isBuySellQuotFailed), + ])), )), )); } diff --git a/lib/src/screens/connect_device/connect_device_page.dart b/lib/src/screens/connect_device/connect_device_page.dart index 5e52b887c..8452a59be 100644 --- a/lib/src/screens/connect_device/connect_device_page.dart +++ b/lib/src/screens/connect_device/connect_device_page.dart @@ -28,7 +28,7 @@ class ConnectDevicePageParams { required this.walletType, required this.onConnectDevice, this.allowChangeWallet = false, - this.isReconnect = false, + this.isReconnect = true, }); } diff --git a/lib/src/screens/dashboard/edit_token_page.dart b/lib/src/screens/dashboard/edit_token_page.dart index 11a584b39..8429a63df 100644 --- a/lib/src/screens/dashboard/edit_token_page.dart +++ b/lib/src/screens/dashboard/edit_token_page.dart @@ -217,12 +217,13 @@ class _EditTokenPageBodyState extends State { bool isPotentialScam = hasPotentialError; final tokenSymbol = _tokenSymbolController.text.toUpperCase(); - + // check if the token symbol is the same as any of the base currencies symbols (ETH, SOL, POL, TRX, etc): // if it is, then it's probably a scam unless it's in the whitelist final baseCurrencySymbols = CryptoCurrency.all.map((e) => e.title.toUpperCase()).toList(); - if (baseCurrencySymbols.contains(tokenSymbol) && !isWhitelisted) { + if (baseCurrencySymbols.contains(tokenSymbol.trim().toUpperCase()) && + !isWhitelisted) { isPotentialScam = true; } diff --git a/lib/src/screens/dashboard/pages/balance/balance_row_widget.dart b/lib/src/screens/dashboard/pages/balance/balance_row_widget.dart index 875618784..47d522173 100644 --- a/lib/src/screens/dashboard/pages/balance/balance_row_widget.dart +++ b/lib/src/screens/dashboard/pages/balance/balance_row_widget.dart @@ -16,7 +16,6 @@ import 'package:cw_core/unspent_coin_type.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:cake_wallet/themes/theme_base.dart'; class BalanceRowWidget extends StatelessWidget { BalanceRowWidget({ @@ -66,8 +65,6 @@ class BalanceRowWidget extends StatelessWidget { @override Widget build(BuildContext context) { - bool brightThemeType = false; - if (dashboardViewModel.settingsStore.currentTheme.type == ThemeType.bright) brightThemeType = true; return Column( children: [ Container( @@ -221,7 +218,33 @@ class BalanceRowWidget extends StatelessWidget { ), ], ), - //), + if (currency.isPotentialScam) + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + margin: EdgeInsets.only(top: 4), + decoration: BoxDecoration( + color: Colors.red[800], + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.warning_amber_outlined, + size: 16, + color: Colors.white, + ), + const SizedBox(width: 4), + Text( + S.of(context).potential_scam, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w700, + ), + ), + ], + ), + ), if (frozenBalance.isNotEmpty) Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart b/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart index e8de89412..73890907d 100644 --- a/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart +++ b/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart @@ -347,7 +347,7 @@ class CryptoBalanceWidget extends StatelessWidget { Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), child: InfoCard( - title: S.of(context).decred_info_title, + title: S.of(context).synchronizing, description: S.of(context).decred_info_card_details, image: 'assets/images/dcr_icon.png', leftButtonTitle: S.of(context).litecoin_mweb_dismiss, diff --git a/lib/src/screens/dev/moneroc_call_profiler.dart b/lib/src/screens/dev/moneroc_call_profiler.dart new file mode 100644 index 000000000..e7043fea9 --- /dev/null +++ b/lib/src/screens/dev/moneroc_call_profiler.dart @@ -0,0 +1,253 @@ +// code shamelessly stolen from xmruw +// https://raw.githubusercontent.com/MrCyjaneK/unnamed_monero_wallet/refs/heads/master-rewrite/lib/pages/debug/performance.dart +import 'dart:math'; + +import 'package:cake_wallet/di.dart'; +import 'package:cake_wallet/monero/monero.dart'; +import 'package:cake_wallet/src/widgets/primary_button.dart'; +import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; +import 'package:cake_wallet/wownero/wownero.dart'; +import 'package:cake_wallet/zano/zano.dart'; +import 'package:cw_core/wallet_type.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/src/screens/base_page.dart'; + +class DevMoneroCallProfilerPage extends BasePage { + DevMoneroCallProfilerPage(); + + @override + String? get title => "[dev] xmr call profiler"; + + @override + Widget body(BuildContext context) { + return PerformanceDebug(); + } +} + + + +class PerformanceDebug extends StatefulWidget { + const PerformanceDebug({super.key}); + + @override + State createState() => _PerformanceDebugState(); +} + +enum ProfilableWallet { + monero, + wownero, + zano, +} + +class _PerformanceDebugState extends State { + List widgets = []; + + final dashboardViewModel = getIt.get(); + + late ProfilableWallet wallet = switch (dashboardViewModel.wallet.type) { + WalletType.monero => ProfilableWallet.monero, + WalletType.wownero => ProfilableWallet.wownero, + WalletType.zano => ProfilableWallet.zano, + _ => throw Exception("Unknown wallet type"), + }; + final precalc = 1700298; + + late Map> debugCallLength = switch (wallet) { + ProfilableWallet.monero => monero!.debugCallLength(), + ProfilableWallet.wownero => wownero!.debugCallLength(), + ProfilableWallet.zano => zano!.debugCallLength(), + }; + + int getOpenWalletTime() { + if (debugCallLength["MONERO_Wallet_init"] == null) { + return precalc; + } + if (debugCallLength["MONERO_Wallet_init"]!.isEmpty) { + return precalc; + } + return debugCallLength["MONERO_Wallet_init"]!.last; + } + +late final String perfInfo = """ +---- Performance tuning +This page lists all calls that take place during the app runtime.- +As per Flutter docs we can read: +> Flutter aims to provide 60 frames per second (fps) performance, or 120 fps- +performance on devices capable of 120Hz updates. + +With that in mind we will aim to render frames every 8.3ms (~8333 µs). It is- +however acceptable to reach 16.6 ms (~16666 µs) but we should also keep in mind- +that there are also UI costs that aren't part of this benchmark. + +For some calls it is also acceptable to exceed this amount of time, for example- +MONERO_Wallet_init takes ~${getOpenWalletTime()}µs- +(${(getOpenWalletTime() / frameTime).toStringAsFixed(2)} frames). That time would- +be unnaceptable in most situations but since we call this function only when- +opening the wallet it is completely fine to freeze the UI for the time being -- +as the user won't even notice that something happened. + +---- Details +count: how many times did we call this function [total time (% of frame)] +average: average execution time (% of frame) +min: fastest execution (% of frame) +max: slowest execution (% of frame) +95th: 95% of the time, the function is faster than this amount of time (% of frame) +""" + .split("-\n") + .join(" "); + + late final frameTime = 8333; + late final frameGreenTier = frameTime ~/ 100; + late final frameBlueTier = frameTime ~/ 10; + late final frameBlueGreyTier = frameTime ~/ 2; + late final frameYellowTier = frameTime; + late final frameOrangeTier = frameTime * 2; + + Color? perfc(num frame) { + if (frame < frameGreenTier) return Colors.green; + if (frame < frameBlueTier) return Colors.blue; + if (frame < frameBlueGreyTier) return Colors.blueGrey; + if (frame < frameGreenTier) return Colors.green; + if (frame < frameYellowTier) return Colors.yellow; + if (frame < frameOrangeTier) return Colors.orange; + return Colors.red; + } + + + @override + void initState() { + _buildWidgets(); + super.initState(); + } + + SelectableText cw(String text, Color? color) { + return SelectableText( + text, + style: TextStyle(color: color), + ); + } + + void _buildWidgets() { + List ws = []; + ws.add(Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SelectableText(perfInfo), + cw("< 1% of a frame (max: $frameGreenTierµs)", Colors.green), + cw("< 10% of a frame (max: $frameBlueTierµs)", Colors.blue), + cw("< 50% of a frame (max: $frameBlueGreyTierµs)", Colors.blueGrey), + cw("< 100% of a frame (max: $frameYellowTierµs)", Colors.yellow), + cw("< 200% of a frame (max: $frameOrangeTierµs)", Colors.orange), + cw("> 200% of a frame (UI junk visible)", Colors.red), + ], + )); + final keys = debugCallLength.keys.toList(); + keys.sort((s1, s2) => + _n95th(debugCallLength[s2]!) - + _n95th(debugCallLength[s1]!)); + for (var key in keys) { + final value = debugCallLength[key]; + if (value == null) continue; + final avg = _avg(value); + final min = _min(value); + final max = _max(value); + final np = _n95th(value); + final total = _total(value); + ws.add( + Card( + child: ListTile( + title: Text( + key, + style: TextStyle(color: perfc(np)), + ), + subtitle: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row(children: [ + cw("count: ${value.length}", null), + const Spacer(), + cw("${_str(total / 1000)}ms", perfc(total)), + ]), + cw("average: ${_str(avg)}µs (~${_str(avg / (frameTime))}f)", + perfc(avg)), + cw("min: $minµs (~${_str(min / (frameTime) * 100)})", + perfc(min)), + cw("max: $maxµs (~${_str(max / (frameTime) * 100)}%)", + perfc(max)), + cw("95th: $npµs (~${_str(np / (frameTime) * 100)}%)", + perfc(np)), + ], + ), + ), + ), + ); + } + if (debugCallLength.isNotEmpty) { + ws.add( + PrimaryButton( + text: "Purge statistics", + onPressed: _purgeStats, + color: Colors.red, + textColor: Colors.white, + ), + ); + } + setState(() { + widgets = ws; + }); + } + + void _purgeStats() { + debugCallLength.clear(); + _buildWidgets(); + } + + int _min(List l) { + return l.reduce(min); + } + + int _max(List l) { + return l.reduce(max); + } + + int _n95th(List l) { + final l0 = l.toList(); + l0.sort(); + int i = (0.95 * l.length).ceil() - 1; + return l0[i]; + } + + double _avg(List l) { + int c = 0; + for (var i = 0; i < l.length; i++) { + c += l[i]; + } + return c / l.length; + } + + int _total(List l) { + int c = 0; + for (var i = 0; i < l.length; i++) { + c += l[i]; + } + return c; + } + + String _str(num d) => d.toStringAsFixed(2); + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(8), + child: Column( + children: widgets, + ), + ), + ); + } +} diff --git a/lib/src/screens/exchange_trade/exchange_confirm_page.dart b/lib/src/screens/exchange_trade/exchange_confirm_page.dart index 60b534c6e..4b7e27294 100644 --- a/lib/src/screens/exchange_trade/exchange_confirm_page.dart +++ b/lib/src/screens/exchange_trade/exchange_confirm_page.dart @@ -118,7 +118,7 @@ class ExchangeConfirmPage extends BasePage { mainAxisAlignment: MainAxisAlignment.center, children: [ (trade.provider.image?.isNotEmpty ?? false) - ? Image.asset(trade.provider.image, height: 50) + ? ImageUtil.getImageFromPath(imagePath: trade.provider.image, height: 50, width: 50) : const SizedBox(), if (!trade.provider.horizontalLogo) Padding( diff --git a/lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart b/lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart index 5ed82e71c..036b5bc6d 100644 --- a/lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart +++ b/lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart @@ -19,9 +19,6 @@ class ExchangeTradeExternalSendPage extends BasePage { @override String get title => S.current.swap; - @override - bool get gradientBackground => true; - @override bool get gradientAll => true; @@ -46,7 +43,7 @@ class ExchangeTradeExternalSendPage extends BasePage { ); return Container( child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(top: 36, bottom: 24), + contentPadding: EdgeInsets.only(bottom: 24), content: Observer( builder: (_) { return Column( diff --git a/lib/src/screens/exchange_trade/exchange_trade_page.dart b/lib/src/screens/exchange_trade/exchange_trade_page.dart index 97d9a34bb..f328cc115 100644 --- a/lib/src/screens/exchange_trade/exchange_trade_page.dart +++ b/lib/src/screens/exchange_trade/exchange_trade_page.dart @@ -26,23 +26,20 @@ import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart'; -void showInformation( - ExchangeTradeViewModel exchangeTradeViewModel, BuildContext context) { +void showInformation(ExchangeTradeViewModel exchangeTradeViewModel, BuildContext context) { final trade = exchangeTradeViewModel.trade; final walletName = exchangeTradeViewModel.wallet.name; final information = exchangeTradeViewModel.isSendable ? S.current.exchange_trade_result_confirm(trade.amount, trade.from.toString(), walletName) + - exchangeTradeViewModel.extraInfo - : S.current.exchange_result_description( - trade.amount, trade.from.toString()) + - exchangeTradeViewModel.extraInfo; + exchangeTradeViewModel.extraInfo + : S.current.exchange_result_description(trade.amount, trade.from.toString()) + + exchangeTradeViewModel.extraInfo; showPopUp( context: context, - builder: (_) => InformationPage( - key: ValueKey('information_page_dialog_key'), - information: information)); + builder: (_) => + InformationPage(key: ValueKey('information_page_dialog_key'), information: information)); } class ExchangeTradePage extends BasePage { @@ -53,9 +50,6 @@ class ExchangeTradePage extends BasePage { @override String get title => S.current.swap; - @override - bool get gradientBackground => true; - @override bool get gradientAll => true; @@ -141,7 +135,7 @@ class ExchangeTradeState extends State { return Container( child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(top: 10, bottom: 16), + contentPadding: EdgeInsets.only(bottom: 16), content: Observer(builder: (_) { final trade = widget.exchangeTradeViewModel.trade; @@ -198,7 +192,7 @@ class ExchangeTradeState extends State { isDisabled: trade.inputAddress == null || trade.inputAddress!.isEmpty, isLoading: sendingState is IsExecutingState, onPressed: () => widget.exchangeTradeViewModel.confirmSending(), - text:S.current.send_from_cake_wallet, + text: S.current.send_from_cake_wallet, color: Theme.of(context).primaryColor, textColor: Colors.white, ) @@ -220,12 +214,11 @@ class ExchangeTradeState extends State { _exchangeStateReaction = reaction((_) => this.widget.exchangeTradeViewModel.sendViewModel.state, (ExecutionState state) { - - if (state is! IsExecutingState && - loadingBottomSheetContext != null && - loadingBottomSheetContext!.mounted) { - Navigator.of(loadingBottomSheetContext!).pop(); - } + if (state is! IsExecutingState && + loadingBottomSheetContext != null && + loadingBottomSheetContext!.mounted) { + Navigator.of(loadingBottomSheetContext!).pop(); + } if (state is FailureState) { WidgetsBinding.instance.addPostFrameCallback((_) { @@ -272,16 +265,21 @@ class ExchangeTradeState extends State { key: ValueKey('exchange_trade_page_confirm_sending_bottom_sheet_key'), currentTheme: widget.currentTheme, titleText: S.of(bottomSheetContext).confirm_transaction, - titleIconPath: widget.exchangeTradeViewModel.sendViewModel.selectedCryptoCurrency.iconPath, + titleIconPath: + widget.exchangeTradeViewModel.sendViewModel.selectedCryptoCurrency.iconPath, currency: widget.exchangeTradeViewModel.sendViewModel.selectedCryptoCurrency, amount: S.of(bottomSheetContext).send_amount, - amountValue: widget.exchangeTradeViewModel.sendViewModel.pendingTransaction!.amountFormatted, - fiatAmountValue: widget.exchangeTradeViewModel.sendViewModel.pendingTransactionFiatAmountFormatted, + amountValue: widget + .exchangeTradeViewModel.sendViewModel.pendingTransaction!.amountFormatted, + fiatAmountValue: widget + .exchangeTradeViewModel.sendViewModel.pendingTransactionFiatAmountFormatted, fee: isEVMCompatibleChain(widget.exchangeTradeViewModel.sendViewModel.walletType) ? S.of(bottomSheetContext).send_estimated_fee : S.of(bottomSheetContext).send_fee, - feeValue: widget.exchangeTradeViewModel.sendViewModel.pendingTransaction!.feeFormatted, - feeFiatAmount: widget.exchangeTradeViewModel.sendViewModel.pendingTransactionFeeFiatAmountFormatted, + feeValue: + widget.exchangeTradeViewModel.sendViewModel.pendingTransaction!.feeFormatted, + feeFiatAmount: widget.exchangeTradeViewModel.sendViewModel + .pendingTransactionFeeFiatAmountFormatted, outputs: widget.exchangeTradeViewModel.sendViewModel.outputs, onSlideComplete: () async { Navigator.of(bottomSheetContext).pop(); @@ -300,7 +298,6 @@ class ExchangeTradeState extends State { return; } - await showModalBottomSheet( context: context, isScrollControlled: true, @@ -321,10 +318,8 @@ class ExchangeTradeState extends State { }); }, ); - }); } - }); _effectsInstalled = true; diff --git a/lib/src/screens/new_wallet/wallet_group_description_page.dart b/lib/src/screens/new_wallet/wallet_group_description_page.dart index b566d0422..e10c64bf9 100644 --- a/lib/src/screens/new_wallet/wallet_group_description_page.dart +++ b/lib/src/screens/new_wallet/wallet_group_description_page.dart @@ -29,37 +29,41 @@ class WalletGroupDescriptionPage extends BasePage { Image.asset(currentTheme.type.walletGroupImage, height: 200), SizedBox(height: 32), Expanded( - child: Text.rich( - TextSpan( - children: [ - TextSpan(text: '${S.of(context).wallet_group_description_one} '), + child: Scrollbar( + child: SingleChildScrollView( + child: Text.rich( TextSpan( - text: '${S.of(context).wallet_group.toLowerCase()} ', - style: TextStyle(fontWeight: FontWeight.w700), + children: [ + TextSpan(text: '${S.of(context).wallet_group_description_one} '), + TextSpan( + text: '${S.of(context).wallet_group.toLowerCase()} ', + style: TextStyle(fontWeight: FontWeight.w700), + ), + TextSpan( + text: '${S.of(context).wallet_group_description_two} ', + ), + TextSpan( + text: '${S.of(context).choose_wallet_group} ', + style: TextStyle(fontWeight: FontWeight.w700), + ), + TextSpan( + text: '${S.of(context).wallet_group_description_three} ', + ), + TextSpan( + text: '${S.of(context).create_new_seed} ', + style: TextStyle(fontWeight: FontWeight.w700), + ), + TextSpan(text: S.of(context).wallet_group_description_four), + ], ), - TextSpan( - text: '${S.of(context).wallet_group_description_two} ', + textAlign: TextAlign.center, + style: TextStyle( + height: 1.5, + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.secondaryTextColor, ), - TextSpan( - text: '${S.of(context).choose_wallet_group} ', - style: TextStyle(fontWeight: FontWeight.w700), - ), - TextSpan( - text: '${S.of(context).wallet_group_description_three} ', - ), - TextSpan( - text: '${S.of(context).create_new_seed} ', - style: TextStyle(fontWeight: FontWeight.w700), - ), - TextSpan(text: S.of(context).wallet_group_description_four), - ], - ), - textAlign: TextAlign.center, - style: TextStyle( - height: 1.5, - fontSize: 16, - fontWeight: FontWeight.w400, - color: Theme.of(context).extension()!.secondaryTextColor, + ), ), ), ), diff --git a/lib/src/screens/new_wallet/wallet_group_existing_seed_description_page.dart b/lib/src/screens/new_wallet/wallet_group_existing_seed_description_page.dart index 4eab8fcec..34e07bbaf 100644 --- a/lib/src/screens/new_wallet/wallet_group_existing_seed_description_page.dart +++ b/lib/src/screens/new_wallet/wallet_group_existing_seed_description_page.dart @@ -32,28 +32,30 @@ class WalletGroupExistingSeedDescriptionPage extends BasePage { Image.asset(currentTheme.type.walletGroupImage, height: 200), SizedBox(height: 32), Expanded( - child: RichText( - text: TextSpan( - children: [ - TextSpan( - text: S.current.wallet_group_description_existing_seed + '\n\n', - style: textStyle), - TextSpan( - text: S.current.wallet_group_description_open_wallet + '\n\n', - style: textStyle), - TextSpan( - text: S.current.wallet_group_description_view_seed + '\n', style: textStyle), - TextSpan( - text: S.current.seed_display_path, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w800, - color: Theme.of(context).extension()!.secondaryTextColor, + child: SingleChildScrollView( + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: S.current.wallet_group_description_existing_seed + '\n\n', + style: textStyle), + TextSpan( + text: S.current.wallet_group_description_open_wallet + '\n\n', + style: textStyle), + TextSpan( + text: S.current.wallet_group_description_view_seed + '\n', style: textStyle), + TextSpan( + text: S.current.seed_display_path, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w800, + color: Theme.of(context).extension()!.secondaryTextColor, + ), ), - ), - ], + ], + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, ), ), Column( diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 69e4bd02a..6d91f0001 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -36,7 +36,6 @@ import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/unspent_coin_type.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:cake_wallet/view_model/send/send_view_model.dart'; import 'package:cake_wallet/view_model/send/send_view_model_state.dart'; @@ -164,8 +163,6 @@ class SendPage extends BasePage { }); }); - bool _bottomSheetOpened = false; - @override Widget body(BuildContext context) { _setEffects(context); @@ -400,6 +397,10 @@ class SendPage extends BasePage { return LoadingPrimaryButton( key: ValueKey('send_page_send_button_key'), onPressed: () async { + + //Request dummy node to get the focus out of the text fields + FocusScope.of(context).requestFocus(FocusNode()); + if (sendViewModel.state is IsExecutingState) return; if (_formKey.currentState != null && !_formKey.currentState!.validate()) { @@ -655,20 +656,26 @@ class SendPage extends BasePage { if (state is IsAwaitingDeviceResponseState) { WidgetsBinding.instance.addPostFrameCallback((_) { - showPopUp( - context: context, - builder: (BuildContext context) { - dialogContext = context; - return AlertWithOneAction( - alertTitle: S.of(context).proceed_on_device, - alertContent: S.of(context).proceed_on_device_description, - buttonText: S.of(context).cancel, - alertBarrierDismissible: false, - buttonAction: () { - sendViewModel.state = InitialExecutionState(); - Navigator.of(context).pop(); - }); - }); + if (!context.mounted) return; + + showModalBottomSheet( + context: context, + isDismissible: false, + builder: (BuildContext bottomSheetContext) => InfoBottomSheet( + currentTheme: currentTheme, + titleText: S.of(bottomSheetContext).proceed_on_device, + contentImage: 'assets/images/hardware_wallet/ledger_nano_x.png', + contentImageColor: + Theme.of(context).extension()!.titleColor, + content: S.of(bottomSheetContext).proceed_on_device_description, + isTwoAction: false, + actionButtonText: S.of(context).cancel, + actionButton: () { + sendViewModel.state = InitialExecutionState(); + Navigator.of(bottomSheetContext).pop(); + }, + ), + ); }); } }); diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index fe2aa511b..a8a9e6b61 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -240,7 +240,7 @@ class SendCardState extends State with AutomaticKeepAliveClientMixin output.setSendAll(sendViewModel.balance)), + allAmountCallback: () async => output.setSendAll(sendViewModel.sendingBalance)), Divider( height: 1, color: Theme.of(context).extension()!.textFieldHintColor), @@ -262,7 +262,7 @@ class SendCardState extends State with AutomaticKeepAliveClientMixin with AutomaticKeepAliveClientMixin Navigator.of(context).pushNamed( - Routes.unspentCoinsList, - arguments: widget.sendViewModel.coinTypeToSpendFrom, - ), + onTap: () async { + await Navigator.of(context).pushNamed( + Routes.unspentCoinsList, + arguments: widget.sendViewModel.coinTypeToSpendFrom, + ); + if (mounted) { + // we just got back from the unspent coins list screen, so we need to recompute the sending balance: + sendViewModel.updateSendingBalance(); + } + }, child: Container( color: Colors.transparent, child: Row( @@ -519,7 +525,7 @@ class SendCardState extends State with AutomaticKeepAliveClientMixin sendViewModel.selectedCryptoCurrency, (Currency currency) { if (output.sendAll) { - output.setSendAll(sendViewModel.balance); + output.setSendAll(sendViewModel.sendingBalance); } output.setCryptoAmount(cryptoAmountController.text); diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart index fcd4f04a9..08556eda9 100644 --- a/lib/src/screens/settings/other_settings_page.dart +++ b/lib/src/screens/settings/other_settings_page.dart @@ -8,6 +8,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arro import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart'; +import 'package:cake_wallet/utils/feature_flag.dart'; import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/foundation.dart'; @@ -64,12 +65,18 @@ class OtherSettingsPage extends BasePage { handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.readDisclaimer), ), - if (kDebugMode && _otherSettingsViewModel.walletType == WalletType.monero) + if (FeatureFlag.hasDevOptions && _otherSettingsViewModel.walletType == WalletType.monero) SettingsCellWithArrow( title: '[dev] monero background sync', handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.devMoneroBackgroundSync), ), + if (FeatureFlag.hasDevOptions && [WalletType.monero, WalletType.wownero, WalletType.zano].contains(_otherSettingsViewModel.walletType)) + SettingsCellWithArrow( + title: '[dev] xmr call profiler', + handler: (BuildContext context) => + Navigator.of(context).pushNamed(Routes.devMoneroCallProfiler), + ), Spacer(), SettingsVersionCell( title: S.of(context).version(_otherSettingsViewModel.currentVersion)), diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart index 238e58eab..5a22f622a 100644 --- a/lib/src/screens/settings/privacy_page.dart +++ b/lib/src/screens/settings/privacy_page.dart @@ -42,7 +42,7 @@ class PrivacyPage extends BasePage { ), SettingsChoicesCell( ChoicesListItem( - title: S.current.exchange, + title: S.current.swap, items: ExchangeApiMode.all, selectedItem: _privacySettingsViewModel.exchangeStatus, onItemSelected: (ExchangeApiMode mode) => diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index 62f79bdc4..507773467 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -525,6 +525,7 @@ class WalletListBodyState extends State { didConnect = true; Navigator.of(context).pop(); }, + isReconnect: true, ), ); diff --git a/lib/src/widgets/adaptable_page_view.dart b/lib/src/widgets/adaptable_page_view.dart index c6800ae22..fc2506e01 100644 --- a/lib/src/widgets/adaptable_page_view.dart +++ b/lib/src/widgets/adaptable_page_view.dart @@ -137,10 +137,25 @@ class _RenderSizingContainer extends RenderProxyBox { parentUsesSize: true, ); - final a = sizes[page.floor()]!; - final b = sizes[page.ceil()]!; + final int floorPage = page.floor(); + final int ceilPage = page.ceil(); + + Size? a = sizes[floorPage]; + Size? b = sizes[ceilPage]; + + if (a == null && sizes.isNotEmpty) { + a = sizes.values.first; + } + if (b == null && sizes.isNotEmpty) { + b = sizes.values.first; + } + + a ??= child.getDryLayout(constraints); + b ??= a; + + final double t = (page - floorPage).clamp(0.0, 1.0); + final double height = lerpDouble(a.height, b.height, t) ?? a.height; - final height = lerpDouble(a.height, b.height, page - page.floor()); child.layout( constraints.copyWith(minHeight: height, maxHeight: height), diff --git a/lib/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart b/lib/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart index f46ea72d0..cfa5980d2 100644 --- a/lib/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart +++ b/lib/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart @@ -3,6 +3,7 @@ import 'package:cake_wallet/src/widgets/standard_slide_button_widget.dart'; import 'package:cake_wallet/themes/extensions/balance_page_theme.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/filter_theme.dart'; +import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart'; import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cw_core/crypto_currency.dart'; @@ -71,6 +72,12 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet { decoration: TextDecoration.none, ); + final tileBackgroundColor = currentTheme.type == ThemeType.light + ? Theme.of(context).extension()!.syncedBackgroundColor + : currentTheme.type == ThemeType.oled + ? Colors.black.withOpacity(0.5) + : Theme.of(context).extension()!.buttonColor; + Widget content = Padding( padding: EdgeInsets.fromLTRB(8, 0, showScrollbar ? 16 : 8, 8), child: Column( @@ -86,6 +93,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet { amount: '', address: paymentIdValue!, itemSubTitleTextStyle: itemSubTitleTextStyle, + tileBackgroundColor: tileBackgroundColor, ), ), StandardTile( @@ -94,6 +102,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet { itemTitleTextStyle: itemTitleTextStyle, itemSubTitle: fiatAmountValue, itemSubTitleTextStyle: itemSubTitleTextStyle, + tileBackgroundColor: tileBackgroundColor, ), const SizedBox(height: 8), StandardTile( @@ -102,6 +111,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet { itemTitleTextStyle: itemTitleTextStyle, itemSubTitle: feeFiatAmount, itemSubTitleTextStyle: itemSubTitleTextStyle, + tileBackgroundColor: tileBackgroundColor, ), const SizedBox(height: 8), Column( @@ -130,6 +140,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet { isBatchSending: isBatchSending, itemTitleTextStyle: itemTitleTextStyle, itemSubTitleTextStyle: itemSubTitleTextStyle, + tileBackgroundColor: tileBackgroundColor, stealthAddress: item.stealthAddress, ) : AddressTile( @@ -140,6 +151,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet { amount: _amount, address: _address, itemSubTitleTextStyle: itemSubTitleTextStyle, + tileBackgroundColor: tileBackgroundColor, ); }, ), @@ -155,6 +167,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet { isBatchSending: true, itemTitleTextStyle: itemTitleTextStyle, itemSubTitleTextStyle: itemSubTitleTextStyle, + tileBackgroundColor: tileBackgroundColor, ), ), ], @@ -215,6 +228,7 @@ class StandardTile extends StatelessWidget { required this.itemTitleTextStyle, this.itemSubTitle, required this.itemSubTitleTextStyle, + required this.tileBackgroundColor, }); final String itemTitle; @@ -222,14 +236,14 @@ class StandardTile extends StatelessWidget { final TextStyle itemTitleTextStyle; final String? itemSubTitle; final TextStyle itemSubTitleTextStyle; + final Color tileBackgroundColor; @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Theme.of(context).extension()!.buttonColor), + decoration: + BoxDecoration(borderRadius: BorderRadius.circular(10), color: tileBackgroundColor), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -259,6 +273,7 @@ class AddressTile extends StatelessWidget { required this.amount, required this.address, required this.itemSubTitleTextStyle, + required this.tileBackgroundColor, }); final String itemTitle; @@ -268,6 +283,7 @@ class AddressTile extends StatelessWidget { final String amount; final String address; final TextStyle itemSubTitleTextStyle; + final Color tileBackgroundColor; @override Widget build(BuildContext context) { @@ -284,7 +300,7 @@ class AddressTile extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), - color: Theme.of(context).extension()!.buttonColor, + color: tileBackgroundColor, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -344,6 +360,7 @@ class AddressExpansionTile extends StatelessWidget { required this.isBatchSending, required this.itemTitleTextStyle, required this.itemSubTitleTextStyle, + required this.tileBackgroundColor, this.stealthAddress, }); @@ -355,6 +372,7 @@ class AddressExpansionTile extends StatelessWidget { final bool isBatchSending; final TextStyle itemTitleTextStyle; final TextStyle itemSubTitleTextStyle; + final Color tileBackgroundColor; final String? stealthAddress; @override @@ -372,7 +390,7 @@ class AddressExpansionTile extends StatelessWidget { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10)), - color: Theme.of(context).extension()!.buttonColor, + color: tileBackgroundColor, ), child: Theme( data: Theme.of(context).copyWith(dividerColor: Colors.transparent), diff --git a/lib/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart b/lib/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart index 26d25b50d..c3ccd7987 100644 --- a/lib/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart +++ b/lib/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart @@ -1,3 +1,4 @@ +import 'package:auto_size_text/auto_size_text.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart'; @@ -85,7 +86,7 @@ class InfoBottomSheet extends BaseBottomSheet { const Spacer(flex: 2), Expanded( flex: 6, - child: Text( + child: AutoSizeText( content!, textAlign: TextAlign.center, style: TextStyle( diff --git a/lib/src/widgets/standard_slide_button_widget.dart b/lib/src/widgets/standard_slide_button_widget.dart index e777155aa..57271b6b5 100644 --- a/lib/src/widgets/standard_slide_button_widget.dart +++ b/lib/src/widgets/standard_slide_button_widget.dart @@ -1,6 +1,7 @@ import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/filter_theme.dart'; import 'package:cake_wallet/themes/extensions/menu_theme.dart'; +import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart'; import 'package:cake_wallet/themes/theme_base.dart'; import 'package:flutter/material.dart'; @@ -33,13 +34,17 @@ class _StandardSlideButtonState extends State { final double effectiveMaxWidth = maxWidth - 2 * sideMargin; const double sliderWidth = 42.0; + final tileBackgroundColor = widget.currentTheme.type == ThemeType.light + ? Theme.of(context).extension()!.syncedBackgroundColor + : widget.currentTheme.type == ThemeType.oled + ? Colors.black.withOpacity(0.5) + : Theme.of(context).extension()!.buttonColor; + return Container( height: widget.height, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), - color: widget.currentTheme.type == ThemeType.light || widget.currentTheme.type == ThemeType.bright - ? Theme.of(context).disabledColor - : widget.currentTheme.type == ThemeType.oled ? Colors.black : Theme.of(context).extension()!.backgroundColor), + color: tileBackgroundColor), child: Stack( alignment: Alignment.centerLeft, children: [ @@ -74,11 +79,11 @@ class _StandardSlideButtonState extends State { height: widget.height - 8, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), - color: widget.currentTheme.type == ThemeType.bright ? Theme.of(context).extension()!.backgroundColor : Theme.of(context).extension()!.buttonColor, + color: Theme.of(context).extension()!.titleColor, ), alignment: Alignment.center, child: Icon(Icons.arrow_forward, - color: Theme.of(context).extension()!.titleColor), + color: widget.currentTheme.type == ThemeType.bright ? Theme.of(context).extension()!.backgroundColor : Theme.of(context).extension()!.buttonColor), ), ), ) diff --git a/lib/store/dashboard/transaction_filter_store.dart b/lib/store/dashboard/transaction_filter_store.dart index f28f7e915..81888109c 100644 --- a/lib/store/dashboard/transaction_filter_store.dart +++ b/lib/store/dashboard/transaction_filter_store.dart @@ -1,6 +1,8 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart'; +import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/view_model/dashboard/action_list_item.dart'; import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart'; +import 'package:cw_core/wallet_type.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/transaction_direction.dart'; import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart'; @@ -10,11 +12,13 @@ part 'transaction_filter_store.g.dart'; class TransactionFilterStore = TransactionFilterStoreBase with _$TransactionFilterStore; abstract class TransactionFilterStoreBase with Store { - TransactionFilterStoreBase() + TransactionFilterStoreBase(this._appStore) : displayIncoming = true, displayOutgoing = true, displaySilentPayments = true; + final AppStore _appStore; + @observable bool displayIncoming; @@ -87,13 +91,15 @@ abstract class TransactionFilterStoreBase with Store { if (allowed && (!displayAll)) { if (item is TransactionListItem) { + final canShowSilentPayment = _appStore.wallet?.type == WalletType.bitcoin && + (bitcoin?.txIsReceivedSilentPayment(item.transaction) ?? false); + allowed = (displayOutgoing && item.transaction.direction == TransactionDirection.outgoing) || (displayIncoming && item.transaction.direction == TransactionDirection.incoming && - !(bitcoin?.txIsReceivedSilentPayment(item.transaction) ?? false)) || - (displaySilentPayments && - (bitcoin?.txIsReceivedSilentPayment(item.transaction) ?? false)); + !canShowSilentPayment) || + (displaySilentPayments && canShowSilentPayment); } else if (item is AnonpayTransactionListItem) { allowed = displayIncoming; } diff --git a/lib/tron/cw_tron.dart b/lib/tron/cw_tron.dart index 2726e873d..8c29dab58 100644 --- a/lib/tron/cw_tron.dart +++ b/lib/tron/cw_tron.dart @@ -84,6 +84,7 @@ class CWTron extends Tron { decimal: token.decimals, enabled: token.enabled, iconPath: token.iconPath, + isPotentialScam: token.isPotentialScam, ); await (wallet as TronWallet).addTronToken(tronToken); } diff --git a/lib/utils/feature_flag.dart b/lib/utils/feature_flag.dart index 6e829d474..c968c5d75 100644 --- a/lib/utils/feature_flag.dart +++ b/lib/utils/feature_flag.dart @@ -6,4 +6,5 @@ class FeatureFlag { static const bool isInAppTorEnabled = false; static const bool isBackgroundSyncEnabled = true; static const int verificationWordsCount = kDebugMode ? 0 : 2; + static const bool hasDevOptions = bool.fromEnvironment('hasDevOptions', defaultValue: kDebugMode); } \ No newline at end of file diff --git a/lib/view_model/buy/buy_sell_view_model.dart b/lib/view_model/buy/buy_sell_view_model.dart index 436f66905..bf05109ad 100644 --- a/lib/view_model/buy/buy_sell_view_model.dart +++ b/lib/view_model/buy/buy_sell_view_model.dart @@ -210,9 +210,12 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S final enteredAmount = double.tryParse(amount.replaceAll(',', '.')) ?? 0; - if (!isReadyToTrade) { + if (!isReadyToTrade && !isBuySellQuotFailed) { cryptoAmount = S.current.fetching; return; + } else if (isBuySellQuotFailed) { + cryptoAmount = ''; + return; } if (bestRateQuote != null) { @@ -238,8 +241,12 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S final enteredAmount = double.tryParse(amount.replaceAll(',', '.')) ?? 0; - if (!isReadyToTrade) { + if (!isReadyToTrade && !isBuySellQuotFailed) { fiatAmount = S.current.fetching; + return; + } else if (isBuySellQuotFailed) { + fiatAmount = ''; + return; } if (bestRateQuote != null) { @@ -379,7 +386,22 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S Future calculateBestRate() async { buySellQuotState = BuySellQuotLoading(); - final result = await Future.wait?>(providerList.map((element) => element + final List validProviders = providerList.where((provider) { + if (isBuyAction) { + return provider.supportedCryptoList.any((pair) => + pair.from == cryptoCurrency && pair.to == fiatCurrency); + } else { + return provider.supportedFiatList.any((pair) => + pair.from == fiatCurrency && pair.to == cryptoCurrency); + } + }).toList(); + + if (validProviders.isEmpty) { + buySellQuotState = BuySellQuotFailed(); + return; + } + + final result = await Future.wait?>(validProviders.map((element) => element .fetchQuote( cryptoCurrency: cryptoCurrency, fiatCurrency: fiatCurrency, diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart index cd10c55c3..1a1a48e96 100644 --- a/lib/view_model/dashboard/balance_view_model.dart +++ b/lib/view_model/dashboard/balance_view_model.dart @@ -231,7 +231,7 @@ abstract class BalanceViewModelBase with Store { formattedAssetTitle: _formatterAsset(key))); } final fiatCurrency = settingsStore.fiatCurrency; - final price = fiatConvertationStore.prices[key] ?? 0; + final price = key.isPotentialScam ? 0.0 : fiatConvertationStore.prices[key] ?? 0; // if (price == null) { // throw Exception('Price is null for: $key'); diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 57be4e8d1..bfd198148 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -270,36 +270,16 @@ abstract class DashboardViewModelBase with Store { reaction((_) => appStore.wallet, (wallet) { _onWalletChange(wallet); _checkMweb(); - showDecredInfoCard = wallet?.type == WalletType.decred; + showDecredInfoCard = wallet?.type == WalletType.decred && + sharedPreferences.getBool(PreferencesKey.showDecredInfoCard) != false; }); _transactionDisposer?.reaction.dispose(); - - _transactionDisposer = - reaction((_) => appStore.wallet!.transactionHistory.transactions.values.toList(), - (List txs) { - transactions.clear(); - - transactions.addAll( - txs.where((tx) { - if (wallet.type == WalletType.monero) { - return monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id; - } - if (wallet.type == WalletType.wownero) { - return wow.wownero!.getTransactionInfoAccountId(tx) == - wow.wownero!.getCurrentAccount(wallet).id; - } - return true; - }).map( - (tx) => TransactionListItem( - transaction: tx, - balanceViewModel: balanceViewModel, - settingsStore: appStore.settingsStore, - key: ValueKey('${wallet.type.name}_transaction_history_item_${tx.id}_key'), - ), - ), - ); - }); + _transactionDisposer = reaction( + (_) => + appStore.wallet!.transactionHistory.transactions.length * + appStore.wallet!.transactionHistory.transactions.values.first.confirmations, + _transactionDisposerCallback); _checkMweb(); reaction((_) => settingsStore.mwebAlwaysScan, (bool value) => _checkMweb()); @@ -307,6 +287,48 @@ abstract class DashboardViewModelBase with Store { final SilentPaymentsScanningViewModel _silentPaymentsScanningViewModel; + bool _isTransactionDisposerCallbackRunning = false; + + void _transactionDisposerCallback(int _) async { + // Simple check to prevent the callback from being called multiple times in the same frame + if (_isTransactionDisposerCallbackRunning) return; + _isTransactionDisposerCallbackRunning = true; + await Future.delayed(Duration.zero); + + try { + final currentAccountId = wallet.type == WalletType.monero + ? monero!.getCurrentAccount(wallet).id + : wallet.type == WalletType.wownero + ? wow.wownero!.getCurrentAccount(wallet).id + : null; + final List relevantTxs = []; + + for (final tx in appStore.wallet!.transactionHistory.transactions.values) { + bool isRelevant = true; + if (wallet.type == WalletType.monero) { + isRelevant = monero!.getTransactionInfoAccountId(tx) == currentAccountId; + } else if (wallet.type == WalletType.wownero) { + isRelevant = wow.wownero!.getTransactionInfoAccountId(tx) == currentAccountId; + } + + if (isRelevant) { + relevantTxs.add(tx); + } + } + // printV("Transaction disposer callback (relevantTxs: ${relevantTxs.length} current: ${transactions.length})"); + + transactions.clear(); + transactions.addAll(relevantTxs.map((tx) => TransactionListItem( + transaction: tx, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore, + key: ValueKey('${wallet.type.name}_transaction_history_item_${tx.id}_key'), + ))); + } finally { + _isTransactionDisposerCallbackRunning = false; + } + } + void _checkMweb() { if (hasMweb) { mwebEnabled = bitcoin!.getMwebEnabled(wallet); @@ -557,7 +579,8 @@ abstract class DashboardViewModelBase with Store { disableBackgroundSync(); return; } - final resp = await FlutterDaemon().startBackgroundSync(settingsStore.currentSyncMode.frequency.inMinutes); + final resp = await FlutterDaemon() + .startBackgroundSync(settingsStore.currentSyncMode.frequency.inMinutes); printV("Background sync enabled: $resp"); backgroundSyncEnabled = true; } @@ -791,31 +814,11 @@ abstract class DashboardViewModelBase with Store { _transactionDisposer?.reaction.dispose(); - _transactionDisposer = - reaction((_) => appStore.wallet!.transactionHistory.transactions.values.toList(), - (List txs) { - transactions.clear(); - - transactions.addAll( - txs.where((tx) { - if (wallet.type == WalletType.monero) { - return monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id; - } - if (wallet.type == WalletType.wownero) { - return wow.wownero!.getTransactionInfoAccountId(tx) == - wow.wownero!.getCurrentAccount(wallet).id; - } - return true; - }).map( - (tx) => TransactionListItem( - transaction: tx, - balanceViewModel: balanceViewModel, - settingsStore: appStore.settingsStore, - key: ValueKey('${wallet.type.name}_transaction_history_item_${tx.id}_key'), - ), - ), - ); - }); + _transactionDisposer = reaction( + (_) => + appStore.wallet!.transactionHistory.transactions.length * + appStore.wallet!.transactionHistory.transactions.values.first.confirmations, + _transactionDisposerCallback); } @action diff --git a/lib/view_model/dashboard/home_settings_view_model.dart b/lib/view_model/dashboard/home_settings_view_model.dart index 4a85ec89a..381ae0614 100644 --- a/lib/view_model/dashboard/home_settings_view_model.dart +++ b/lib/view_model/dashboard/home_settings_view_model.dart @@ -83,6 +83,7 @@ abstract class HomeSettingsViewModelBase with Store { decimal: token.decimals, contractAddress: contractAddress, iconPath: token.iconPath, + isPotentialScam: token.isPotentialScam, ); await ethereum!.addErc20Token(_balanceViewModel.wallet, erc20token); @@ -95,6 +96,7 @@ abstract class HomeSettingsViewModelBase with Store { decimal: token.decimals, contractAddress: contractAddress, iconPath: token.iconPath, + isPotentialScam: token.isPotentialScam, ); await polygon!.addErc20Token(_balanceViewModel.wallet, polygonToken); } diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index 8b7349e9a..58b5e5756 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -23,8 +23,6 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart'; -import 'package:cake_wallet/decred/decred.dart'; import 'package:cake_wallet/core/wallet_change_listener_view_model.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; @@ -39,7 +37,6 @@ import 'package:cake_wallet/exchange/provider/exchange_provider.dart'; import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart'; import 'package:cake_wallet/exchange/provider/swaptrade_exchange_provider.dart'; import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart'; -import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart'; import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart'; import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart'; import 'package:cake_wallet/exchange/trade.dart'; @@ -181,7 +178,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with List get _allProviders => [ ChangeNowExchangeProvider(settingsStore: _settingsStore), SideShiftExchangeProvider(), - SimpleSwapExchangeProvider(), ThorChainExchangeProvider(tradesStore: trades), ChainflipExchangeProvider(tradesStore: trades), if (FeatureFlag.isExolixEnabled) ExolixExchangeProvider(), diff --git a/lib/view_model/node_list/node_create_or_edit_view_model.dart b/lib/view_model/node_list/node_create_or_edit_view_model.dart index 8fbe174e3..7e4e73915 100644 --- a/lib/view_model/node_list/node_create_or_edit_view_model.dart +++ b/lib/view_model/node_list/node_create_or_edit_view_model.dart @@ -1,7 +1,6 @@ import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/entities/qr_scanner.dart'; import 'package:cake_wallet/store/settings_store.dart'; -import 'package:cw_core/utils/print_verbose.dart'; import 'package:flutter/cupertino.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; diff --git a/lib/view_model/restore_from_backup_view_model.dart b/lib/view_model/restore_from_backup_view_model.dart index 1c3dc5048..a74beeaea 100644 --- a/lib/view_model/restore_from_backup_view_model.dart +++ b/lib/view_model/restore_from_backup_view_model.dart @@ -7,7 +7,6 @@ import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/main.dart'; import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/core/backup_service.dart'; import 'package:cw_core/node.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/authentication_store.dart'; @@ -44,13 +43,22 @@ abstract class RestoreFromBackupViewModelBase with Store { final file = File(filePath); - - await backupService.importBackupFile(file, password); + try { + await backupService.importBackupFile(file, password); + } catch (e, s) { + if (e.toString().contains("unknown_backup_version")) { + state = FailureState('This is not a valid backup file, please make sure you selected the correct backup file'); + } else { + state = FailureState('Failed to restore backup, please try again'); + ExceptionHandler.onError(FlutterErrorDetails(exception: e, stack: s, silent: true)); + } + } try { await initializeAppAtRoot(reInitializing: true); } catch (e, s) { - throw Exception('failed_app_initialization: $e $s'); + state = FailureState('Failed app initialization, please try again'); + ExceptionHandler.onError(FlutterErrorDetails(exception: e, stack: s, silent: true)); } final store = getIt.get(); diff --git a/lib/view_model/send/output.dart b/lib/view_model/send/output.dart index 98c05e95c..8662ef618 100644 --- a/lib/view_model/send/output.dart +++ b/lib/view_model/send/output.dart @@ -309,37 +309,26 @@ abstract class OutputBase with Store { switch (_wallet.type) { case WalletType.monero: + case WalletType.ethereum: + case WalletType.polygon: + case WalletType.solana: + case WalletType.tron: + case WalletType.haven: + case WalletType.zano: + case WalletType.nano: + case WalletType.decred: maximumFractionDigits = 12; break; case WalletType.bitcoin: - maximumFractionDigits = 8; - break; case WalletType.litecoin: - maximumFractionDigits = 8; - break; case WalletType.bitcoinCash: maximumFractionDigits = 8; break; - case WalletType.haven: - maximumFractionDigits = 12; - break; - case WalletType.ethereum: - case WalletType.polygon: - maximumFractionDigits = 12; - break; - case WalletType.solana: - maximumFractionDigits = 12; - break; - case WalletType.tron: - maximumFractionDigits = 12; - break; case WalletType.wownero: maximumFractionDigits = 11; break; - case WalletType.zano: - maximumFractionDigits = 12; - break; - default: + case WalletType.none: + case WalletType.banano: break; } diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index ac1229d05..31ec974ec 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -217,14 +217,50 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor @computed String get balance { - if (coinTypeToSpendFrom == UnspentCoinType.mweb) { + if (walletType == WalletType.litecoin && coinTypeToSpendFrom == UnspentCoinType.mweb) { return balanceViewModel.balances.values.first.secondAvailableBalance; - } else if (coinTypeToSpendFrom == UnspentCoinType.nonMweb) { + } else if (walletType == WalletType.litecoin && coinTypeToSpendFrom == UnspentCoinType.nonMweb) { return balanceViewModel.balances.values.first.availableBalance; } return wallet.balance[selectedCryptoCurrency]!.formattedFullAvailableBalance; } + @action + Future updateSendingBalance() async { + // force the sendingBalance to recompute since unspent coins aren't observable + // or at least mobx can't detect the changes + + final currentType = coinTypeToSpendFrom; + + if (currentType == UnspentCoinType.any) { + coinTypeToSpendFrom = UnspentCoinType.nonMweb; + } else if (currentType == UnspentCoinType.nonMweb) { + coinTypeToSpendFrom = UnspentCoinType.any; + } else if (currentType == UnspentCoinType.mweb) { + coinTypeToSpendFrom = UnspentCoinType.nonMweb; + } + + // set it back to the original value: + coinTypeToSpendFrom = currentType; + } + + @computed + String get sendingBalance { + // only for electrum, monero, wownero, decred wallets atm: + switch (wallet.type) { + case WalletType.bitcoin: + case WalletType.litecoin: + case WalletType.bitcoinCash: + case WalletType.monero: + case WalletType.wownero: + case WalletType.decred: + return wallet.formatCryptoAmount( + unspentCoinsListViewModel.getSendingBalance(coinTypeToSpendFrom).toString()); + default: + return balance; + } + } + @computed bool get isFiatDisabled => balanceViewModel.isFiatDisabled; @@ -357,9 +393,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor @action Future createTransaction({ExchangeProvider? provider}) async { try { - state = IsExecutingState(); - - if (wallet.isHardwareWallet) state = IsAwaitingDeviceResponseState(); + if (wallet.isHardwareWallet) + state = IsAwaitingDeviceResponseState(); + else + state = IsExecutingState(); pendingTransaction = await wallet.createTransaction(_credentials(provider)); diff --git a/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart b/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart index d4fadb2f1..a54e2be49 100644 --- a/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart +++ b/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart @@ -131,6 +131,36 @@ abstract class UnspentCoinsListViewModelBase with Store { } } + List _getSpecificUnspents(UnspentCoinType overrideCoinTypeToSpendFrom) { + switch (wallet.type) { + case WalletType.monero: + return monero!.getUnspents(wallet); + case WalletType.wownero: + return wownero!.getUnspents(wallet); + case WalletType.bitcoin: + case WalletType.litecoin: + case WalletType.bitcoinCash: + return bitcoin!.getUnspents(wallet, coinTypeToSpendFrom: overrideCoinTypeToSpendFrom); + case WalletType.decred: + return decred!.getUnspents(wallet); + default: + return List.empty(); + } + } + + @action + int getSendingBalance(UnspentCoinType overrideCoinTypeToSpendFrom) { + // return items.where((element) => element.isSending).fold(0, (previousValue, element) => previousValue + element.value); + // go through all unspent coins and add up the value minus frozen and non sending: + int total = 0; + + for (final item in _getSpecificUnspents(overrideCoinTypeToSpendFrom)) { + if (item.isFrozen || !item.isSending) continue; + total += item.value; + } + return total; + } + @action void _updateUnspentCoinsInfo() { items.clear(); diff --git a/lib/wownero/cw_wownero.dart b/lib/wownero/cw_wownero.dart index e20b6fbbf..26092486b 100644 --- a/lib/wownero/cw_wownero.dart +++ b/lib/wownero/cw_wownero.dart @@ -361,4 +361,9 @@ class CWWownero extends Wownero { void wownerocCheck() { checkIfMoneroCIsFine(); } + + @override + Map> debugCallLength() { + return wownero_wallet_api.debugCallLength(); + } } diff --git a/lib/zano/cw_zano.dart b/lib/zano/cw_zano.dart index 19fec04e4..7bd515e32 100644 --- a/lib/zano/cw_zano.dart +++ b/lib/zano/cw_zano.dart @@ -131,4 +131,9 @@ class CWZano extends Zano { @override bool validateAddress(String address) => ZanoUtils.validateAddress(address); + + @override + Map> debugCallLength() { + return api.debugCallLength(); + } } diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index a87e938f3..b551d629d 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -107,7 +107,7 @@ install(CODE " set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") -if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") set(LIB_TRIPLET "aarch64-linux-gnu") else() set(LIB_TRIPLET "x86_64-linux-gnu") diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 01b922894..000000000 --- a/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,27 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include -#include -#include -#include - -void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) devicelocale_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "DevicelocalePlugin"); - devicelocale_plugin_register_with_registrar(devicelocale_registrar); - g_autoptr(FlPluginRegistrar) flutter_local_authentication_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterLocalAuthenticationPlugin"); - flutter_local_authentication_plugin_register_with_registrar(flutter_local_authentication_registrar); - g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); - flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); - g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); - url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); -} diff --git a/linux/flutter/generated_plugin_registrant.h b/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47bc..000000000 --- a/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake deleted file mode 100644 index f52be7481..000000000 --- a/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,28 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - devicelocale - flutter_local_authentication - flutter_secure_storage_linux - url_launcher_linux -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST - sp_scanner -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift deleted file mode 100644 index 528de8c42..000000000 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// Generated file. Do not edit. -// - -import FlutterMacOS -import Foundation - -import connectivity_plus -import cw_decred -import cw_mweb -import device_info_plus -import devicelocale -import fast_scanner -import flutter_inappwebview_macos -import flutter_local_authentication -import flutter_secure_storage_macos -import in_app_review -import package_info_plus -import path_provider_foundation -import share_plus -import shared_preferences_foundation -import universal_ble -import url_launcher_macos -import wakelock_plus - -func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) - CwDecredPlugin.register(with: registry.registrar(forPlugin: "CwDecredPlugin")) - CwMwebPlugin.register(with: registry.registrar(forPlugin: "CwMwebPlugin")) - DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) - DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) - MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) - InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) - FlutterLocalAuthenticationPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalAuthenticationPlugin")) - FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) - InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin")) - FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) - PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) - SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) - SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) - UniversalBlePlugin.register(with: registry.registrar(forPlugin: "UniversalBlePlugin")) - UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) - WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) -} diff --git a/macos/Podfile.lock b/macos/Podfile.lock index cc6ae6e3b..689f0ea03 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -3,7 +3,6 @@ PODS: - FlutterMacOS - ReachabilitySwift - cw_mweb (0.0.1): - - cw_decred (0.0.1): - FlutterMacOS - device_info_plus (0.0.1): - FlutterMacOS @@ -46,7 +45,6 @@ PODS: DEPENDENCIES: - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) - cw_mweb (from `Flutter/ephemeral/.symlinks/plugins/cw_mweb/macos`) - - cw_decred (from `Flutter/ephemeral/.symlinks/plugins/cw_decred/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`) - fast_scanner (from `Flutter/ephemeral/.symlinks/plugins/fast_scanner/macos`) @@ -74,10 +72,6 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos cw_mweb: :path: Flutter/ephemeral/.symlinks/plugins/cw_mweb/macos - cw_decred: - :path: Flutter/ephemeral/.symlinks/plugins/cw_decred/macos - cw_monero: - :path: Flutter/ephemeral/.symlinks/plugins/cw_monero/macos device_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos devicelocale: @@ -114,8 +108,6 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747 cw_mweb: 7440b12ead811dda972a9918442ea2a458e8742c - cw_monero: ec03de55a19c4a2b174ea687e0f4202edc716fa4 - cw_decred: 0c93fbeb31bd97a6ad4ec5680960af0943bfca78 device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 fast_scanner: d31bae07e2653403a69dac99fb710c1722b16a97 diff --git a/pubspec_base.yaml b/pubspec_base.yaml index f262499bb..844db8871 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -10,7 +10,7 @@ dependencies: url: https://github.com/cake-tech/qr.flutter.git ref: cake-4.0.2 version: 4.0.2 - shared_preferences: 2.3.2 + shared_preferences: 2.5.3 # provider: ^6.0.3 rxdart: ^0.28.0 yaml: ^3.1.1 @@ -21,7 +21,7 @@ dependencies: http: ^1.1.0 path_provider: ^2.0.11 mobx: ^2.1.4 - flutter_mobx: ^2.0.6+5 + flutter_mobx: 2.0.6+5 flutter_slidable: ^3.0.1 share_plus: ^10.0.0 # date_range_picker: ^1.0.6 @@ -83,7 +83,6 @@ dependencies: version: 1.0.0 flutter_plugin_android_lifecycle: 2.0.23 path_provider_android: ^2.2.1 - shared_preferences_android: 2.3.3 url_launcher_android: 6.3.14 url_launcher_linux: 3.1.1 # https://github.com/flutter/flutter/issues/153083 sensitive_clipboard: diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 1ca01f1c9..9d54afa04 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "شراء Bitcoin", "buy_now": "اشتري الآن", "buy_provider_unavailable": "مزود حاليا غير متوفر.", + "buy_sell_pair_is_not_supported_warning": "لا يتم دعم زوج العملة هذا من قبل أي مزود لطريقة الدفع المحددة. الرجاء اختيار زوج مختلف أو محاولة تغيير طريقة الدفع.", "buy_with": "اشتر بواسطة", "by_cake_pay": "عن طريق Cake Pay", "cake_2fa_preset": " كعكة 2FA مسبقا", @@ -131,6 +132,7 @@ "change_rep_message": "؟ﻦﻴﻠﺜﻤﻤﻟﺍ ﺮﻴﻴﻐﺗ ﺪﻳﺮﺗ ﻚﻧﺃ ﺪﻛﺄﺘﻣ ﺖﻧﺃ ﻞﻫ", "change_rep_successful": "تم تغيير ممثل بنجاح", "change_selected_exchanges": "تغيير التبادلات المحددة", + "change_selected_pair": "تغيير الزوج المحدد", "change_wallet_alert_content": "هل تريد تغيير المحفظة الحالية إلى ${wallet_name}؟", "change_wallet_alert_title": "تغيير المحفظة الحالية", "choose_a_payment_method": "اختر طريقة الدفع", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "الرجاء محاولة الاتصال بعقدة أخرى", "please_wait": "انتظر من فضلك", "polygonscan_history": "ﻥﺎﻜﺴﻧﻮﺠﻴﻟﻮﺑ ﺦﻳﺭﺎﺗ", + "potential_scam": "عملية احتيال محتملة", "powered_by": "بدعم من ${title}", "pre_seed_button_text": "انا أفهم. أرني سييد الخاص بي", "pre_seed_description": "في الصفحة التالية ستشاهد سلسلة من الكلمات ${words}. هذه هي سييد الفريدة والخاصة بك وهي الطريقة الوحيدة لاسترداد محفظتك في حالة فقدها أو عطلها. تقع على عاتقك مسؤولية تدوينها وتخزينها في مكان آمن خارج تطبيق Cake Wallet.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "يتم المزامنة", "sync_status_timed_out": "نفد وقته", "sync_status_unsupported": "عقدة غير مدعومة", + "synchronizing": "المزامنة", "syncing_wallet_alert_content": "قد لا يكتمل رصيدك وقائمة المعاملات الخاصة بك حتى تظهر عبارة “SYNCHRONIZED“ في الأعلى. انقر / اضغط لمعرفة المزيد.", "syncing_wallet_alert_title": "محفظتك تتم مزامنتها", "template": "قالب", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 9ae3678b7..716b632ce 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Купуване на Bitcoin", "buy_now": "Купи сега", "buy_provider_unavailable": "Понастоящем доставчик не е наличен.", + "buy_sell_pair_is_not_supported_warning": "Тази валутна двойка не се поддържа от нито един доставчик за избрания начин на плащане. Моля, изберете друга двойка или опитайте да промените начина на плащане.", "buy_with": "Купуване чрез", "by_cake_pay": "от Cake Pay", "cake_2fa_preset": "Торта 2FA Preset", @@ -131,6 +132,7 @@ "change_rep_message": "Сигурни ли сте, че искате да смените представителите?", "change_rep_successful": "Успешно промени представител", "change_selected_exchanges": "Променете избраните борси", + "change_selected_pair": "Променете избраната двойка", "change_wallet_alert_content": "Искате ли да смените сегашния портфейл на ${wallet_name}?", "change_wallet_alert_title": "Смяна на сегашния портфейл", "choose_a_payment_method": "Изберете начин на плащане", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "Моля, опитайте се да се свържете към друг node.", "please_wait": "Моля Изчакай", "polygonscan_history": "История на PolygonScan", + "potential_scam": "Потенциална измама", "powered_by": "Powered by ${title}", "pre_seed_button_text": "Разбирам. Покажи seed", "pre_seed_description": "На следващата страница ще видите поредица от ${words} думи. Това е вашият таен личен seed и е единственият начин да възстановите портфейла си. Отговорността за съхранението му на сигурно място извън приложението на Cake Wallet е изцяло ВАША.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "СИНХРОНИЗИРАНЕ", "sync_status_timed_out": "ВРЕМЕТО ИЗТЕЧЕ", "sync_status_unsupported": "Неподдържан възел", + "synchronizing": "Синхронизиране", "syncing_wallet_alert_content": "Списъкът ви с баланс и транзакции може да не е пълен, докато в горната част не пише „СИНХРОНИЗИРАН“. Кликнете/докоснете, за да научите повече.", "syncing_wallet_alert_title": "Вашият портфейл се синхронизира", "template": "Шаблон", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 7894346d6..ba559e654 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Nakoupit Bitcoin", "buy_now": "Kup nyní", "buy_provider_unavailable": "Poskytovatel aktuálně nedostupný.", + "buy_sell_pair_is_not_supported_warning": "Tento dvojice měny není podporován žádným poskytovatelem pro vybranou metodu platby. Vyberte prosím jiný pár nebo zkuste změnit způsob platby.", "buy_with": "Nakoupit pomocí", "by_cake_pay": "od Cake Pay", "cake_2fa_preset": "Předvolba Cake 2FA", @@ -131,6 +132,7 @@ "change_rep_message": "Jste si jisti, že chcete změnit zástupce?", "change_rep_successful": "Úspěšně změnil zástupce", "change_selected_exchanges": "Změnit vybrané výměny", + "change_selected_pair": "Změnit vybraný pár", "change_wallet_alert_content": "Opravdu chcete změnit aktivní peněženku na ${wallet_name}?", "change_wallet_alert_title": "Přepnout peněženku", "choose_a_payment_method": "Vyberte metodu platby", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "Zkuste se prosím připojit k jinému uzlu", "please_wait": "Prosím, čekejte", "polygonscan_history": "Historie PolygonScan", + "potential_scam": "Potenciální podvod", "powered_by": "Zajišťuje ${title}", "pre_seed_button_text": "Rozumím. Ukaž mi můj seed.", "pre_seed_description": "Na následující stránce uvidíte sérii ${words} slov. Je to váš tzv. seed a je to JEDINÁ možnost, jak můžete později obnovit svou peněženku v případě ztráty nebo poruchy. Je VAŠÍ zodpovědností zapsat si ho a uložit si ho na bezpečném místě mimo aplikaci Cake Wallet.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "SYNCHRONIZUJI", "sync_status_timed_out": "ČAS VYPRŠEL", "sync_status_unsupported": "Nepodporovaný uzel", + "synchronizing": "Synchronizace", "syncing_wallet_alert_content": "Váš seznam zůstatků a transakcí nemusí být úplný, dokud nebude nahoře uvedeno „SYNCHRONIZOVANÉ“. Kliknutím/klepnutím se dozvíte více.", "syncing_wallet_alert_title": "Vaše peněženka se synchronizuje", "template": "Šablona", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 779ba694c..6636625d1 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Bitcoin kaufen", "buy_now": "Kaufe jetzt", "buy_provider_unavailable": "Anbieter derzeit nicht verfügbar.", + "buy_sell_pair_is_not_supported_warning": "Dieses Währungspaar wird von keinem Anbieter für die ausgewählte Zahlungsmethode unterstützt. Bitte wählen Sie ein anderes Paar oder versuchen Sie, die Zahlungsmethode zu ändern.", "buy_with": "Kaufen mit", "by_cake_pay": "von Cake Pay", "cake_2fa_preset": "Cake 2FA-Voreinstellung", @@ -131,6 +132,7 @@ "change_rep_message": "Sind Sie sicher, dass Sie den Vertreter wechseln möchten?", "change_rep_successful": "Vertreter erfolgreich gerändert", "change_selected_exchanges": "Änderung ausgewählter Austausch", + "change_selected_pair": "Ändern Sie das ausgewählte Paar", "change_wallet_alert_content": "Möchten Sie die aktuelle Wallet zu ${wallet_name} ändern?", "change_wallet_alert_title": "Aktuelle Wallet ändern", "choose_a_payment_method": "Wählen Sie eine Zahlungsmethode", @@ -531,13 +533,14 @@ "please_choose_one": "Bitte wählen Sie einen", "please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist", "please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.", - "Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.", "please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.", + "Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.", "please_select": "Bitte auswählen:", "please_select_backup_file": "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.", "please_try_to_connect_to_another_node": "Bitte versuchen Sie, sich mit einem anderen Knoten zu verbinden", "please_wait": "Warten Sie mal", "polygonscan_history": "PolygonScan-Verlauf", + "potential_scam": "Potenzieller Betrug", "powered_by": "Ermöglicht durch ${title}", "pre_seed_button_text": "Verstanden. Zeig mir meinen Seed", "pre_seed_description": "Auf der nächsten Seite sehen Sie eine Reihe von ${words} Wörtern. Dies ist Ihr einzigartiger und privater Seed und der EINZIGE Weg, um Ihre Wallet im Falle eines Verlusts oder einer Fehlfunktion wiederherzustellen. Es liegt in IHRER Verantwortung, ihn aufzuschreiben und an einem sicheren Ort außerhalb der Cake Wallet-App aufzubewahren.", @@ -826,6 +829,7 @@ "sync_status_syncronizing": "SYNCHRONISIERE", "sync_status_timed_out": "Zeitlich abgestimmt", "sync_status_unsupported": "Nicht unterstützter Knoten", + "synchronizing": "Synchronisierung", "syncing_wallet_alert_content": "Ihr Kontostand und Ihre Transaktionsliste sind möglicherweise erst vollständig, wenn oben „SYNCHRONISIERT“ steht. Klicken/tippen Sie, um mehr zu erfahren.", "syncing_wallet_alert_title": "Ihr Wallet wird synchronisiert", "template": "Vorlage", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 0224c159c..f059ef27e 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Buy Bitcoin", "buy_now": "Buy Now", "buy_provider_unavailable": "Provider currently unavailable.", + "buy_sell_pair_is_not_supported_warning": "This currency pair isn’t supported by any provider for the selected payment method. Please choose a different pair or try changing the payment method.", "buy_with": "Buy with", "by_cake_pay": "by Cake Pay", "cake_2fa_preset": "Cake 2FA Preset", @@ -131,6 +132,7 @@ "change_rep_message": "Are you sure that you want to change representatives?", "change_rep_successful": "Successfully changed representative", "change_selected_exchanges": "Change Selected Exchanges", + "change_selected_pair": "Change Selected Pair", "change_wallet_alert_content": "Do you want to change current wallet to ${wallet_name}?", "change_wallet_alert_title": "Change current wallet", "choose_a_payment_method": "Choose a payment method", @@ -538,6 +540,7 @@ "please_try_to_connect_to_another_node": "Please try to connect to another node", "please_wait": "Please wait", "polygonscan_history": "PolygonScan history", + "potential_scam": "Potential Scam", "powered_by": "Powered by ${title}", "pre_seed_button_text": "I understand. Show me my seed", "pre_seed_description": "On the next page you will see a series of ${words} words. This is your unique and private seed and it is the ONLY way to recover your wallet in case of loss or malfunction. It is YOUR responsibility to write it down and store it in a safe place outside of the Cake Wallet app.", @@ -826,6 +829,7 @@ "sync_status_syncronizing": "SYNCHRONIZING", "sync_status_timed_out": "TIMED OUT", "sync_status_unsupported": "UNSUPPORTED NODE", + "synchronizing": "Synchronizing", "syncing_wallet_alert_content": "Your balance and transaction list may not be complete until it says “SYNCHRONIZED” at the top. Click/tap to learn more.", "syncing_wallet_alert_title": "Your wallet is syncing", "template": "Template", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 2829757ac..d9bd87d77 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -69,7 +69,7 @@ "avg_savings": "Ahorro promedio", "awaitDAppProcessing": "Espere a que la dApp termine de procesarse.", "awaiting_payment_confirmation": "Esperando confirmación de pago", - "background_sync": "Sincronización de fondo", + "background_sync": "Sincronización en segundo plano", "background_sync_mode": "Modo de sincronización en segundo plano", "backup": "Apoyo", "backup_file": "Archivo de respaldo", @@ -93,6 +93,7 @@ "buy_bitcoin": "Comprar Bitcoin", "buy_now": "Comprar ahora", "buy_provider_unavailable": "Proveedor actualmente no disponible.", + "buy_sell_pair_is_not_supported_warning": "Este par de divisas no es compatible con ningún proveedor para el método de pago seleccionado. Elija un par diferente o intente cambiar el método de pago.", "buy_with": "Compra con", "by_cake_pay": "por Cake Pay", "cake_2fa_preset": "Pastel 2FA preestablecido", @@ -131,6 +132,7 @@ "change_rep_message": "¿Estás seguro de que quieres cambiar de representante?", "change_rep_successful": "Representante cambiado con éxito", "change_selected_exchanges": "Cambiar intercambios seleccionados", + "change_selected_pair": "Cambiar el par seleccionado", "change_wallet_alert_content": "¿Quieres cambiar la billetera actual a ${wallet_name}?", "change_wallet_alert_title": "Cambiar billetera actual", "choose_a_payment_method": "Elija un método de pago", @@ -538,6 +540,7 @@ "please_try_to_connect_to_another_node": "Intenta conectarte a otro nodo", "please_wait": "Espera por favor", "polygonscan_history": "Historial de PolygonScan", + "potential_scam": "Estafa potencial", "powered_by": "Posible gracias a ${title}", "pre_seed_button_text": "Entiendo. Muéstrame mi semilla", "pre_seed_description": "En la página siguiente verás una serie de ${words} palabras. Esta es su semilla única y privada y es la ÚNICA forma de recuperar tu billetera en caso de pérdida o mal funcionamiento. Es TU responsabilidad escribirla y guardarla en un lugar seguro fuera de la aplicación Cake Wallet.", @@ -826,6 +829,7 @@ "sync_status_syncronizing": "SINCRONIZANDO", "sync_status_timed_out": "CADUCADO", "sync_status_unsupported": "Nodo no compatible", + "synchronizing": "Sincronización", "syncing_wallet_alert_content": "Es posible que su lista de saldo y transacciones no esté completa hasta que diga \"SINCRONIZADO\" en la parte superior. Haga clic/toque para obtener más información.", "syncing_wallet_alert_title": "Tu billetera se está sincronizando", "template": "Plantilla", @@ -932,8 +936,8 @@ "understand": "Entiendo", "unlock": "desbloquear", "unmatched_currencies": "La moneda de tu billetera actual no coincide con la del QR escaneado", - "unrestricted_background_service": "Servicio de antecedentes sin restricciones", - "unrestricted_background_service_notice": "Para habilitar la sincronización de antecedentes, debe habilitar el servicio de fondo sin restricciones", + "unrestricted_background_service": "Servicio de sincronización sin restricciones", + "unrestricted_background_service_notice": "Para habilitar la sincronización en segundo plano, debes habilitar el servicio de sincronización sin restricciones", "unspent_change": "Cambiar", "unspent_coins_details_title": "Detalles de monedas no gastadas", "unspent_coins_title": "Monedas no gastadas", @@ -1031,4 +1035,4 @@ "you_will_receive_estimated_amount": "Recibirá(estimado )", "you_will_send": "Convertir de", "yy": "YY" -} \ No newline at end of file +} diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 6b2498909..a9e1b25c0 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Acheter du Bitcoin", "buy_now": "Acheter maintenant", "buy_provider_unavailable": "Fournisseur actuellement indisponible.", + "buy_sell_pair_is_not_supported_warning": "Cette paire de devises n'est prise en charge par aucun fournisseur pour le mode de paiement sélectionné. Veuillez choisir une autre paire ou essayer de modifier le mode de paiement.", "buy_with": "Acheter avec", "by_cake_pay": "par Cake Pay", "cake_2fa_preset": "Cake 2FA prédéfini", @@ -131,6 +132,7 @@ "change_rep_message": "Êtes-vous sûr de vouloir changer de représentant ?", "change_rep_successful": "Représentant changé avec succès", "change_selected_exchanges": "Modifier les échanges sélectionnés", + "change_selected_pair": "Modifier la paire sélectionnée", "change_wallet_alert_content": "Souhaitez-vous changer le portefeuille (wallet) actuel vers ${wallet_name} ?", "change_wallet_alert_title": "Changer le portefeuille (wallet) actuel", "choose_a_payment_method": "Choisissez un mode de paiement", @@ -303,7 +305,7 @@ "etherscan_history": "Historique Etherscan", "event": "Événement", "events": "Événements", - "exchange": "Échange", + "exchange": "Acheter / Vendre", "exchange_incorrect_current_wallet_for_xmr": "Si vous souhaitez échanger des XMR depuis le solde Monero de votre Cake Wallet, veuillez d'abord passer à votre portefeuille Monero.", "exchange_new_template": "Nouveau modèle d'échange", "exchange_provider_unsupported": "${providerName} n'est plus pris en charge !", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "Merci d'essayer la connexion vers un autre nœud", "please_wait": "Merci de patienter", "polygonscan_history": "Historique de PolygonScan", + "potential_scam": "Arnaque potentielle", "powered_by": "Proposé par ${title}", "pre_seed_button_text": "J'ai compris. Montrez moi ma phrase secrète (seed)", "pre_seed_description": "Sur la page suivante vous allez voir une série de ${words} mots. Ils constituent votre phrase secrète (seed) unique et privée et sont le SEUL moyen de restaurer votre portefeuille (wallet) en cas de perte ou de dysfonctionnement. Il est de VOTRE responsabilité d'écrire cette série de mots et de la stocker dans un lieu sûr en dehors de l'application Cake Wallet.", @@ -757,8 +760,8 @@ "shared_seed_wallet_groups": "Groupes de portefeuilles partagés", "show": "Montrer", "show_address_book_popup": "Afficher la fenêtre contextuelle du carnet d'adresses", - "show_balance": "Longue presse pour montrer l'équilibre", - "show_balance_toast": "Longue appuyez sur pour masquer ou afficher l'équilibre", + "show_balance": "Appuyez longtemps pour afficher votre solde", + "show_balance_toast": "Appuyez longtemps pour masquer ou afficher votre solde", "show_details": "Afficher les détails", "show_keys": "Visualiser la phrase secrète (seed) et les clefs", "show_market_place": "Afficher la place de marché", @@ -785,7 +788,7 @@ "silent_payments_scanned_tip": "SCANNEZ POUR DONNER ! (${tip})", "silent_payments_scanning": "Scan des paiements silencieux", "silent_payments_settings": "Paramètres de paiement silencieux", - "single_seed_wallets_group": "Portefeuilles de semences simples", + "single_seed_wallets_group": "Portefeuilles de mots-clés (seed) simples", "slidable": "Glissable", "solana_create_associated_token_account_exception": "Création d'erreur Création de jetons associés pour l'adresse détenue.", "solana_no_associated_token_account_exception": "Il n'y a pas de compte de jeton associé pour cette adresse.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "SYNCHRONISATION EN COURS", "sync_status_timed_out": "FIN DU TEMPS", "sync_status_unsupported": "Nœud non pris en charge", + "synchronizing": "Synchronisation", "syncing_wallet_alert_content": "Votre solde et votre liste de transactions peuvent ne pas être à jour tant que la mention « SYNCHRONISÉ » n'apparaît en haut de l'écran. Cliquez/appuyez pour en savoir plus.", "syncing_wallet_alert_title": "Votre portefeuille (wallet) est en cours de synchronisation", "template": "Modèle", @@ -951,7 +955,7 @@ "variable_pair_not_supported": "Cette paire variable n'est pas prise en charge avec les échanges sélectionnés", "verification": "Vérification", "verify_message": "Vérifier le message", - "verify_seed": "Vérifiez les semences", + "verify_seed": "Vérifiez les mots-clés (seed)", "verify_with_2fa": "Vérifier avec Cake 2FA", "version": "Version ${currentVersion}", "view_all": "Voir tout", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 44bb769f2..7435739be 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Sayi Bitcoin", "buy_now": "Saya yanzu", "buy_provider_unavailable": "Mai ba da kyauta a halin yanzu babu.", + "buy_sell_pair_is_not_supported_warning": "Wannan mai samar da wannan kudin ba shi da goyan bayan hanyar biyan kuɗi da aka zaɓa. Da fatan za a zabi wata ƙungiya daban ko kuma gwada canza hanyar biyan kuɗi.", "buy_with": "Saya da", "by_cake_pay": "da Cake Pay", "cake_2fa_preset": "Cake 2FA saiti", @@ -131,6 +132,7 @@ "change_rep_message": "Shin kun tabbata kuna son canza wakilai?", "change_rep_successful": "An samu nasarar canzawa wakilin", "change_selected_exchanges": "Canza musayar musayar", + "change_selected_pair": "Canja wurin biyu", "change_wallet_alert_content": "Kana so ka canja walat yanzu zuwa ${wallet_name}?", "change_wallet_alert_title": "Canja walat yanzu", "choose_a_payment_method": "Zabi hanyar biyan kuɗi", @@ -539,6 +541,7 @@ "please_try_to_connect_to_another_node": "Don Allah yi ƙoƙarin haɗa da wani node", "please_wait": "Don Allah a rufe", "polygonscan_history": "PolygonScan tarihin kowane zamani", + "potential_scam": "M zamba", "powered_by": "An ƙarfafa shi ta ${title}", "pre_seed_button_text": "Ina fahimta. Nuna mini seed din nawa", "pre_seed_description": "A kan shafin nan za ku ga wata ƙungiya na ${words} kalmomi. Wannan shine tsarin daban-daban ku kuma na sirri kuma shine hanya ɗaya kadai don mai da purse dinku a cikin yanayin rasa ko rashin aiki. Yana da damar da kuke a cikin tabbatar da kuyi rubuta shi kuma kuyi ajiye shi a wuri na aminci wanda ya wuce wurin app na Cake Wallet.", @@ -827,6 +830,7 @@ "sync_status_syncronizing": "KWAFI", "sync_status_timed_out": "ATED Out", "sync_status_unsupported": "Ba a Taimako ba", + "synchronizing": "Aikiɓaɓaƙe", "syncing_wallet_alert_content": "Ma'aunin ku da lissafin ma'amala bazai cika ba har sai an ce \"SYNCHRONIZED\" a saman. Danna/matsa don ƙarin koyo.", "syncing_wallet_alert_title": "Walat ɗin ku yana aiki tare", "template": "Samfura", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 94dcfb555..c07ed9ca0 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "बिटकॉइन खरीदें", "buy_now": "अभी खरीदें", "buy_provider_unavailable": "वर्तमान में प्रदाता अनुपलब्ध है।", + "buy_sell_pair_is_not_supported_warning": "यह मुद्रा जोड़ी चयनित भुगतान विधि के लिए किसी भी प्रदाता द्वारा समर्थित नहीं है। कृपया एक अलग जोड़ी चुनें या भुगतान विधि को बदलने का प्रयास करें।", "buy_with": "के साथ खरीदें", "by_cake_pay": "केकपे द्वारा", "cake_2fa_preset": "केक 2एफए प्रीसेट", @@ -131,6 +132,7 @@ "change_rep_message": "क्या आप वाकई प्रतिनिधियों को बदलना चाहते हैं?", "change_rep_successful": "सफलतापूर्वक बदलकर प्रतिनिधि", "change_selected_exchanges": "चयनित एक्सचेंजों को बदलें", + "change_selected_pair": "चयनित जोड़ी बदलें", "change_wallet_alert_content": "क्या आप करंट वॉलेट को बदलना चाहते हैं ${wallet_name}?", "change_wallet_alert_title": "वर्तमान बटुआ बदलें", "choose_a_payment_method": "एक भुगतान विधि का चयन करें", @@ -538,6 +540,7 @@ "please_try_to_connect_to_another_node": "कृपया दूसरे नोड से कनेक्ट करने का प्रयास करें", "please_wait": "कृपया प्रतीक्षा करें", "polygonscan_history": "पॉलीगॉनस्कैन इतिहास", + "potential_scam": "संभावित घोटाला", "powered_by": "द्वारा संचालित ${title}", "pre_seed_button_text": "मै समझता हुँ। मुझे अपना बीज दिखाओ", "pre_seed_description": "अगले पेज पर आपको ${words} शब्दों की एक श्रृंखला दिखाई देगी। यह आपका अद्वितीय और निजी बीज है और नुकसान या खराबी के मामले में अपने बटुए को पुनर्प्राप्त करने का एकमात्र तरीका है। यह आपकी जिम्मेदारी है कि इसे नीचे लिखें और इसे Cake Wallet ऐप के बाहर सुरक्षित स्थान पर संग्रहीत करें।", @@ -827,6 +830,7 @@ "sync_status_syncronizing": "सिंक्रनाइज़ करने", "sync_status_timed_out": "समय समााप्त", "sync_status_unsupported": "असमर्थित नोड", + "synchronizing": "सिंक्रनाइज़ करना", "syncing_wallet_alert_content": "आपकी शेष राशि और लेनदेन सूची तब तक पूरी नहीं हो सकती जब तक कि शीर्ष पर \"सिंक्रनाइज़्ड\" न लिखा हो। अधिक जानने के लिए क्लिक/टैप करें।", "syncing_wallet_alert_title": "आपका वॉलेट सिंक हो रहा है", "template": "खाका", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 815367da9..e3616d332 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Kupite Bitcoin", "buy_now": "Kupi sada", "buy_provider_unavailable": "Davatelj trenutno nije dostupan.", + "buy_sell_pair_is_not_supported_warning": "Ovaj par valute nije podržao nijedan pružatelj odabranog načina plaćanja. Odaberite drugi par ili pokušajte promijeniti način plaćanja.", "buy_with": "Kupite s", "by_cake_pay": "od Cake Paya", "cake_2fa_preset": "Cake 2FA Preset", @@ -131,6 +132,7 @@ "change_rep_message": "Jeste li sigurni da želite promijeniti predstavnika?", "change_rep_successful": "Uspješno promijenjena reprezentativna", "change_selected_exchanges": "Promijenite odabrane razmjene", + "change_selected_pair": "Promijenite odabrani par", "change_wallet_alert_content": "Želite li promijeniti trenutni novčanik u ${wallet_name}?", "change_wallet_alert_title": "Izmijeni trenutni novčanik", "choose_a_payment_method": "Odaberite način plaćanja", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "Molimo pokušajte se spojiti na drugi node.", "please_wait": "Molimo pričekajte", "polygonscan_history": "Povijest PolygonScan", + "potential_scam": "Potencijalna prijevara", "powered_by": "Omogućio ${title}", "pre_seed_button_text": "Razumijem. Prikaži mi moj pristupni izraz", "pre_seed_description": "Na sljedećoj ćete stranici vidjeti niz ${words} riječi. Radi se o Vašem jedinstvenom i tajnom pristupnom izrazu koji je ujedno i JEDINI način na koji možete oporaviti svoj novčanik u slučaju gubitka ili kvara. VAŠA je odgovornost zapisati ga te pohraniti na sigurno mjesto izvan Cake Wallet aplikacije.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "SINKRONIZIRANJE", "sync_status_timed_out": "ISTEKLO", "sync_status_unsupported": "Nepodržani čvor", + "synchronizing": "Sinkronizirajući", "syncing_wallet_alert_content": "Vaš saldo i popis transakcija možda neće biti potpuni sve dok na vrhu ne piše \"SINKRONIZIRANO\". Kliknite/dodirnite da biste saznali više.", "syncing_wallet_alert_title": "Vaš novčanik se sinkronizira", "template": "Predložak", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index 1b5ed2dd4..28d242d73 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Գնել Bitcoin", "buy_now": "Գնել հիմա", "buy_provider_unavailable": "Տվյալ պահին մատակարարը անհասանելի է։", + "buy_sell_pair_is_not_supported_warning": "Այս արժութային զույգը չի ապահովվում որեւէ մատակարարի կողմից ընտրված վճարման եղանակի համար: Խնդրում ենք ընտրել այլ զույգ կամ փորձել փոխել վճարման եղանակը:", "buy_with": "Գնել", "by_cake_pay": "Cake Pay-ով", "cake_2fa_preset": "Cake 2FA նախապես կանխորոշված", @@ -131,6 +132,7 @@ "change_rep_message": "Վստահ եք, որ ցանկանում եք փոխել ներկայացուցիչներին?", "change_rep_successful": "Ներկայացուցչի փոփոխությունը հաջողությամբ կատարվեց", "change_selected_exchanges": "Փոխեք ընտրված փոխանակումները", + "change_selected_pair": "Փոխեք ընտրված զույգը", "change_wallet_alert_content": "Ցանկանում եք փոխել ընթացիկ դրամապանակը ${wallet_name}?", "change_wallet_alert_title": "Փոխել ընթացիկ դրամապանակը", "choose_a_payment_method": "Ընտրեք վճարման եղանակ", @@ -536,6 +538,7 @@ "please_try_to_connect_to_another_node": "Խնդրում ենք փորձել միանալ այլ հանգույցի", "please_wait": "Խնդրում ենք սպասել", "polygonscan_history": "PolygonScan պատմություն", + "potential_scam": "Հնարավոր խաբեություն", "powered_by": "${title} կողմից ապահովված", "pre_seed_button_text": "Ես հասկանում եմ։ Ցույց տվեք իմ սերմը", "pre_seed_description": "Հաջորդ էջում դուք կտեսնեք ${words} բառերի շարք։ Սա ձեր յուրահատուկ և գաղտնի սերմն է, որը ձեր դրամապանակը վերականգնելու միակ միջոցն է կորուստի կամ սխալ գործարքի դեպքում։ Դուք պատասխանատու եք այն գրառել և ապահով վայրում պահել Cake Wallet հավելվածից դուրս", @@ -823,6 +826,7 @@ "sync_status_syncronizing": "ՀԱՄԱԺԱՄԵՑՎՈՒՄ Է", "sync_status_timed_out": "Ժամանակը սպառվեց", "sync_status_unsupported": "ՉԱՋԱԿՑՎՈՂ ՀԱՆԳՈՒՅՑ,", + "synchronizing": "Համաժամանակող", "syncing_wallet_alert_content": "Ձեր հաշիվը և գործարքների ցանկը կարող են լինել անավարտ մինչև վերին մասում գրված լինի “ՀԱՂՈՒՄ”։ Սեղմեք/դիպեք ուսումնասիրելու համար։", "syncing_wallet_alert_title": "Ձեր դրամապանակը համաժամացվում է", "template": "Տարբերակ", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index f7e068293..b7a517773 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Beli Bitcoin", "buy_now": "Beli sekarang", "buy_provider_unavailable": "Penyedia saat ini tidak tersedia.", + "buy_sell_pair_is_not_supported_warning": "Pasangan mata uang ini tidak didukung oleh penyedia mana pun untuk metode pembayaran yang dipilih. Pilih pasangan yang berbeda atau coba ubah metode pembayaran.", "buy_with": "Beli dengan", "by_cake_pay": "oleh Cake Pay", "cake_2fa_preset": "Preset Kue 2FA", @@ -131,6 +132,7 @@ "change_rep_message": "Apakah Anda yakin ingin mengubah perwakilan?", "change_rep_successful": "Berhasil mengubah perwakilan", "change_selected_exchanges": "Ubah pertukaran yang dipilih", + "change_selected_pair": "Ubah pasangan yang dipilih", "change_wallet_alert_content": "Apakah Anda ingin mengganti dompet saat ini ke ${wallet_name}?", "change_wallet_alert_title": "Ganti dompet saat ini", "choose_a_payment_method": "Pilih metode pembayaran", @@ -539,6 +541,7 @@ "please_try_to_connect_to_another_node": "Silakan coba untuk terhubung ke node lain", "please_wait": "Harap tunggu", "polygonscan_history": "Sejarah PolygonScan", + "potential_scam": "Penipuan potensial", "powered_by": "Didukung oleh ${title}", "pre_seed_button_text": "Saya mengerti. Tampilkan seed saya", "pre_seed_description": "Di halaman berikutnya Anda akan melihat serangkaian kata ${words}. Ini adalah seed unik dan pribadi Anda dan itu SATU-SATUNYA cara untuk mengembalikan dompet Anda jika hilang atau rusak. Ini adalah TANGGUNG JAWAB Anda untuk menuliskannya dan menyimpan di tempat yang aman di luar aplikasi Cake Wallet.", @@ -828,6 +831,7 @@ "sync_status_syncronizing": "SEDANG SINKRONISASI", "sync_status_timed_out": "WAKTU HABIS", "sync_status_unsupported": "Node yang tidak didukung", + "synchronizing": "Sinkronisasi", "syncing_wallet_alert_content": "Saldo dan daftar transaksi Anda mungkin belum lengkap sampai tertulis “SYNCHRONIZED” di bagian atas. Klik/ketuk untuk mempelajari lebih lanjut.", "syncing_wallet_alert_title": "Dompet Anda sedang disinkronkan", "template": "Template", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 5cd7daa51..7db560738 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Acquista Bitcoin", "buy_now": "Acquista ora", "buy_provider_unavailable": "Provider attualmente non disponibile.", + "buy_sell_pair_is_not_supported_warning": "Questa coppia di valute non è supportata da nessun provider per il metodo di pagamento selezionato. Scegli una coppia diversa o prova a modificare il metodo di pagamento.", "buy_with": "Acquista con", "by_cake_pay": "da Cake Pay", "cake_2fa_preset": "Preset Cake 2FA", @@ -131,6 +132,7 @@ "change_rep_message": "Sei sicuro di voler cambiare rappresentanti?", "change_rep_successful": "Rappresentante modificato con successo", "change_selected_exchanges": "Modificare gli Exchange selezionati", + "change_selected_pair": "Modifica coppia selezionata", "change_wallet_alert_content": "Sei sicuro di voler cambiare il portafoglio attuale con ${wallet_name}?", "change_wallet_alert_title": "Cambia portafoglio attuale", "choose_a_payment_method": "Scegli un metodo di pagamento", @@ -538,6 +540,7 @@ "please_try_to_connect_to_another_node": "Gentilmente prova a connetterti ad un altro nodo", "please_wait": "Attendere prego", "polygonscan_history": "Cronologia PolygonScan", + "potential_scam": "Potenziale truffa", "powered_by": "Sviluppato da ${title}", "pre_seed_button_text": "Ho capito. Mostrami il seme", "pre_seed_description": "Nella pagina seguente ti sarà mostrata una serie di parole ${words}. Questo è il tuo seme unico e privato ed è l'UNICO modo per recuperare il tuo portafoglio in caso di perdita o malfunzionamento. E' TUA responsabilità trascriverlo e conservarlo in un posto sicuro fuori dall'app Cake Wallet.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "SINCRONIZZAZIONE", "sync_status_timed_out": "TIMED OUT", "sync_status_unsupported": "NODO NON SUPPORTATO", + "synchronizing": "Sincronizzazione", "syncing_wallet_alert_content": "Il saldo e l'elenco delle transazioni potrebbero non essere completi fin quando non viene visualizzato \"SINCRONIZZATO\" in alto. Clicca/tocca per saperne di più.", "syncing_wallet_alert_title": "Il tuo portafoglio si sta sincronizzando", "template": "Modello", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 94c2a85ec..c70526164 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "ビットコインを購入する", "buy_now": "今すぐ購入", "buy_provider_unavailable": "現在、プロバイダーは利用できません。", + "buy_sell_pair_is_not_supported_warning": "この通貨ペアは、選択した支払い方法のプロバイダーによってサポートされていません。別のペアを選択するか、支払い方法を変更してみてください。", "buy_with": "で購入", "by_cake_pay": "by Cake Pay", "cake_2fa_preset": "ケーキ 2FA プリセット", @@ -131,6 +132,7 @@ "change_rep_message": "代表者を変更してもよろしいですか?", "change_rep_successful": "代表者の変更に成功しました", "change_selected_exchanges": "選択した交換を変更します", + "change_selected_pair": "選択したペアを変更します", "change_wallet_alert_content": "現在のウォレットをに変更しますか ${wallet_name}?", "change_wallet_alert_title": "現在のウォレットを変更する", "choose_a_payment_method": "支払い方法を選択します", @@ -538,6 +540,7 @@ "please_try_to_connect_to_another_node": "別のノードに接続してみてください", "please_wait": "お待ちください", "polygonscan_history": "ポリゴンスキャン履歴", + "potential_scam": "潜在的な詐欺", "powered_by": "搭載 ${title}", "pre_seed_button_text": "わかります。 種を見せて", "pre_seed_description": "次のページでは、一連の${words}語が表示されます。 これはあなたのユニークでプライベートなシードであり、紛失や誤動作が発生した場合にウォレットを回復する唯一の方法です。 それを書き留めて、Cake Wallet アプリの外の安全な場所に保管するのはあなたの責任です。", @@ -826,6 +829,7 @@ "sync_status_syncronizing": "同期", "sync_status_timed_out": "タイムアウトしました", "sync_status_unsupported": "サポートされていないノード", + "synchronizing": "同期", "syncing_wallet_alert_content": "上部に「同期済み」と表示されるまで、残高と取引リストが完了していない可能性があります。詳細については、クリック/タップしてください。", "syncing_wallet_alert_title": "ウォレットは同期中です", "template": "テンプレート", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 6a09f8439..909ac9921 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "비트 코인 구매", "buy_now": "지금 구매하십시오", "buy_provider_unavailable": "제공자는 현재 사용할 수 없습니다.", + "buy_sell_pair_is_not_supported_warning": "이 통화 쌍은 선택한 결제 방법을 제공하는 모든 공급자가 지원하지 않습니다. 다른 쌍을 선택하거나 결제 방법을 변경하십시오.", "buy_with": "구매", "by_cake_pay": "Cake Pay로", "cake_2fa_preset": "케이크 2FA 프리셋", @@ -131,6 +132,7 @@ "change_rep_message": "대표를 바꾸고 싶습니까?", "change_rep_successful": "대리인이 성공적으로 변경되었습니다", "change_selected_exchanges": "선택된 거래소 변경", + "change_selected_pair": "선택한 쌍을 변경하십시오", "change_wallet_alert_content": "현재 지갑을 다음으로 변경 하시겠습니까 ${wallet_name}?", "change_wallet_alert_title": "현재 지갑 변경", "choose_a_payment_method": "결제 방법을 선택하십시오", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "다른 노드에 연결을 시도하십시오", "please_wait": "기다리세요", "polygonscan_history": "다각형 스캔 기록", + "potential_scam": "잠재적 사기", "powered_by": "에 의해 구동 ${title}", "pre_seed_button_text": "이해 했어요. 내 씨앗을 보여줘", "pre_seed_description": "다음 페이지에서 ${words} 개의 단어를 볼 수 있습니다. 이것은 귀하의 고유하고 개인적인 시드이며 분실 또는 오작동시 지갑을 복구하는 유일한 방법입니다. 기록해두고 Cake Wallet 앱 외부의 안전한 장소에 보관하는 것은 귀하의 책임입니다.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "동기화", "sync_status_timed_out": "시간 초과", "sync_status_unsupported": "지원되지 않은 노드", + "synchronizing": "동기화", "syncing_wallet_alert_content": "상단에 \"동기화됨\"이라고 표시될 때까지 잔액 및 거래 목록이 완전하지 않을 수 있습니다. 자세히 알아보려면 클릭/탭하세요.", "syncing_wallet_alert_title": "지갑 동기화 중", "template": "주형", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index ff461284c..1396d77b7 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Bitcoin ကိုဝယ်ပါ။", "buy_now": "အခုဝယ်ပါ", "buy_provider_unavailable": "လက်ရှိတွင်လက်ရှိမရနိုင်ပါ။", + "buy_sell_pair_is_not_supported_warning": "ဤငွေကြေးအတွဲကိုရွေးချယ်ထားသောငွေပေးချေမှုနည်းလမ်းအတွက်မည်သည့်ပံ့ပိုးသူမှမထောက်ပံ့ပါ။ ကျေးဇူးပြု. မတူညီသောစုံတွဲကိုရွေးချယ်ပါသို့မဟုတ်ငွေပေးချေမှုနည်းလမ်းကိုပြောင်းလဲရန်ကြိုးစားပါ။", "buy_with": "အတူဝယ်ပါ။", "by_cake_pay": "Cake Pay ဖြင့်", "cake_2fa_preset": "ကိတ်မုန့် 2FA ကြိုတင်သတ်မှတ်", @@ -131,6 +132,7 @@ "change_rep_message": "ကိုယ်စားလှယ်ပြောင်းလိုသည်မှာ သေချာပါသလား။", "change_rep_successful": "အောင်မြင်စွာကိုယ်စားလှယ်ပြောင်းလဲသွားတယ်", "change_selected_exchanges": "ရွေးချယ်ထားသောအပြန်အလှန်ဖလှယ်မှုကိုပြောင်းလဲပါ", + "change_selected_pair": "ရွေးချယ်ထားသည့်စုံတွဲကိုပြောင်းပါ", "change_wallet_alert_content": "လက်ရှိပိုက်ဆံအိတ်ကို ${wallet_name} သို့ ပြောင်းလိုပါသလား။", "change_wallet_alert_title": "လက်ရှိပိုက်ဆံအိတ်ကို ပြောင်းပါ။", "choose_a_payment_method": "ငွေပေးချေမှုနည်းလမ်းကိုရွေးချယ်ပါ", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "အခြား node သို့ ချိတ်ဆက်ရန် ကြိုးစားပါ။", "please_wait": "ကျေးဇူးပြုပြီးခဏစောင့်ပါ", "polygonscan_history": "PolygonScan မှတ်တမ်း", + "potential_scam": "အလားအလာရှိသောလိမ်လည်မှု", "powered_by": "${title} မှ ပံ့ပိုးပေးသည်", "pre_seed_button_text": "ကျွန်တော်နားလည်ပါတယ်။ ငါ့အမျိုးအနွယ်ကို ပြလော့", "pre_seed_description": "နောက်စာမျက်နှာတွင် ${words} စကားလုံးများ အတွဲလိုက်ကို တွေ့ရပါမည်။ ၎င်းသည် သင်၏ထူးခြားပြီး သီးသန့်မျိုးစေ့ဖြစ်ပြီး ပျောက်ဆုံးခြင်း သို့မဟုတ် ချွတ်ယွင်းမှုရှိပါက သင့်ပိုက်ဆံအိတ်ကို ပြန်လည်ရယူရန် တစ်ခုတည်းသောနည်းလမ်းဖြစ်သည်။ ၎င်းကို Cake Wallet အက်ပ်၏အပြင်ဘက်တွင် လုံခြုံသောနေရာတွင် သိမ်းဆည်းရန်မှာ သင်၏တာဝန်ဖြစ်သည်။", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "ထပ်တူပြုခြင်း။", "sync_status_timed_out": "ထွက်အချိန်ကုန်", "sync_status_unsupported": "node မထောက်ပံ့ node ကို", + "synchronizing": "ထပ်တူပြုခြင်း", "syncing_wallet_alert_content": "သင်၏လက်ကျန်နှင့် ငွေပေးငွေယူစာရင်းသည် ထိပ်တွင် \"Synchronizeed\" ဟုပြောသည်အထိ မပြီးမြောက်နိုင်ပါ။ ပိုမိုလေ့လာရန် နှိပ်/နှိပ်ပါ။", "syncing_wallet_alert_title": "သင့်ပိုက်ဆံအိတ်ကို စင့်ခ်လုပ်နေပါသည်။", "template": "ပုံစံခွက်", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index d8bb9f3fa..c4a189ea2 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Koop Bitcoin", "buy_now": "Koop nu", "buy_provider_unavailable": "Provider momenteel niet beschikbaar.", + "buy_sell_pair_is_not_supported_warning": "Dit valutapaar wordt door een provider niet ondersteund voor de geselecteerde betaalmethode. Kies een ander paar of probeer de betaalmethode te wijzigen.", "buy_with": "Koop met", "by_cake_pay": "door Cake Pay", "cake_2fa_preset": "Taart 2FA Voorinstelling", @@ -131,6 +132,7 @@ "change_rep_message": "Weet u zeker dat u van vertegenwoordiger wilt veranderen?", "change_rep_successful": "Met succes veranderde vertegenwoordiger", "change_selected_exchanges": "Wijzig geselecteerde uitwisselingen", + "change_selected_pair": "Wijzig geselecteerd paar", "change_wallet_alert_content": "Wilt u de huidige portemonnee wijzigen in ${wallet_name}?", "change_wallet_alert_title": "Wijzig huidige portemonnee", "choose_a_payment_method": "Kies een betaalmethode", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "Probeer verbinding te maken met een ander knooppunt", "please_wait": "Even geduld aub", "polygonscan_history": "PolygonScan-geschiedenis", + "potential_scam": "Potentiële zwendel", "powered_by": "Aangedreven door ${title}", "pre_seed_button_text": "Ik begrijp het. Laat me mijn zaad zien", "pre_seed_description": "Op de volgende pagina ziet u een reeks van ${words} woorden. Dit is uw unieke en persoonlijke zaadje en het is de ENIGE manier om uw portemonnee te herstellen in geval van verlies of storing. Het is JOUW verantwoordelijkheid om het op te schrijven en op een veilige plaats op te slaan buiten de Cake Wallet app.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "SYNCHRONISEREN", "sync_status_timed_out": "Uitgeput", "sync_status_unsupported": "Niet ondersteund knooppunt", + "synchronizing": "Synchronisatie", "syncing_wallet_alert_content": "Uw saldo- en transactielijst is mogelijk pas compleet als er bovenaan 'GESYNCHRONISEERD' staat. Klik/tik voor meer informatie.", "syncing_wallet_alert_title": "Uw portemonnee wordt gesynchroniseerd", "template": "Sjabloon", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index a79c28a93..adfc1d4cf 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -1,5 +1,5 @@ { - "about_cake_pay": "Cake Pay umożliwia łatwe kupowanie kart podarunkowych z wirtualnymi aktywami, które można natychmiast wydać u ponad 150 000 sprzedawców w Stanach Zjednoczonych.", + "about_cake_pay": "Cake Pay umożliwia łatwe kupowanie kart podarunkowych z wirtualnymi saldami, które można natychmiast wydać u ponad 150 000 sprzedawców.", "account": "Konto", "accounts": "Konta", "accounts_subaddresses": "Konta i podadresy", @@ -32,7 +32,7 @@ "address_remove_content": "Czy na pewno chcesz usunąć wybrany kontakt?", "addresses": "Adresy", "advanced_settings": "Zaawansowane ustawienia", - "aggressive": "Nadgorliwy", + "aggressive": "Agresywny", "agree": "Zgadzam się", "agree_and_continue": "Zgadzam się i kontynuuj", "agree_to": "Tworząc konto wyrażasz zgodę na ", @@ -56,12 +56,12 @@ "ascending": "Wznoszący się", "ask_each_time": "Zapytaj za każdym razem", "auth_store_ban_timeout": "przekroczenie limitu czasu", - "auth_store_banned_for": "Zablokowany za ", + "auth_store_banned_for": "Zablokowany na ", "auth_store_banned_minutes": " minuty", "auth_store_incorrect_password": "Niepoprawny PIN", "authenticated": "Uwierzytelniony", "authentication": "Uwierzytelnianie", - "auto_generate_addresses": "Auto generują adresy", + "auto_generate_addresses": "Automatycznie generuj adresy", "auto_generate_subaddresses": "Automatycznie generuj podadresy", "automatic": "Automatyczny", "available_balance": "Dostępne środki", @@ -69,34 +69,35 @@ "avg_savings": "Śr. oszczędności", "awaitDAppProcessing": "Poczekaj, aż dApp zakończy przetwarzanie.", "awaiting_payment_confirmation": "Oczekiwanie na potwierdzenie płatności", - "background_sync": "Synchronizacja tła", + "background_sync": "Synchronizacja w tle", "background_sync_mode": "Tryb synchronizacji w tle", "backup": "Kopia zapasowa", "backup_file": "Plik kopii zapasowej", "backup_password": "Hasło kpoii zapasowej", - "balance": "Balansować", + "balance": "Saldo", "balance_page": "Strona salda", "bill_amount": "Kwota rachunku", "billing_address_info": "Jeśli zostaniesz poproszony o podanie adresu rozliczeniowego, podaj swój adres wysyłki", "biometric_auth_reason": "Zeskanuj swój odcisk palca, aby uwierzytelnić", "bitcoin_dark_theme": "Ciemny motyw Bitcoina", - "bitcoin_light_theme": "Lekki motyw Bitcoin", + "bitcoin_light_theme": "Jasny motyw Bitcoin", "bitcoin_payments_require_1_confirmation": "Płatności Bitcoin wymagają 1 potwierdzenia, co może zająć 20 minut lub dłużej. Dziękuję za cierpliwość! Otrzymasz wiadomość e-mail, gdy płatność zostanie potwierdzona.", "block_height": "Wysokość bloku", - "block_remaining": "1 blok pozostałym", + "block_remaining": "pozostał 1 blok", "Blocks_remaining": "Pozostało ${status} bloków", "bluetooth": "Bluetooth", - "bright_theme": "Biały", - "bump_fee": "Opłata za nierówność", + "bright_theme": "Jasny", + "bump_fee": "Opłata za transakcje", "buy": "Kup", "buy_alert_content": "Obecnie obsługujemy tylko zakup Bitcoin, Ethereum, Litecoin i Monero. Utwórz lub przełącz się na swój portfel Bitcoin, Ethereum, Litecoin lub Monero.", "buy_bitcoin": "Kup Bitcoin", "buy_now": "Kup Teraz", "buy_provider_unavailable": "Dostawca obecnie niedostępny.", + "buy_sell_pair_is_not_supported_warning": "Ta para walut nie jest obsługiwana przez żadnego dostawcy dla wybranej metody płatności. Wybierz inną parę lub spróbuj zmienić metodę płatności.", "buy_with": "Kup za pomocą", "by_cake_pay": "przez Cake Pay", - "cake_2fa_preset": "Ciasto 2FA Preset", - "cake_dark_theme": "Cake Dark Temat", + "cake_2fa_preset": "Cake 2FA Preset", + "cake_dark_theme": "Cake Dark", "cake_pay_account_note": "Zarejestruj się, używając tylko adresu e-mail, aby przeglądać i kupować karty. Niektóre są nawet dostępne ze zniżką!", "cake_pay_learn_more": "Kupuj i wykorzystuj karty podarunkowe od razu w aplikacji!\nPrzesuń od lewej do prawej, aby dowiedzieć się więcej.", "cake_pay_save_order": "Karta powinna zostać wysłana na adres e-mail w ciągu 1 dnia roboczego \n Zapisz identyfikator zamówienia:", @@ -108,8 +109,8 @@ "cakepay_confirm_no_vpn": "Potwierdzam, że nie używam proxy ani VPN", "cakepay_confirm_purchase": "Potwierdź zakup", "cakepay_confirm_terms_agreed": "Zgadzam się na przedstawione tutaj warunki:", - "cakepay_confirm_voided_refund": "Rozumiem, że próby odkupienia z ograniczonego kraju nie unieważają wszelkich", - "cakepay_ios_not_available": "Przepraszam, ta karta podarunkowa nie jest dostępna na iOS. Zamiast tego możesz go kupić na Android lub za pośrednictwem naszej strony internetowej.", + "cakepay_confirm_voided_refund": "Rozumiem, że próby zwrotu z kraju niedozwolnego nie zostaną uznane", + "cakepay_ios_not_available": "Przepraszamy, ta karta podarunkowa nie jest dostępna na iOS. Możesz ją kupić na Androidzie lub za pośrednictwem naszej strony internetowej.", "cakepay_prepaid_card": "Przedpłacona karta debetowa CakePay", "camera_consent": "Twój aparat zostanie użyty do przechwycenia obrazu w celach identyfikacyjnych przez ${provider}. Aby uzyskać szczegółowe informacje, sprawdź ich Politykę prywatności.", "camera_permission_is_required": "Wymagane jest pozwolenie na korzystanie z aparatu.\nWłącz tę funkcję w ustawieniach aplikacji.", @@ -117,20 +118,21 @@ "card_address": "Adres:", "cardholder_agreement": "Umowa posiadacza karty", "cards": "Karty", - "chains": "Więzy", + "chains": "Łańcuchy", "change": "Zmień", "change_backup_password_alert": "Twoje poprzednie pliki kopii zapasowej nie będą dostępne do zaimportowania z nowym hasłem kopii zapasowej. Nowe hasło kopii zapasowej będzie używane tylko dla nowych plików kopii zapasowych. Czy na pewno chcesz zmienić hasło zapasowe?", "change_currency": "Zmień walutę", "change_current_node": "Czy na pewno chcesz wybrać ten węzeł? ${node}?", "change_current_node_title": "Zmień bieżący węzeł", - "change_exchange_provider": "Zmień dostawca zamiany", + "change_exchange_provider": "Zmień dostawce wymiany", "change_language": "Zmień język", "change_language_to": "Zmień język na ${language}?", "change_password": "Zmień hasło", "change_rep": "Zmień przedstawiciela", "change_rep_message": "Czy na pewno chcesz zmienić przedstawiciela?", - "change_rep_successful": "Pomyślnie zmienił przedstawiciela", + "change_rep_successful": "Pomyślnie zmieniono przedstawiciela", "change_selected_exchanges": "Zmień wybrane wymiany", + "change_selected_pair": "Zmień wybraną parę", "change_wallet_alert_content": "Czy chcesz zmienić obecny portfel na ${wallet_name}?", "change_wallet_alert_title": "Zmień obecny portfel", "choose_a_payment_method": "Wybierz metodę płatności", @@ -138,30 +140,30 @@ "choose_account": "Wybierz konto", "choose_address": "\n\nWybierz adres:", "choose_card_value": "Wybierz wartość karty", - "choose_derivation": "Wybierz wyprowadzenie portfela", + "choose_derivation": "Wybierz wyprowadzenie frazy", "choose_from_available_options": "Wybierz z dostępnych opcji:", "choose_one": "Wybierz jeden", - "choose_relay": "Wybierz przekaźnik, którego chcesz użyć", + "choose_relay": "Wybierz przekaźnik, który chcesz użyć", "choose_wallet_currency": "Wybierz walutę portfela:", "choose_wallet_group": "Wybierz grupę portfela", "clear": "Wyczyść", "clearnet_link": "łącze Clearnet", - "close": "Zamknąć", - "coin_control": "Kontrola monet (opcjonalnie)", - "cold_or_recover_wallet": "Dodaj portfel tylko do odczytu od Cupcake lub zimnego portfela lub odzyskaj papierowy portfel", + "close": "Zamknij", + "coin_control": "Kontrola monet (opcjonalne)", + "cold_or_recover_wallet": "Dodaj portfel tylko do odczytu od Cupcake, innego zimnego portfela lub odzyskaj papierowy portfel", "collection_address": "Adres kolekcji", "collection_description": "Opis kolekcji", "collection_name": "Nazwa kolekcji", "color_theme": "Motyw kolorystyczny", "commit_transaction_amount_fee": "Zatwierdź transakcję\nIlość: ${amount}\nOpłata: ${fee}", - "confirm": "Potwierdzać", + "confirm": "Potwierdź", "confirm_delete_template": "Ta czynność usunie ten szablon. Czy chcesz kontynuować?", "confirm_delete_wallet": "Ta czynność usunie ten portfel. Czy chcesz kontynuować?", "confirm_fee_deduction": "Potwierdź odliczenie opłaty", - "confirm_fee_deduction_content": "Czy zgadzasz się odliczyć opłatę od wyników?", + "confirm_fee_deduction_content": "Czy zgadzasz się odliczyć opłatę z wysyłanej kwoty?", "confirm_passphrase": "Potwierdź hasło", - "confirm_sending": "Potwierdź wysłanie", - "confirm_silent_payments_switch_node": "Twój obecny węzeł nie obsługuje cichych płatności \\ NCAKE Portfel przełączy się na kompatybilny węzeł, tylko do skanowania", + "confirm_sending": "Potwierdź transakcje wychodzącą", + "confirm_silent_payments_switch_node": "Twój obecny węzeł nie obsługuje cichych płatności \\ Cake Wallet przełączy się na kompatybilny węzeł, tylko do skanowania", "confirm_transaction": "Potwierdź transakcję", "confirmations": "Potwierdzenia", "confirmed": "Potwierdzone saldo", @@ -189,7 +191,7 @@ "copy_address": "Skopiuj adress", "copy_id": "skopiuj ID", "copyWalletConnectLink": "Skopiuj link do WalletConnect z dApp i wklej tutaj", - "corrupted_seed_notice": "Pliki dla tego portfela są uszkodzone i nie można ich otworzyć. Zobacz wyrażenie nasion, zapisz je i przywróć portfel.\n\nJeśli wartość jest pusta, ziarno nie można było poprawnie odzyskać.", + "corrupted_seed_notice": "Pliki dla tego portfela są uszkodzone i nie można ich otworzyć. Zobacz frazę seed, zapisz je i przywróć portfel.\n\nJeśli wartość jest pusta, frazy seed nie można było poprawnie odzyskać.", "countries": "Kraje", "create_account": "Utwórz konto", "create_backup": "Utwórz kopię zapasową", @@ -205,36 +207,36 @@ "custom_drag": "Niestandardowe (trzymaj i przeciągnij)", "custom_redeem_amount": "Niestandardowa kwota wykorzystania", "custom_value": "Wartość niestandardowa", - "dark_theme": "Ciemny", + "dark_theme": "Ciemny motyw", "debit_card": "Karta debetowa", - "debit_card_terms": "Przechowywanie i używanie numeru karty płatniczej (oraz danych uwierzytelniających odpowiadających numerowi karty płatniczej) w tym portfelu cyfrowym podlega Warunkom odpowiedniej umowy posiadacza karty z wydawcą karty płatniczej, zgodnie z obowiązującym od od czasu do czasu.", + "debit_card_terms": "Przechowywanie i używanie numeru karty płatniczej (oraz danych uwierzytelniających odpowiadających numerowi karty płatniczej) w tym portfelu cyfrowym podlega Warunkom odpowiedniej umowy posiadacza karty z wydawcą karty płatniczej, zgodnie z obowiązującym od time do time.", "decimal_places_error": "Za dużo miejsc dziesiętnych", - "decimals_cannot_be_zero": "Token dziesiętny nie może być zerowy.", - "decred_info_card_details": "Decred używa zdecentralizowanej i zachowującej prywatność metodę synchronizacji znanej jako „SPV”, która trwa dłużej niż normalny portfel bitcoin. Aby dowiedzieć się więcej, dotknij poniżej.", - "decred_info_title": "Synchronizacja w dekred", + "decimals_cannot_be_zero": "Liczba dziesiętna nie może być zerowa.", + "decred_info_card_details": "Decred używa zdecentralizowanej i zachowującej prywatność metody synchronizacji znanej jako „SPV”, która trwa dłużej niż synchronizacja portfela bitcoin. Aby dowiedzieć się więcej, kliknij poniżej.", + "decred_info_title": "Synchronizacja w decred", "default_buy_provider": "Domyślny dostawca zakupu", "default_sell_provider": "Domyślny dostawca sprzedaży", - "delete": "Skasuj", + "delete": "Usuń", "delete_account": "Usuń konto", "delete_wallet": "Usuń portfel", "delete_wallet_confirm_message": "Czy na pewno chcesz usunąć portfel ${wallet_name}?", "deleteConnectionConfirmationPrompt": "Czy na pewno chcesz usunąć połączenie z", "denominations": "Wyznaczenia", "derivationpath": "Ścieżka pochodna", - "descending": "Schodzenie", + "descending": "Malejąco", "description": "Opis", "destination_tag": "Tag docelowy:", - "dfx_option_description": "Kup krypto z EUR & CHF. Dla klientów detalicznych i korporacyjnych w Europie", + "dfx_option_description": "Kup krypto za EUR & CHF. Dla klientów prywatnych i korporacyjnych w Europie", "didnt_get_code": "Nie dostałeś kodu?", "digit_pin": "-znakowy PIN", "digital_and_physical_card": " cyfrowa i fizyczna przedpłacona karta debetowa", - "disable": "Wyłączyć", - "disable_bulletin": "Wyłącz biuletyn statusu usługi", + "disable": "Wyłącz", + "disable_bulletin": "Wyłącz biuletyn", "disable_buy": "Wyłącz akcję kupna", "disable_cake_2fa": "Wyłącz Cake 2FA", "disable_exchange": "Wyłącz wymianę", "disable_exchange_option": "Wyłącz opcję wymiany", - "disable_fee_api_warning": "Wyłączając to, stawki opłaty mogą być w niektórych przypadkach niedokładne, więc możesz skończyć się przepłaceniem lub wynagrodzeniem opłat za transakcje", + "disable_fee_api_warning": "Wyłączając tą opcję, stawki opłaty mogą być w niektórych przypadkach niedokładne, więc możesz przepłacić opłatę za transakcje", "disable_fiat": "Wyłącz waluty FIAT", "disable_sell": "Wyłącz akcję sprzedaży", "disable_trade_option": "Wyłącz opcję handlu", @@ -246,7 +248,7 @@ "displayable": "Wyświetlane", "do_not_have_enough_gas_asset": "Nie masz wystarczającej ilości ${currency}, aby dokonać transakcji przy bieżących warunkach sieci blockchain. Potrzebujesz więcej ${currency}, aby uiścić opłaty za sieć blockchain, nawet jeśli wysyłasz inny zasób.", "do_not_send": "Nie wysyłaj", - "do_not_share_warning_text": "NIE udostępniaj ich nikomu innemu, w tym pomocy technicznej.\n\nTwoje środki wtedy prawdopodobnie zostaną skradzione!", + "do_not_share_warning_text": "NIE udostępniaj ich nikomu innemu, w tym pomocy technicznej.\n\nJeśli to zrobisz twoje środki prawdopodobnie zostaną skradzione!", "do_not_show_me": "Nie pokazuj mi tego ponownie", "domain_looks_up": "Wyszukiwanie domen", "donation_link_details": "Szczegóły linku darowizny", @@ -257,10 +259,10 @@ "edit_token": "Edytuj token", "electrum_address_disclaimer": "Za każdym razem, gdy wykorzystasz adres, dla wiekszej prywatności generujemy nowy, ale poprzednie adresy nadal działają, i moga odbierać środki", "email_address": "Adres e-mail", - "enable": "Włączać", + "enable": "Włącz", "enable_mempool_api": "Mempool API dla dokładnych opłat i dat", "enable_replace_by_fee": "Włącz wymianę po lewej", - "enable_silent_payments_scanning": "Zacznij skanować ciche płatności, aż do osiągnięcia wskazówki", + "enable_silent_payments_scanning": "Zacznij skanować Silent Payments", "enabled": "Włączone", "enter_amount": "Wprowadź kwotę", "enter_backup_password": "Wprowadź tutaj hasło kopii zapasowej", @@ -274,27 +276,27 @@ "enterTokenID": "Wprowadź identyfikator tokena", "enterWalletConnectURI": "Wprowadź identyfikator URI WalletConnect", "error": "Błąd", - "error_dialog_content": "Ups, mamy trochę błędu.\n\nProszę o przesłanie raportu o błędach do naszego zespołu wsparcia, aby aplikacja była lepsza.", + "error_dialog_content": "Ups, mamy błąd.\n\nProszę o przesłanie raportu o błędach do naszego zespołu wsparcia, aby nasz zespół mógł go poprawić.", "error_text_account_name": "Nazwa konta może zawierać tylko litery, cyfry\ni musi mieć od 1 do 15 znaków", "error_text_address": "Adres musi odpowiadać typowi kryptowaluty", "error_text_amount": "Kwota może zawierać tylko liczby", "error_text_contact_name": "Nazwa kontaktu nie może zawierać symboli ` , ' \"\ni musi mieć od 1 do 32 znaków ", - "error_text_crypto_currency": "Liczba cyfr ułamkowych\nmusi być mniejsza lub równa 12", - "error_text_fiat": "Wartość kwoty nie może przekroczyć dostępnego salda.\nLiczba cyfr ułamkowych musi być mniejsza lub równa 2", + "error_text_crypto_currency": "Liczba cyfr dziesiętnych\nmusi być mniejsza lub równa 12", + "error_text_fiat": "Wartość kwoty nie może przekroczyć dostępnego salda.\nLiczba cyfr dziesiętnych musi być mniejsza lub równa 2", "error_text_input_above_maximum_limit": "Kwota jest większa niż maksymalna", "error_text_input_below_minimum_limit": "Kwota jest mniejsza niż minimalna", "error_text_keys": "Klucze portfela mogą zawierać tylko 64 znaki w systemie szesnastkowym", "error_text_limits_loading_failed": "Wymiana dla ${provider} nie została utworzona. Ładowanie limitów nie powiodło się", "error_text_maximum_limit": "Wymiana dla ${provider} nie została utworzona. Kwota jest większa niż maksymalna: ${max} ${currency}", "error_text_minimal_limit": "Wymiana dla ${provider} nie została utworzona. Kwota jest mniejsza niż minimalna: ${min} ${currency}", - "error_text_node_address": "Wpisz adres iPv4", + "error_text_node_address": "Wpisz adres IPv4", "error_text_node_port": "Port węzła może zawierać tylko liczby od 0 do 65535", "error_text_node_proxy_address": "Wprowadź :, na przykład 127.0.0.1:9050", "error_text_payment_id": "ID może zawierać od 16 do 64 znaków w formacie szesnastkowym", "error_text_subaddress_name": "Nazwa podadresu nie może zawierać symboli ` , ' \"\ni musi mieć od 1 do 20 znaków", "error_text_template": "Nazwa i adres szablonu nie mogą zawierać ` , ' \" symbolika\ni musi mieć od 1 do 106 znaków", "error_text_wallet_name": "Nazwa portfela może zawierać tylko litery, cyfry lub symbole _ - \ni musi mieć od 1 do 33 znaków", - "error_text_xmr": "Wartość XMR nie może przekraczać dostępnego salda.\nLiczba cyfr ułamkowych musi być mniejsza lub równa 12", + "error_text_xmr": "Wartość XMR nie może przekraczać dostępnego salda.\nLiczba cyfr dziesiętnych musi być mniejsza lub równa 12", "errorGettingCredentials": "Niepowodzenie: Błąd podczas uzyskiwania poświadczeń", "errorSigningTransaction": "Wystąpił błąd podczas podpisywania transakcji", "estimated": "Oszacowano", @@ -304,7 +306,7 @@ "event": "Wydarzenie", "events": "Wydarzenia", "exchange": "Giełda", - "exchange_incorrect_current_wallet_for_xmr": "Jeśli chcesz zamienić XMR z salda Monero Portfer, najpierw przejdź na portfel Monero.", + "exchange_incorrect_current_wallet_for_xmr": "Jeśli chcesz zamienić XMR z salda Monero, najpierw przejdź na portfel Monero.", "exchange_new_template": "Nowy szablon wymiany", "exchange_provider_unsupported": "${providerName} nie jest już obsługiwany!", "exchange_result_confirm": "Naciskając Potwierdź, wyślesz ${fetchingLabel} ${from} z twojego portfela ${walletName} na adres podany poniżej. Lub możesz wysłać z zewnętrznego portfela na poniższy adres / kod QR.\n\nNaciśnij Potwierdź, aby kontynuować lub wróć, aby zmienić kwoty.", @@ -312,14 +314,14 @@ "exchange_result_write_down_ID": "*Skopiuj lub zanotuj identyfikator transakcji pokazany powyżej.", "exchange_result_write_down_trade_id": "Skopiuj lub zanotuj identyfikator transakcji (ID), aby kontynuować.", "exchange_sync_alert_content": "Poczekaj, aż portfel zostanie zsynchronizowany", - "exchange_trade_result_confirm": "Naciskając wyślij z portfela ciasta, wyślesz ${fetchingLabel} ${from} z portfela o nazwie ${walletName} na adres pokazany poniżej. Lub możesz wysłać z portfela zewnętrznego na adres / qr kod na stronie Wyślij ze strony szczegółów portfela zewnętrznego. \n\n naciśnij którykolwiek z przycisków, aby kontynuować lub wróć, aby zmienić kwoty.", + "exchange_trade_result_confirm": "Naciskając wyślij z Cake Wallet, wyślesz ${fetchingLabel} ${from} z portfela o nazwie ${walletName} na adres pokazany poniżej. Lub możesz wysłać z portfela zewnętrznego na adres / qr kod na stronie Wyślij ze strony szczegółów portfela zewnętrznego. \n\n naciśnij którykolwiek z przycisków, aby kontynuować lub wróć, aby zmienić kwoty.", "expired": "Przedawniony", "expires": "Wygasa", - "expiresOn": "Upływa w dniu", + "expiresOn": "Wygasa w dniu", "expiry_and_validity": "Wygaśnięcie i ważność", "export_backup": "Eksportuj kopię zapasową", - "export_logs": "Dzienniki eksportu", - "export_outputs": "Wyjścia eksportowe", + "export_logs": "Eksportuj dzienniki", + "export_outputs": "Eksportuj wyjscia", "extra_id": "Dodatkowy ID:", "extracted_address_content": "Wysyłasz środki na\n${recipient_name}", "failed_authentication": "Nieudane uwierzytelnienie. ${state_error}", @@ -373,47 +375,47 @@ "how_to_use_card": "Jak korzystać z tej karty?", "id": "ID: ", "if_you_dont_see_your_device": "Jeśli nie widzisz swojego urządzenia powyżej, upewnij się, że Twoja księga nie śpi i odblokowana!", - "ignor": "Ignorować", + "ignor": "Ignoruj", "import": "Import", "importNFTs": "Importuj NFT", "in_store": "W Sklepie", "incoming": "Przychodzące", "incorrect_seed": "Wprowadzony seed jest nieprawidłowy.", - "incorrect_seed_option": "Błędny. Spróbuj ponownie", - "incorrect_seed_option_back": "Błędny. Upewnij się, że twoje ziarno jest prawidłowo zapisane i spróbuj ponownie.", + "incorrect_seed_option": "Błędna fraza seed. Spróbuj ponownie", + "incorrect_seed_option_back": "Błędna fraza seed. Upewnij się, że wraza, którą wprowadzasz jest prawidłowo zapisana i spróbuj ponownie.", "inputs": "Wejścia", "insufficient_funds_for_tx": "Niewystarczające fundusze na skuteczne wykonanie transakcji.", - "insufficient_lamport_for_tx": "Nie masz wystarczającej ilości SOL, aby pokryć transakcję i opłatę za transakcję. Uprzejmie dodaj więcej sol do portfela lub zmniejsz wysyłaną kwotę SOL.", - "insufficient_lamports": "Nie masz wystarczającej ilości SOL, aby pokryć transakcję i opłatę za transakcję. Potrzebujesz przynajmniej ${solValueNeeded} sol. Uprzejmie dodaj więcej sol do portfela lub zmniejsz wysyłaną kwotę SOL, którą wysyłasz", - "insufficientFundsForRentError": "Nie masz wystarczającej ilości SOL, aby pokryć opłatę za transakcję i czynsz za konto. Uprzejmie dodaj więcej sol do portfela lub zmniejsz solę, którą wysyłasz", + "insufficient_lamport_for_tx": "Nie masz wystarczającej ilości SOL, aby pokryć transakcję i opłatę za transakcję. Dodaj więcej SOL do portfela lub zmniejsz wysyłaną kwotę SOL.", + "insufficient_lamports": "Nie masz wystarczającej ilości SOL, aby pokryć transakcję i opłatę za transakcję. Potrzebujesz przynajmniej ${solValueNeeded} SOL. Uprzejmie dodaj więcej SOL do portfela lub zmniejsz wysyłaną kwotę SOL, którą wysyłasz", + "insufficientFundsForRentError": "Nie masz wystarczającej ilości SOL, aby pokryć opłatę za transakcję i czynsz za konto. Dodaj więcej SOL do portfela lub zmniejsz kwotę, którą wysyłasz", "introducing_cake_pay": "Przedstawiamy Cake Pay!", "invalid_input": "Nieprawidłowe dane wejściowe", "invalid_password": "Nieprawidłowe hasło", "invoice_details": "Dane do faktury", "is_percentage": "jest", - "keys": "Klawiatura", + "keys": "Klucze", "last_30_days": "Ostatnie 30 dni", "learn_more": "Dowiedz się więcej", - "ledger_connection_error": "Nie udało się połączyć z twoją księgą. Proszę spróbuj ponownie.", - "ledger_error_device_locked": "Księga jest zamknięta", + "ledger_connection_error": "Nie udało się połączyć z twoim portfelem. Proszę spróbuj ponownie.", + "ledger_error_device_locked": "Portfel jest zablokowany", "ledger_error_tx_rejected_by_user": "Transakcja odrzucona na urządzeniu", - "ledger_error_wrong_app": "Upewnij się, że opisz odpowiednią aplikację na swojej księdze", - "ledger_please_enable_bluetooth": "Włącz Bluetooth wykrywanie księgi", - "legacy": "Dziedzictwo", + "ledger_error_wrong_app": "Upewnij się, że uruchamiasz odpowiednią aplikację na swoim portfelu", + "ledger_please_enable_bluetooth": "Włącz Bluetooth aby wykryć twój portfel", + "legacy": "Legacy", "light_theme": "Jasny", "litecoin_enable_mweb_sync": "Włącz skanowanie MWEB", "litecoin_mweb": "MWEB", "litecoin_mweb_allow_coins": "Zezwalaj na monety MWEB", - "litecoin_mweb_always_scan": "Ustaw MWEB zawsze skanowanie", - "litecoin_mweb_description": "MWEB to nowy protokół, który przynosi szybciej, tańsze i bardziej prywatne transakcje do Litecoin", - "litecoin_mweb_dismiss": "Odrzucać", + "litecoin_mweb_always_scan": "Ustaw MWEB na ciągłe skanowanie", + "litecoin_mweb_description": "MWEB to nowy protokół, który oferuje szybsze, tańsze i bardziej prywatne transakcje dla kryptowaluty Litecoin", + "litecoin_mweb_dismiss": "Odrzuć", "litecoin_mweb_display_card": "Pokaż kartę MWEB", "litecoin_mweb_enable": "Włącz MWEB", "litecoin_mweb_enable_later": "Możesz ponownie włączyć MWEB w ustawieniach wyświetlania.", "litecoin_mweb_logs": "Dzienniki MWEB", "litecoin_mweb_node": "Węzeł MWEB", - "litecoin_mweb_pegin": "Kołek", - "litecoin_mweb_pegout": "Palikować", + "litecoin_mweb_pegin": "Peg in", + "litecoin_mweb_pegout": "Peg out", "litecoin_mweb_scanning": "Skanowanie MWEB", "litecoin_mweb_settings": "Ustawienia MWEB", "litecoin_mweb_warning": "Korzystanie z MWEB początkowo pobiera ~ 600 MB danych i może potrwać do 30 minut w zależności od prędkości sieci. Te początkowe dane pobierają tylko raz i będą dostępne dla wszystkich portfeli Litecoin", @@ -430,7 +432,7 @@ "manage_yats": "Zarządzaj Yats", "mark_as_redeemed": "Oznacz jako wykorzystany", "market_place": "Rynek", - "matrix_green_dark_theme": "Matrix Zielony ciemny motyw", + "matrix_green_dark_theme": "Matrix zielony ciemny motyw", "max_amount": "Max: ${value}", "max_value": "Max: ${value} ${currency}", "memo": "Notatka:", @@ -439,7 +441,7 @@ "methods": "Metody", "min_amount": "Min: ${value}", "min_value": "Min: ${value} ${currency}", - "mint_address": "Adres mięty", + "mint_address": "Adres mintowania", "minutes_to_pin_code": "${minute} minut", "mm": "MM", "modify_2fa": "Zmodyfikuj ciasto 2FA", @@ -450,7 +452,7 @@ "moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}", "more_options": "Więcej opcji", "multiple_addresses_detected": "Wykryto wiele adresów", - "mweb_confirmed": "Potwierdził MWEB", + "mweb_confirmed": "Potwierdzone MWEB", "mweb_unconfirmed": "Niepotwierdzone MWEB", "name": "Nazwa", "nano_current_rep": "Obecny przedstawiciel", @@ -468,8 +470,8 @@ "newConnection": "Nowe połączenie", "no_cards_found": "Nie znaleziono żadnych kart", "no_extra_detail": "Brak dodatkowych szczegółów", - "no_id_needed": "Nie potrzeba Dowodu!", - "no_id_required": "Nie wymagamy Dowodu. Doładuj i wydawaj gdziekolwiek", + "no_id_needed": "Nie potrzeba dowodu!", + "no_id_required": "Nie wymagamy dowodu. Doładuj i wydawaj gdziekolwiek", "no_providers_available": "Brak dostępnych dostawców", "no_relay_on_domain": "Brak przekaźnika dla domeny użytkownika lub przekaźnik jest niedostępny. Wybierz przekaźnik, którego chcesz użyć.", "no_relays": "Żadnych przekaźników", @@ -493,9 +495,9 @@ "offline": "Offline", "ok": "Ok", "old_fee": "Stara opłata", - "onion_link": "Łącznik cebulowy", + "onion_link": "Link .onion", "online": "online", - "onramper_option_description": "Szybko kup kryptowaluty z wieloma metodami płatności. Dostępne w większości krajów. Spready i opłaty różnią się.", + "onramper_option_description": "Szybko kup kryptowaluty z wieloma metodami płatności. Dostępne w większości krajów. Ceny i opłaty różnią się.", "open_gift_card": "Otwórz kartę podarunkową", "open_wallet": "Otwarty portfel", "optional_description": "Opcjonalny opis", @@ -514,8 +516,8 @@ "overshot": "Przesadzanie", "overwrite_amount": "Nadpisz ilość", "pairingInvalidEvent": "Nieprawidłowe zdarzenie parowania", - "passphrase": "PassPhraza (opcjonalnie)", - "passphrases_doesnt_match": "Passfrazy nie pasują, spróbuj ponownie", + "passphrase": "Hasło frazy seed (opcjonalnie)", + "passphrases_doesnt_match": "Hasła frazy seed nie pasują, spróbuj ponownie", "password": "Hasło", "paste": "Wklej", "pause_wallet_creation": "Możliwość utworzenia Portfela Haven jest obecnie wstrzymana.", @@ -530,20 +532,21 @@ "placeholder_transactions": "Twoje transakcje zostaną wyświetlone tutaj", "please_choose_one": "Wybierz jeden", "please_fill_totp": "Wpisz 8-cyfrowy kod znajdujący się na drugim urządzeniu", - "please_make_selection": "Wybierz poniżej, aby utworzyć lub przywrócić swój portfel.", + "please_make_selection": "Wybierz opcję, aby utworzyć lub przywrócić swój portfel.", "please_reference_document": "Proszę odwołać się do poniższych dokumentów, aby uzyskać więcej informacji.", "please_select": "Proszę wybrać:", "please_select_backup_file": "Wybierz plik kopii zapasowej i wprowadź hasło.", "please_try_to_connect_to_another_node": "Spróbuj połączyć się z innym węzłem", "please_wait": "Proszę czekać", "polygonscan_history": "Historia PolygonScan", + "potential_scam": "Potencjalne oszustwo", "powered_by": "Obsługiwane przez ${title}", "pre_seed_button_text": "Rozumiem. Pokaż mi moją fraze seed", - "pre_seed_description": "Na następnej stronie zobaczysz serię ${words} słów. To jest Twoja unikalna i prywatna fraza seed i jest to JEDYNY sposób na odzyskanie portfela w przypadku utraty lub awarii telefonu. Twoim obowiązkiem jest zapisanie go i przechowywanie w bezpiecznym miejscu (np. na kartce w SEJFIE).", - "pre_seed_title": "WAŻNY", + "pre_seed_description": "Na następnej stronie zobaczysz serię ${words} słów. To jest Twoja unikalna i prywatna fraza seed i jest to JEDYNY sposób na odzyskanie portfela w przypadku utraty lub awarii telefonu. Twoim obowiązkiem jest zapisanie go i przechowywanie w bezpiecznym miejscu (np. na kartce w sejfie).", + "pre_seed_title": "WAŻNE", "prepaid_cards": "Karty przedpłacone", "prevent_screenshots": "Zapobiegaj zrzutom ekranu i nagrywaniu ekranu", - "primary_address": "Adres podstawowy", + "primary_address": "Adres główny", "privacy": "Prywatność", "privacy_policy": "Polityka prywatności", "privacy_settings": "Ustawienia prywatności", @@ -553,10 +556,10 @@ "proceed_on_device_description": "Postępuj zgodnie z instrukcjami wyświetlonymi w portfelu sprzętowym", "processing": "Przetwarzanie", "profile": "Profil", - "provider_error": "${provider} pomyłka", + "provider_error": "${provider} błąd", "public_key": "Klucz publiczny", "purchase_gift_card": "Kup kartę podarunkową", - "purple_dark_theme": "Purple Dark Temat", + "purple_dark_theme": "Ciemy Fiolet", "qr_fullscreen": "Dotknij, aby otworzyć pełnoekranowy kod QR", "qr_payment_amount": "Ten kod QR zawiera kwotę do zapłaty. Czy chcesz nadpisać obecną wartość?", "quantity": "Ilość", @@ -567,14 +570,14 @@ "received": "Odebrane", "recipient_address": "Adres odbiorcy", "reconnect": "Połącz ponownie", - "reconnect_alert_text": "Czy na pewno ponownie się ponownie połączysz?", + "reconnect_alert_text": "Czy na pewno chcesz się ponownie połączyć?", "reconnect_your_hardware_wallet": "Ponownie podłącz portfel sprzętowy", "reconnection": "Ponowne łączenie", "red_dark_theme": "Czerwony Mroczny motyw", - "red_light_theme": "Motyw czerwony światło", - "redeemed": "wykupione", + "red_light_theme": "Cezrwony Jasny motyw", + "redeemed": "wydane", "refund_address": "Adres do zwrotu", - "reject": "Odrzucić", + "reject": "Odrzuć", "remaining": "pozostałe", "remove": "Usuń", "remove_node": "Usuń węzeł", @@ -607,21 +610,21 @@ "restore_description_from_hardware_wallet": "Przywróć z portfela sprzętowego księgi", "restore_description_from_keys": "Przywróć swój portfel z kluczy prywatnych", "restore_description_from_seed": "Przywróć swój portfel z 25 lub 13-słownej frazy seed", - "restore_description_from_seed_keys": "Odzyskaj swój portfel z seedów / kluczy, które zapisałeś w bezpiecznym miejscu", + "restore_description_from_seed_keys": "Odzyskaj swój portfel z frazy seed / kluczy, które zapisałeś w bezpiecznym miejscu", "restore_existing_wallet": "Przywróć istniejący portfel", "restore_from_date_or_blockheight": "Wprowadź datę na kilka dni przed utworzeniem tego portfela, lub jeśli znasz wysokość bloku, wprowadź go zamiast daty", "restore_from_seed_placeholder": "Wpisz lub wklej tutaj swoją frazę seed", "restore_new_seed": "Nowy seed", - "restore_next": "Kolejny", + "restore_next": "Następny", "restore_recover": "Przywróć", "restore_restore_wallet": "Przywróć portfel", - "restore_seed_keys_restore": "Przywracanie seedów / kluczy", + "restore_seed_keys_restore": "Przywracanie z frazy seed / kluczy", "restore_spend_key_private": "Podaj prywatny klucz wglądu (view key)", "restore_title_from_backup": "Przywróć z pliku kopii zapasowej", "restore_title_from_hardware_wallet": "Przywróć z portfela sprzętowego", "restore_title_from_keys": "Przywróć z kluczy", - "restore_title_from_seed": "Przywróć z seedów", - "restore_title_from_seed_keys": "Przywróć z seedów / kluczy", + "restore_title_from_seed": "Przywróć z frazy seed", + "restore_title_from_seed_keys": "Przywróć z frazy seed / kluczy", "restore_view_key_private": "Podaj klucz prywatny", "restore_wallet": "Przywróć portfel", "restore_wallet_name": "Nazwa portfela", @@ -680,8 +683,8 @@ "seedtype": "Sedtype", "seedtype_alert_content": "Dzielenie się nasionami z innymi portfelami jest możliwe tylko z BIP39 sededType.", "seedtype_alert_title": "Ustanowienie typu sedype", - "seedtype_legacy": "Dziedzictwo (25 słów)", - "seedtype_polyseed": "Poliqueed (16 słów)", + "seedtype_legacy": "Legacy (25 słów)", + "seedtype_polyseed": "Polyseed (16 słów)", "seedtype_wownero": "Wowero (14 słów)", "select_backup_file": "Wybierz plik kopii zapasowej", "select_buy_provider_notice": "Wybierz powyższe dostawcę zakupu. Możesz pominąć ten ekran, ustawiając domyślnego dostawcę zakupu w ustawieniach aplikacji.", @@ -702,7 +705,7 @@ "send_error_minimum_value": "Minimalna wartość to 0,01", "send_estimated_fee": "Szacowana opłata:", "send_fee": "Opłata:", - "send_from_cake_wallet": "Wyślij z portfela ciasta", + "send_from_cake_wallet": "Wyślij z Cake Wallet", "send_from_external_wallet": "Wyślij z portfela zewnętrznego", "send_name": "Imię", "send_new": "Nowy", @@ -745,24 +748,24 @@ "settings_trades": "Transakcje", "settings_transactions": "Transakcje", "settings_wallets": "Portfele", - "setup_2fa": "Skonfiguruj ciasto 2FA", + "setup_2fa": "Skonfiguruj Cake 2FA", "setup_2fa_text": "Cake 2FA działa przy użyciu TOTP jako drugiego czynnika uwierzytelniającego.\n\nTOTP Cake 2FA wymaga obsługi SHA-512 i 8 cyfr; zapewnia to większe bezpieczeństwo. Więcej informacji i obsługiwane aplikacje znajdziesz w przewodniku.", "setup_pin": "Ustaw PIN", "setup_successful": "Twój kod PIN został pomyślnie skonfigurowany!", "setup_totp_recommended": "Skonfiguruj TOTP", - "setup_warning_2fa_text": "Będziesz musiał przywrócić swój portfel z nasion mnemonicznych.\n\nWsparcie Cake nie będzie w stanie Ci pomóc, jeśli utracisz dostęp do swoich nasion 2FA lub mnemoników.\nCake 2FA to drugie uwierzytelnienie niektórych działań w portfelu. Przed użyciem Cake 2FA zalecamy zapoznanie się z instrukcją.NIE jest tak bezpieczne jak przechowywanie w chłodni.\n\nJeśli utracisz dostęp do aplikacji 2FA lub kluczy TOTP, UTRAcisz dostęp do tego portfela. ", + "setup_warning_2fa_text": "Będziesz musiał przywrócić swój portfel z frazy seed.\n\nWsparcie Cake nie będzie w stanie Ci pomóc, jeśli utracisz dostęp do swoich kluczy 2FA lub frazy seed.\nCake 2FA to drugie uwierzytelnienie niektórych działań w portfelu. Przed użyciem Cake 2FA zalecamy zapoznanie się z instrukcją. Cake 2FA nie jest tak bezpieczne jak przechowywanie w zimnym lub sprzętowym portfelu.\n\nJeśli utracisz dostęp do aplikacji 2FA lub kluczy TOTP, Utracisz dostęp do tego portfela.", "setup_your_debit_card": "Skonfiguruj swoją kartę debetową", "share": "Udział", "share_address": "Udostępnij adres", - "shared_seed_wallet_groups": "Wspólne grupy portfeli nasion", + "shared_seed_wallet_groups": "Grupy portfeli", "show": "Pokazywać", "show_address_book_popup": "Pokaż okienko książki adresowej", - "show_balance": "Długa prasa, aby pokazać równowagę", - "show_balance_toast": "Długa naciśnij, aby ukryć lub pokazać równowagę", + "show_balance": "Przytrzymaj, aby pokazać saldo", + "show_balance_toast": "Przytrzymaj i puść, aby ukryć lub pokazać saldo", "show_details": "Pokaż szczegóły", "show_keys": "Pokaż seed/klucze", "show_market_place": "Pokaż rynek", - "show_seed": "Pokaż frazy seed", + "show_seed": "Pokaż frazę seed", "sign_message": "Podpisuj wiadomość", "sign_up": "Zarejestruj się", "sign_verify_message": "Podpisz lub zweryfikuj wiadomość", @@ -772,10 +775,10 @@ "signature_invalid_error": "Podpis nie jest ważny dla podanej wiadomości", "signTransaction": "Podpisz transakcję", "signup_for_card_accept_terms": "Zarejestruj się, aby otrzymać kartę i zaakceptuj warunki.", - "silent_payment": "Cicha płatność", - "silent_payments": "Ciche płatności", + "silent_payment": "Silent Payment", + "silent_payments": "Silent Payments", "silent_payments_always_on": "(zawsze dalej)", - "silent_payments_always_scan": "Ustaw ciche płatności zawsze skanowanie", + "silent_payments_always_scan": "Włącz ciągłe skanowanie Silent Payments", "silent_payments_disclaimer": "Nowe adresy nie są nową tożsamością. Jest to ponowne wykorzystanie istniejącej tożsamości z inną etykietą.", "silent_payments_display_card": "Pokaż kartę Silent Payments", "silent_payments_register_key": "Zarejestruj się Wyświetl Klucz do szybszego skanowania", @@ -785,7 +788,7 @@ "silent_payments_scanned_tip": "Zeskanowany do napiwku! (${tip})", "silent_payments_scanning": "Skanowanie cichych płatności", "silent_payments_settings": "Ustawienia o cichej płatności", - "single_seed_wallets_group": "Pojedyncze portfele nasion", + "single_seed_wallets_group": "Pojedyncze portfele", "slidable": "Przesuwne", "solana_create_associated_token_account_exception": "Błąd tworzenia powiązanego konta tokena dla adresu wpływającego.", "solana_no_associated_token_account_exception": "Nie ma powiązanego konta tokena dla tego adresu.", @@ -803,10 +806,10 @@ "support_description_guides": "Dokumentacja i wsparcie dla typowych problemów", "support_description_live_chat": "Darmowe i szybkie! Do pomocy są dostępni przeszkoleni przedstawiciele wsparcia", "support_description_other_links": "Dołącz do naszych społeczności lub skontaktuj się z nami naszymi partnerami za pomocą innych metod", - "support_title_guides": "Dokumenty portfela ciasta", + "support_title_guides": "Dokumenty Cake Wallet", "support_title_live_chat": "Wsparcie na żywo", "support_title_other_links": "Inne linki wsparcia", - "swap": "Zamieniać", + "swap": "Wymiana", "sweeping_wallet": "Zamiatanie portfela", "sweeping_wallet_alert": "To nie powinno zająć dużo czasu. NIE WYCHODŹ Z TEGO EKRANU, W PRZECIWNYM WYPADKU MOŻE ZOSTAĆ UTRACONA ŚRODKI", "switchToETHWallet": "Przejdź na portfel Ethereum i spróbuj ponownie", @@ -825,25 +828,26 @@ "sync_status_syncronizing": "SYNCHRONIZACJA", "sync_status_timed_out": "PRZEKROCZONO LIMIT CZASU", "sync_status_unsupported": "Nieobsługiwany węzeł", - "syncing_wallet_alert_content": "Twoje saldo i lista transakcji mogą nie być kompletne, dopóki u góry nie pojawi się napis „SYNCHRONIZOWANY”. Kliknij/stuknij, aby dowiedzieć się więcej.", + "synchronizing": "Synchronizacja", + "syncing_wallet_alert_content": "Twoje saldo i lista transakcji mogą nie być kompletne, dopóki u góry nie pojawi się napis „ZSYNCHRONIZOWANY”. Kliknij/stuknij, aby dowiedzieć się więcej.", "syncing_wallet_alert_title": "Twój portfel się synchronizuje", "template": "Szablon", "template_name": "Nazwa szablonu", "testnet_coins_no_value": "Monety testowe nie mają wartości", - "third_intro_content": "Yats mieszkają również poza Cake Wallet. Każdy adres portfela na ziemi można zastąpić Yat!", + "third_intro_content": "Yats działają również poza Cake Wallet. Każdy adres portfela na ziemi można zamienić na Yat!", "third_intro_title": "Yat ładnie bawi się z innymi", "this_pair_is_not_supported_warning": "Ta para nie jest obsługiwana z aktualnie wybraną wymianą. Wybierz kolejną wymianę.", "thorchain_contract_address_not_supported": "Thorchain nie wspiera wysyłania na adres umowy", "thorchain_taproot_address_not_supported": "Dostawca Thorchain nie obsługuje adresów TAPROOT. Zmień adres lub wybierz innego dostawcę.", "time": "${minutes}m ${seconds}s", - "tip": "wskazówka:", + "tip": "tip:", "today": "Dzisiaj", "token_contract_address": "Adres kontraktu tokena", "token_decimal": "Token dziesiętny", "token_name": "Nazwa tokena, np.: Tether", "token_symbol": "Symbol tokena np.: USDT", "tokenID": "ID", - "tor_connection": "Połączenie Torem", + "tor_connection": "Połączenie przez Tor", "tor_only": "Tylko sieć Tor", "total": "Całkowity", "total_saving": "Całkowite oszczędności", @@ -869,19 +873,19 @@ "trade_is_powered_by": "Ta wymiana jest obsługiwana przez ${provider}", "trade_not_created": "Wymiana nie została utworzona", "trade_not_found": "Nie znaleziono transakcji.", - "trade_state_btc_sent": "Wysłanie", - "trade_state_complete": "Ukończona", + "trade_state_btc_sent": "Wysłano", + "trade_state_complete": "Ukończono", "trade_state_confirming": "Potwierdzanie", - "trade_state_created": "Stworzona", - "trade_state_finished": "Zakończona", - "trade_state_paid": "Opłacona", + "trade_state_created": "Stworzono", + "trade_state_finished": "Zakończono", + "trade_state_paid": "Opłacono", "trade_state_paid_unconfirmed": "Transakcja niepotwierdzona", "trade_state_pending": "Oczekująca", "trade_state_timeout": "Koniec czasu", "trade_state_to_be_created": "Została stworzona", "trade_state_traded": "Wymienione", "trade_state_trading": "Wymiana", - "trade_state_underpaid": "Niedopłacone", + "trade_state_underpaid": "Niedopłacona", "trade_state_unpaid": "Nie opłacona", "trades": "Transakcje", "transaction_cost": "Koszt transakcji", @@ -904,21 +908,21 @@ "transaction_priority_medium": "Średnia", "transaction_priority_minimum": "Minimum", "transaction_priority_regular": "Regularna", - "transaction_priority_slow": "Powolny ~ 24 godziny+", + "transaction_priority_slow": "Wolna (Zalecane)", "transaction_sent": "Transakcja wysłana!", "transaction_sent_notice": "Jeśli ekran nie zmieni się po 1 minucie, sprawdź eksplorator bloków i swój e-mail.", "transactions": "Transakcje", "transactions_by_date": "Transakcje według daty", "trongrid_history": "Historia Trongrida", "trusted": "Zaufany", - "tx_commit_exception_no_dust_on_change": "Transakcja jest odrzucana z tą kwotą. Za pomocą tych monet możesz wysłać ${min} bez zmiany lub ${max}, które zwraca zmianę.", + "tx_commit_exception_no_dust_on_change": "Transakcja została odrzucana z tą kwotą. Za pomocą tych monet możesz wysłać ${min} bez reszty lub ${max}, które zwrócą resztę.", "tx_commit_failed": "Zatwierdzenie transakcji nie powiodło się. Skontaktuj się z obsługą.", "tx_commit_failed_no_peers": "Transakcja nie była transmitowana, spróbuj ponownie za około sekundę", "tx_invalid_input": "Używasz niewłaściwego typu wejściowego dla tego rodzaju płatności", "tx_no_dust_exception": "Transakcja jest odrzucana przez wysyłanie zbyt małej ilości. Spróbuj zwiększyć kwotę.", "tx_not_enough_inputs_exception": "Za mało dostępnych danych wejściowych. Wybierz więcej pod kontrolą monet", "tx_rejected_bip68_final": "Transakcja niepotwierdza wejściów i nie zastąpiła opłaty.", - "tx_rejected_dust_change": "Transakcja odrzucona według reguł sieciowych, niska ilość zmiany (kurz). Spróbuj wysłać całość lub zmniejszyć kwotę.", + "tx_rejected_dust_change": "Transakcja odrzucona według reguł sieciowych, niska ilość zmiany (pył). Spróbuj wysłać całość lub zmniejszyć kwotę.", "tx_rejected_dust_output": "Transakcja odrzucona według reguł sieciowych, niskiej ilości wyjściowej (pyłu). Zwiększ kwotę.", "tx_rejected_dust_output_send_all": "Transakcja odrzucona według reguł sieciowych, niskiej ilości wyjściowej (pyłu). Sprawdź saldo monet wybranych pod kontrolą monet.", "tx_rejected_vout_negative": "Za mało salda, aby zapłacić za opłaty tej transakcji. Sprawdź saldo monet pod kontrolą monet.", @@ -929,15 +933,15 @@ "unavailable_balance_description": "Niedostępne saldo: Suma ta obejmuje środki zablokowane w transakcjach oczekujących oraz te, które aktywnie zamroziłeś w ustawieniach kontroli monet. Zablokowane salda staną się dostępne po zakończeniu odpowiednich transakcji, natomiast zamrożone salda pozostaną niedostępne dla transakcji, dopóki nie zdecydujesz się ich odblokować.", "unconfirmed": "Niepotwierdzone saldo", "understand": "Rozumiem", - "unlock": "Odblokować", - "unmatched_currencies": "Waluta Twojego obecnego portfela nie zgadza się z waluctą zeskanowanego kodu QR", + "unlock": "Odblokuj", + "unmatched_currencies": "Waluta Twojego obecnego portfela nie zgadza się z walutą zeskanowanego kodu QR", "unrestricted_background_service": "Nieograniczona usługa w tle", "unrestricted_background_service_notice": "Aby włączyć synchronizację tła, musisz włączyć nieograniczoną usługę w tle", "unspent_change": "Zmiana", "unspent_coins_details_title": "Szczegóły niewydanych monet", "unspent_coins_title": "Niewydane monety", "unsupported_asset": "Nie obsługujemy tego działania w przypadku tego zasobu. Utwórz lub przełącz się na portfel obsługiwanego typu aktywów.", - "uptime": "Czas aktu", + "uptime": "Czas online", "upto": "do ${value}", "usb": "USB", "use": "Użyj ", @@ -988,19 +992,19 @@ "wallet_name": "Nazwa portfela", "wallet_name_exists": "Portfel o tej nazwie już istnieje", "wallet_password_is_empty": "Hasło portfela jest puste. Hasło portfela nie powinno być puste", - "wallet_recovery_height": "Wysokość odzysku", + "wallet_recovery_height": "Wysokość odzyskiwania", "wallet_restoration_store_incorrect_seed_length": "Nieprawidłowa długość frazy seed", "wallet_seed": "Seed portfela", "wallet_seed_legacy": "Dziedziczne ziarno portfela", "wallet_store_monero_wallet": "Portfel Monero", - "walletConnect": "PortfelPołącz", + "walletConnect": "WalletConnect", "wallets": "Portfele", "warning": "Ostrzeżenie", "welcome": "Witamy w", - "welcome_subtitle_new_wallet": "Jeśli chcesz zacząć od nowa, dotknij Utwórz nowy portfel poniżej, a będziesz na wyścigach.", + "welcome_subtitle_new_wallet": "Jeśli chcesz zacząć od nowa, dotknij Utwórz nowy portfel poniżej.", "welcome_subtitle_restore_wallet": "Jeśli masz istniejący portfel, który chcesz wnieść do ciasta, po prostu wybierz przywróć istniejący portfel, a my przeprowadzimy Cię przez proces.", "welcome_to_cakepay": "Witamy w Cake Pay!", - "what_is_silent_payments": "Co to są ciche płatności?", + "what_is_silent_payments": "Co to Silent Payments?", "widgets_address": "Adres", "widgets_or": "lub", "widgets_restore_from_blockheight": "Przywróć z wysokości bloku", @@ -1011,7 +1015,7 @@ "xlm_extra_info": "Nie zapomnij podać dodatkowego identyfikatora (memo) podczas wysyłania transakcji XLM do wymiany", "xmr_available_balance": "Dostępne środki", "xmr_full_balance": "Pełne saldo", - "xmr_hidden": "Ukryty", + "xmr_hidden": "Ukryte", "xmr_to_error": "Błąd XMR.TO", "xmr_to_error_description": "Nieprawidłowa kwota. Maksymalny limit to 8 cyfr po przecinku", "xrp_extra_info": "Nie zapomnij podać tagu docelowego podczas wysyłania transakcji XRP do wymiany", @@ -1030,4 +1034,4 @@ "you_will_receive_estimated_amount": "Otrzymasz(oszacowane )", "you_will_send": "Konwertuj z", "yy": "RR" -} \ No newline at end of file +} diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 3c17e6fe3..68262ef50 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Compre Bitcoin", "buy_now": "Comprar agora", "buy_provider_unavailable": "Provedor atualmente indisponível.", + "buy_sell_pair_is_not_supported_warning": "Este par de moeda não é suportado por nenhum provedor para o método de pagamento selecionado. Escolha um par diferente ou tente alterar o método de pagamento.", "buy_with": "Compre com", "by_cake_pay": "por Cake Pay", "cake_2fa_preset": "Predefinição de bolo 2FA", @@ -131,6 +132,7 @@ "change_rep_message": "Tem certeza de que deseja alterar os representantes?", "change_rep_successful": "Mudou com sucesso o representante", "change_selected_exchanges": "Altere as trocas selecionadas", + "change_selected_pair": "Altere o par selecionado", "change_wallet_alert_content": "Quer mudar a carteira atual para ${wallet_name}?", "change_wallet_alert_title": "Alterar carteira atual", "choose_a_payment_method": "Escolha um método de pagamento", @@ -539,6 +541,7 @@ "please_try_to_connect_to_another_node": "Por favor, tente conectar-se a outro nó", "please_wait": "Por favor, aguarde", "polygonscan_history": "História do PolygonScan", + "potential_scam": "Golpe potencial", "powered_by": "Troca realizada por ${title}", "pre_seed_button_text": "Compreendo. Me mostre minha semente", "pre_seed_description": "Na próxima página, você verá uma série de ${words} palavras. Esta é a sua semente única e privada e é a ÚNICA maneira de recuperar sua carteira em caso de perda ou mau funcionamento. É SUA responsabilidade anotá-lo e armazená-lo em um local seguro fora do aplicativo Cake Wallet.", @@ -827,6 +830,7 @@ "sync_status_syncronizing": "SINCRONIZANDO", "sync_status_timed_out": "TEMPO ESGOTADO", "sync_status_unsupported": "Nó não suportado", + "synchronizing": "Sincronizando", "syncing_wallet_alert_content": "Seu saldo e lista de transações podem não estar completos até que diga “SYNCHRONIZED” no topo. Clique/toque para saber mais.", "syncing_wallet_alert_title": "Sua carteira está sincronizando", "template": "Modelo", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index a0c0aad67..d15ddf371 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Купить Bitcoin", "buy_now": "Купить сейчас", "buy_provider_unavailable": "Поставщик в настоящее время недоступен.", + "buy_sell_pair_is_not_supported_warning": "Эта валютная пара не поддерживается каким -либо поставщиком для выбранного способа оплаты. Пожалуйста, выберите другую пару или попробуйте изменить метод оплаты.", "buy_with": "Купить с помощью", "by_cake_pay": "от Cake Pay", "cake_2fa_preset": "Торт 2FA Preset", @@ -131,6 +132,7 @@ "change_rep_message": "Вы уверены, что хотите сменить представителя?", "change_rep_successful": "Успешно изменил представитель", "change_selected_exchanges": "Изменить выбранные обмены", + "change_selected_pair": "Изменить выбранную пару", "change_wallet_alert_content": "Вы хотите изменить текущий кошелек на ${wallet_name}?", "change_wallet_alert_title": "Изменить текущий кошелек", "choose_a_payment_method": "Выберите способ оплаты", @@ -538,6 +540,7 @@ "please_try_to_connect_to_another_node": "Пожалуйста, попробуйте подключиться к другой ноде", "please_wait": "Пожалуйста, подождите", "polygonscan_history": "История PolygonScan", + "potential_scam": "Потенциальная афера", "powered_by": "Используя ${title}", "pre_seed_button_text": "Понятно. Покажите мнемоническую фразу", "pre_seed_description": "На следующей странице вы увидите серию из ${words} слов. Это ваша уникальная и личная мнемоническая фраза, и это ЕДИНСТВЕННЫЙ способ восстановить свой кошелек в случае потери или неисправности. ВАМ необходимо записать ее и хранить в надежном месте вне приложения Cake Wallet.", @@ -826,6 +829,7 @@ "sync_status_syncronizing": "СИНХРОНИЗАЦИЯ", "sync_status_timed_out": "ВРЕМЯ ВЫШЛО", "sync_status_unsupported": "Неподдерживаемый узел", + "synchronizing": "Синхронизация", "syncing_wallet_alert_content": "Ваш баланс и список транзакций могут быть неполными, пока вверху не будет написано «СИНХРОНИЗИРОВАНО». Щелкните/коснитесь, чтобы узнать больше.", "syncing_wallet_alert_title": "Ваш кошелек синхронизируется", "template": "Шаблон", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 5362c91be..652b28ce4 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "ซื้อ Bitcoin", "buy_now": "ซื้อตอนนี้", "buy_provider_unavailable": "ผู้ให้บริการไม่สามารถใช้งานได้ในปัจจุบัน", + "buy_sell_pair_is_not_supported_warning": "คู่สกุลเงินนี้ไม่ได้รับการสนับสนุนจากผู้ให้บริการรายใดสำหรับวิธีการชำระเงินที่เลือก โปรดเลือกคู่อื่นหรือลองเปลี่ยนวิธีการชำระเงิน", "buy_with": "ซื้อด้วย", "by_cake_pay": "โดย Cake Pay", "cake_2fa_preset": "เค้ก 2FA ที่ตั้งไว้ล่วงหน้า", @@ -131,6 +132,7 @@ "change_rep_message": "คุณแน่ใจหรือไม่ว่าต้องการเปลี่ยนตัวแทน", "change_rep_successful": "เปลี่ยนตัวแทนสำเร็จ", "change_selected_exchanges": "เปลี่ยนการแลกเปลี่ยนที่เลือก", + "change_selected_pair": "เปลี่ยนคู่ที่เลือก", "change_wallet_alert_content": "คุณต้องการเปลี่ยนกระเป๋าปัจจุบันเป็น ${wallet_name} หรือไม่?", "change_wallet_alert_title": "เปลี่ยนกระเป๋าปัจจุบัน", "choose_a_payment_method": "เลือกวิธีการชำระเงิน", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "โปรดลองเชื่อมต่อกับโหนดอื่น", "please_wait": "โปรดรอ", "polygonscan_history": "ประวัติ PolygonScan", + "potential_scam": "การหลอกลวงที่มีศักยภาพ", "powered_by": "พัฒนาขึ้นโดย ${title}", "pre_seed_button_text": "ฉันเข้าใจ แสดง seed ของฉัน", "pre_seed_description": "บนหน้าถัดไปคุณจะเห็นชุดของคำ ${words} คำ นี่คือ seed ของคุณที่ไม่ซ้ำใดๆ และเป็นความลับเพียงของคุณ และนี่คือเพียงวิธีเดียวที่จะกู้กระเป๋าของคุณในกรณีที่สูญหายหรือมีปัญหา มันเป็นความรับผิดชอบของคุณเพื่อเขียนมันลงบนกระดาษและจัดเก็บไว้ในที่ปลอดภัยนอกแอป Cake Wallet", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "กำลังซิงโครไนซ์", "sync_status_timed_out": "หมดเวลา", "sync_status_unsupported": "โหนดที่ไม่ได้รับการสนับสนุน", + "synchronizing": "การซิงโครไนซ์", "syncing_wallet_alert_content": "รายการยอดเงินและธุรกรรมของคุณอาจไม่สมบูรณ์จนกว่าจะมีข้อความว่า “ซิงโครไนซ์” ที่ด้านบน คลิก/แตะเพื่อเรียนรู้เพิ่มเติม่", "syncing_wallet_alert_title": "กระเป๋าสตางค์ของคุณกำลังซิงค์", "template": "แบบฟอร์ม", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 78dff2249..46bf27419 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Bumili ng Bitcoin", "buy_now": "Bumili Ngayon", "buy_provider_unavailable": "Kasalukuyang hindi available ang provider.", + "buy_sell_pair_is_not_supported_warning": "Ang pares ng pera na ito ay hindi suportado ng anumang tagapagbigay ng serbisyo para sa napiling paraan ng pagbabayad. Mangyaring pumili ng ibang pares o subukang baguhin ang paraan ng pagbabayad.", "buy_with": "Bumili ng", "by_cake_pay": "by Cake Pay", "cake_2fa_preset": "Cake 2FA Preset", @@ -131,6 +132,7 @@ "change_rep_message": "Sigurado ka bang nais mong baguhin ang mga representative?", "change_rep_successful": "Matagumpay na nagbago ng representative", "change_selected_exchanges": "Baguhin ang mga napiling palitan", + "change_selected_pair": "Baguhin ang napiling pares", "change_wallet_alert_content": "Gusto mo bang palitan ang kasalukuyang wallet sa ${wallet_name}?", "change_wallet_alert_title": "Baguhin ang kasalukuyang wallet", "choose_a_payment_method": "Pumili ng isang paraan ng pagbabayad", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "Pakisubukang kumonekta sa iba pang node", "please_wait": "Mangyaring maghintay", "polygonscan_history": "Kasaysayan ng PolygonScan", + "potential_scam": "Potensyal na scam", "powered_by": "Pinapagana ng ${title}", "pre_seed_button_text": "Naiintindihan ko. Ipakita sa akin ang aking binhi", "pre_seed_description": "Sa susunod na pahina makikita mo ang isang serye ng mga ${words} na mga salita. Ito ang iyong natatangi at pribadong binhi at ito ang tanging paraan upang mabawi ang iyong pitaka kung sakaling mawala o madepektong paggawa. Responsibilidad mong isulat ito at itago ito sa isang ligtas na lugar sa labas ng cake wallet app.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "PAG-SYNCHRONIZE", "sync_status_timed_out": "NAG-TIME OUT", "sync_status_unsupported": "HINDI SUPORTADONG NODE", + "synchronizing": "Pag -synchronize", "syncing_wallet_alert_content": "Ang iyong balanse at listahan ng transaksyon ay maaaring hindi kumpleto hanggang sa sabihin nito na \"NAKA-SYNCHRONIZE\" sa tuktok. Mag-click/tap upang malaman ang higit pa.", "syncing_wallet_alert_title": "Ang iyong wallet ay nag-sync", "template": "Template", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 5fd1604ae..0081003d0 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Bitcoin Satın Al", "buy_now": "Şimdi al", "buy_provider_unavailable": "Sağlayıcı şu anda kullanılamıyor.", + "buy_sell_pair_is_not_supported_warning": "Bu para birimi çifti, seçilen ödeme yöntemi için herhangi bir sağlayıcı tarafından desteklenmez. Lütfen farklı bir çift seçin veya ödeme yöntemini değiştirmeyi deneyin.", "buy_with": "Şunun ile al: ", "by_cake_pay": "Cake Pay tarafından", "cake_2fa_preset": "Kek 2FA Ön Ayarı", @@ -131,6 +132,7 @@ "change_rep_message": "Temsilcileri değiştirmek istediğinizden emin misiniz?", "change_rep_successful": "Temsilciyi başarıyla değiştirdi", "change_selected_exchanges": "Seçilen borsaları değiştirin", + "change_selected_pair": "Seçilen çifti değiştir", "change_wallet_alert_content": "Şimdiki cüzdanı ${wallet_name} cüzdanı ile değiştirmek istediğinden emin misin?", "change_wallet_alert_title": "Şimdiki cüzdanı değiştir", "choose_a_payment_method": "Bir Ödeme Yöntemi Seçin", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "Lütfen farklı düğüme bağlanmayı dene", "please_wait": "Lütfen bekleyin", "polygonscan_history": "PolygonScan geçmişi", + "potential_scam": "Potansiyel aldatmaca", "powered_by": "${title} tarafından desteklenmektedir", "pre_seed_button_text": "Anladım. Bana tohumumu göster.", "pre_seed_description": "Bir sonraki sayfada ${words} kelime göreceksin. Bu senin benzersiz ve özel tohumundur, kaybetmen veya silinmesi durumunda cüzdanını kurtarmanın TEK YOLUDUR. Bunu yazmak ve Cake Wallet uygulaması dışında güvenli bir yerde saklamak tamamen SENİN sorumluluğunda.", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "SENKRONİZE EDİLİYOR", "sync_status_timed_out": "ZAMAN AŞIMINA UĞRADI", "sync_status_unsupported": "Desteklenmeyen düğüm", + "synchronizing": "Senkronize etme", "syncing_wallet_alert_content": "Bakiyeniz ve işlem listeniz, en üstte \"SENKRONİZE EDİLDİ\" yazana kadar tamamlanmamış olabilir. Daha fazla bilgi edinmek için tıklayın/dokunun.", "syncing_wallet_alert_title": "Cüzdanınız senkronize ediliyor", "template": "Şablon", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index dfcdc1a0b..e4121539e 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Купити Bitcoin", "buy_now": "Купити зараз", "buy_provider_unavailable": "В даний час постачальник недоступний.", + "buy_sell_pair_is_not_supported_warning": "Ця пара валюти не підтримується жодним постачальником для вибраного методу оплати. Виберіть іншу пару або спробуйте змінити метод оплати.", "buy_with": "Купити за допомогою", "by_cake_pay": "від Cake Pay", "cake_2fa_preset": "Торт 2FA Preset", @@ -131,6 +132,7 @@ "change_rep_message": "Ви впевнені, що хочете змінити представника?", "change_rep_successful": "Успішно змінив представник", "change_selected_exchanges": "Змінити вибрані біржі", + "change_selected_pair": "Змінити вибрану пару", "change_wallet_alert_content": "Ви хочете змінити поточний гаманець на ${wallet_name}?", "change_wallet_alert_title": "Змінити поточний гаманець", "choose_a_payment_method": "Виберіть метод оплати", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "Будь ласка, спробуйте підключитися до іншого вузлу", "please_wait": "Будь ласка, зачекайте", "polygonscan_history": "Історія PolygonScan", + "potential_scam": "Потенційна афера", "powered_by": "Використовуючи ${title}", "pre_seed_button_text": "Зрозуміло. Покажіть мнемонічну фразу", "pre_seed_description": "На наступній сторінці ви побачите серію з ${words} слів. Це ваша унікальна та приватна мнемонічна фраза, і це ЄДИНИЙ спосіб відновити ваш гаманець на випадок втрати або несправності. ВАМ необхідно записати її та зберігати в безпечному місці поза програмою Cake Wallet.", @@ -826,6 +829,7 @@ "sync_status_syncronizing": "СИНХРОНІЗАЦІЯ", "sync_status_timed_out": "ТАЙМ-АУТ", "sync_status_unsupported": "Непідтримуваний вузол", + "synchronizing": "Синхронізація", "syncing_wallet_alert_content": "Ваш баланс та список транзакцій може бути неповним, доки вгорі не буде написано «СИНХРОНІЗОВАНО». Натисніть/торкніться, щоб дізнатися більше.", "syncing_wallet_alert_title": "Ваш гаманець синхронізується", "template": "Шаблон", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 1052a37c9..3d99f36a7 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Bitcoin خریدیں۔", "buy_now": "ابھی خریدئے", "buy_provider_unavailable": "فراہم کنندہ فی الحال دستیاب نہیں ہے۔", + "buy_sell_pair_is_not_supported_warning": "اس کرنسی کی جوڑی کو کسی بھی فراہم کنندہ کے ذریعہ منتخب کردہ ادائیگی کے طریقہ کار کے لئے تعاون نہیں کیا جاتا ہے۔ براہ کرم ایک مختلف جوڑی کا انتخاب کریں یا ادائیگی کے طریقہ کار کو تبدیل کرنے کی کوشش کریں۔", "buy_with": "کے ساتھ خریدیں۔", "by_cake_pay": "Cake پے کے ذریعے", "cake_2fa_preset": "کیک 2FA پیش سیٹ", @@ -131,6 +132,7 @@ "change_rep_message": "؟ﮟﯿﮨ ﮯﺘﮨﺎﭼ ﺎﻧﺮﮐ ﻞﯾﺪﺒﺗ ﻮﮐ ﮞﻭﺪﻨﺋﺎﻤﻧ ﯽﻌﻗﺍﻭ ﭖﺁ ﺎﯿﮐ", "change_rep_successful": "نمائندہ کو کامیابی کے ساتھ تبدیل کیا", "change_selected_exchanges": "منتخب تبادلے کو تبدیل کریں", + "change_selected_pair": "منتخب کردہ جوڑی کو تبدیل کریں", "change_wallet_alert_content": "کیا آپ موجودہ والیٹ کو ${wallet_name} میں تبدیل کرنا چاہتے ہیں؟", "change_wallet_alert_title": "موجودہ پرس تبدیل کریں۔", "choose_a_payment_method": "ادائیگی کا طریقہ منتخب کریں", @@ -539,6 +541,7 @@ "please_try_to_connect_to_another_node": "براہ کرم کسی دوسرے نوڈ سے جڑنے کی کوشش کریں۔", "please_wait": "برائے مہربانی انتظار کریں", "polygonscan_history": "ﺦﯾﺭﺎﺗ ﯽﮐ ﻦﯿﮑﺳﺍ ﻥﻮﮔ ﯽﻟﻮﭘ", + "potential_scam": "ممکنہ گھوٹالہ", "powered_by": "${title} کے ذریعے تقویت یافتہ", "pre_seed_button_text": "میں سمجھتا ہوں۔ مجھے میرا بیج دکھاؤ", "pre_seed_description": "اگلے صفحے پر آپ کو ${words} الفاظ کا ایک سلسلہ نظر آئے گا۔ یہ آپ کا انوکھا اور نجی بیج ہے اور یہ آپ کے بٹوے کو ضائع یا خرابی کی صورت میں بازیافت کرنے کا واحد طریقہ ہے۔ اسے لکھنا اور اسے کیک والیٹ ایپ سے باہر کسی محفوظ جگہ پر اسٹور کرنا آپ کی ذمہ داری ہے۔", @@ -827,6 +830,7 @@ "sync_status_syncronizing": "مطابقت پذیری", "sync_status_timed_out": "وقت ختم", "sync_status_unsupported": "غیر تعاون یافتہ نوڈ", + "synchronizing": "ہم آہنگی", "syncing_wallet_alert_content": "آپ کے بیلنس اور لین دین کی فہرست اس وقت تک مکمل نہیں ہو سکتی جب تک کہ یہ سب سے اوپر \"SYNCRONIZED\" نہ کہے۔ مزید جاننے کے لیے کلک/تھپتھپائیں۔", "syncing_wallet_alert_title": "آپ کا بٹوہ مطابقت پذیر ہو رہا ہے۔", "template": "سانچے", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index 9bfaf64e1..690d6fbc5 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Mua Bitcoin", "buy_now": "Mua ngay", "buy_provider_unavailable": "Nhà cung cấp hiện không khả dụng.", + "buy_sell_pair_is_not_supported_warning": "Cặp tiền tệ này được hỗ trợ bởi bất kỳ nhà cung cấp nào cho phương thức thanh toán đã chọn. Vui lòng chọn một cặp khác hoặc thử thay đổi phương thức thanh toán.", "buy_with": "Mua bằng", "by_cake_pay": "bởi Cake Pay", "cake_2fa_preset": "Thiết lập sẵn Cake 2FA", @@ -131,6 +132,7 @@ "change_rep_message": "Bạn có chắc chắn muốn thay đổi đại diện không?", "change_rep_successful": "Thay đổi đại diện thành công", "change_selected_exchanges": "Thay đổi các trao đổi được chọn", + "change_selected_pair": "Thay đổi cặp đã chọn", "change_wallet_alert_content": "Bạn có muốn thay đổi ví hiện tại thành ${wallet_name} không?", "change_wallet_alert_title": "Thay đổi ví hiện tại", "choose_account": "Chọn tài khoản", @@ -535,6 +537,7 @@ "please_try_to_connect_to_another_node": "Vui lòng thử kết nối với một nút khác", "please_wait": "Vui lòng chờ", "polygonscan_history": "Lịch sử PolygonScan", + "potential_scam": "Lừa đảo tiềm năng", "powered_by": "Được cung cấp bởi ${title}", "pre_seed_button_text": "Tôi hiểu. Hiển thị hạt giống của tôi", "pre_seed_description": "Trên trang tiếp theo, bạn sẽ thấy một chuỗi ${words} từ. Đây là hạt giống riêng tư và duy nhất của bạn và là CÁCH DUY NHẤT để khôi phục ví của bạn trong trường hợp mất hoặc hỏng hóc. Đây là TRÁCH NHIỆM của bạn để ghi lại và lưu trữ nó ở một nơi an toàn ngoài ứng dụng Cake Wallet.", @@ -822,6 +825,7 @@ "sync_status_syncronizing": "ĐANG ĐỒNG BỘ", "sync_status_timed_out": "HẾT THỜI GIAN", "sync_status_unsupported": "NÓT KHÔNG ĐƯỢC HỖ TRỢ", + "synchronizing": "Đồng bộ hóa", "syncing_wallet_alert_content": "Số dư và danh sách giao dịch của bạn có thể không đầy đủ cho đến khi nó hiển thị “ĐÃ ĐỒNG BỘ” ở trên cùng. Nhấn vào đây để tìm hiểu thêm.", "syncing_wallet_alert_title": "Ví của bạn đang đồng bộ", "template": "Mẫu", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index d4528f73f..ab7d03526 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "Ra Bitcoin", "buy_now": "Ra Bayibayi", "buy_provider_unavailable": "Olupese lọwọlọwọ ko si.", + "buy_sell_pair_is_not_supported_warning": "Apo owo yii ko ni atilẹyin nipasẹ eyikeyi olupese fun ọna isanwo ti o yan. Jọwọ yan bata ti o yatọ tabi gbiyanju yiyipada ọna isanwo.", "buy_with": "Rà pẹ̀lú", "by_cake_pay": "láti ọwọ́ Cake Pay", "cake_2fa_preset": "Cake 2FA Tito", @@ -131,6 +132,7 @@ "change_rep_message": "Ṣe o da ọ loju pe o fẹ yi awọn aṣoju pada?", "change_rep_successful": "Ni ifijišẹ yipada aṣoju", "change_selected_exchanges": "Yiyipada awọn paṣipaarọ ti o yan", + "change_selected_pair": "Yi bata ti a yan", "change_wallet_alert_content": "Ṣe ẹ fẹ́ pààrọ̀ àpamọ́wọ́ yìí sí ${wallet_name}?", "change_wallet_alert_title": "Ẹ pààrọ̀ àpamọ́wọ́ yìí", "choose_a_payment_method": "Yan ọna isanwo kan", @@ -538,6 +540,7 @@ "please_try_to_connect_to_another_node": "Ẹ jọ̀wọ́, gbìyànjú dárapọ̀ mọ́ apẹka mìíràn yí wọlé", "please_wait": "Jọwọ saa", "polygonscan_history": "PolygonScan itan", + "potential_scam": "Egan ti o ni agbara", "powered_by": "Láti ọwọ́ ${title}", "pre_seed_button_text": "Mo ti gbọ́. O fi hóró mi hàn mi", "pre_seed_description": "Ẹ máa wo àwọn ọ̀rọ̀ ${words} lórí ojú tó ń bọ̀. Èyí ni hóró aládàáni yín tó kì í jọra. Ẹ lè fi í nìkan dá àpamọ́wọ́ yín padà sípò tí àṣìṣe tàbí ìbàjẹ́ bá ṣẹlẹ̀. Hóró yín ni ẹ gbọ́dọ̀ kọ sílẹ̀ àti pamọ́ síbí tó kò léwu níta Cake Wallet.", @@ -826,6 +829,7 @@ "sync_status_syncronizing": "Ń MÚDỌ́GBA", "sync_status_timed_out": "Ti akoko jade", "sync_status_unsupported": "Ile-igbimọ ti ko ni atilẹyin", + "synchronizing": "Mimuuṣiṣẹpọ", "syncing_wallet_alert_content": "Iwontunws.funfun rẹ ati atokọ idunadura le ma pari titi ti yoo fi sọ “SYNCHRONIZED” ni oke. Tẹ/tẹ ni kia kia lati ni imọ siwaju sii.", "syncing_wallet_alert_title": "Apamọwọ rẹ n muṣiṣẹpọ", "template": "Àwòṣe", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 6ee2a5356..0888c9fa3 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -93,6 +93,7 @@ "buy_bitcoin": "购买比特币", "buy_now": "立即购买", "buy_provider_unavailable": "提供者目前不可用。", + "buy_sell_pair_is_not_supported_warning": "此货币对不受任何提供商的支持。请选择另一对或尝试更改付款方式。", "buy_with": "一起购买", "by_cake_pay": "通过 Cake Pay", "cake_2fa_preset": "蛋糕 2FA 预设", @@ -131,6 +132,7 @@ "change_rep_message": "您确定要更换代表吗?", "change_rep_successful": "成功改变了代表", "change_selected_exchanges": "更改选定的交换", + "change_selected_pair": "更改选定对", "change_wallet_alert_content": "您是否想将当前钱包改为 ${wallet_name}?", "change_wallet_alert_title": "更换当前钱包", "choose_a_payment_method": "选择付款方式", @@ -537,6 +539,7 @@ "please_try_to_connect_to_another_node": "请尝试连接到其他节点", "please_wait": "请稍等", "polygonscan_history": "多边形扫描历史", + "potential_scam": "潜在骗局", "powered_by": "Powered by ${title}", "pre_seed_button_text": "我明白。 查看种子", "pre_seed_description": "在下一页上,您将看到${words}个文字。 这是您独有的种子,是丟失或出现故障时恢复钱包的唯一方法。 您有必须将其写下并储存在Cake Wallet应用程序以外的安全地方。", @@ -825,6 +828,7 @@ "sync_status_syncronizing": "正在同步", "sync_status_timed_out": "时间到", "sync_status_unsupported": "不支持的节点", + "synchronizing": "同步", "syncing_wallet_alert_content": "您的余额和交易列表可能不完整,直到顶部显示“已同步”。单击/点击以了解更多信息。", "syncing_wallet_alert_title": "您的钱包正在同步", "template": "模板", diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 597c0aa9a..9b5685a07 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -14,15 +14,15 @@ TYPES=($MONERO_COM $CAKEWALLET) APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.20.3" -MONERO_COM_BUILD_NUMBER=115 +MONERO_COM_VERSION="1.21.0" +MONERO_COM_BUILD_NUMBER=116 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" MONERO_COM_SCHEME="monero.com" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.23.4" -CAKEWALLET_BUILD_NUMBER=249 +CAKEWALLET_VERSION="5.0.0" +CAKEWALLET_BUILD_NUMBER=254 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" CAKEWALLET_SCHEME="cakewallet" diff --git a/scripts/android/build_decred.sh b/scripts/android/build_decred.sh index 0533b2a4c..4588f9143 100755 --- a/scripts/android/build_decred.sh +++ b/scripts/android/build_decred.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -e cd "$(dirname "$0")" @@ -7,10 +7,10 @@ cd "$(dirname "$0")" CW_DECRED_DIR=$(realpath ../..)/cw_decred LIBWALLET_PATH="${PWD}/decred/libwallet" LIBWALLET_URL="https://github.com/decred/libwallet.git" -LIBWALLET_VERSION="87b2769538db3065b334d247b25774593fc6443d" +LIBWALLET_VERSION="dba5327d35cb5d5d1ff113b780869deee154511f" -if [ -e $LIBWALLET_PATH ]; then - rm -fr $LIBWALLET_PATH/{*,.*} || true +if [[ -e $LIBWALLET_PATH ]]; then + rm -fr $LIBWALLET_PATH || true fi mkdir -p $LIBWALLET_PATH || true @@ -65,7 +65,7 @@ do esac # PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}" - if [ -e ./build ]; then + if [[ -e ./build ]]; then rm -fr ./build fi diff --git a/scripts/android/build_mwebd.sh b/scripts/android/build_mwebd.sh index cd4e2c1f4..3e9c5199d 100755 --- a/scripts/android/build_mwebd.sh +++ b/scripts/android/build_mwebd.sh @@ -1,9 +1,9 @@ if [[ "$1" == "--dont-install" ]]; then echo "Skipping Go installation as per --dont-install flag" else - # install go > 1.23: - wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz - sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz + # install go > 1.24: + wget https://go.dev/dl/go1.24.1.linux-amd64.tar.gz + sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.24.1.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:~/go/bin go install golang.org/x/mobile/cmd/gomobile@latest @@ -13,7 +13,7 @@ fi # build mwebd: git clone https://github.com/ltcmweb/mwebd cd mwebd -git reset --hard 555349415f76a42ec5c76152b64c4ab9aabc448f +git reset --hard f75cb9edef07d03360ee2d33e6edae4243a890b1 gomobile bind -target=android -androidapi 21 . mkdir -p ../../../cw_mweb/android/libs/ cp ./mwebd.aar $_ \ No newline at end of file diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh index 1c1579830..a9e86bb4a 100644 --- a/scripts/ios/app_env.sh +++ b/scripts/ios/app_env.sh @@ -12,13 +12,13 @@ TYPES=($MONERO_COM $CAKEWALLET) APP_IOS_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.20.3" -MONERO_COM_BUILD_NUMBER=113 +MONERO_COM_VERSION="1.21.0" +MONERO_COM_BUILD_NUMBER=114 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.23.4" -CAKEWALLET_BUILD_NUMBER=302 +CAKEWALLET_VERSION="5.0.0" +CAKEWALLET_BUILD_NUMBER=308 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" diff --git a/scripts/ios/app_icon.sh b/scripts/ios/app_icon.sh index 3914c3756..e3eb36b3c 100755 --- a/scripts/ios/app_icon.sh +++ b/scripts/ios/app_icon.sh @@ -14,10 +14,6 @@ case $APP_IOS_TYPE in ICON_120_PATH=`pwd`/../../assets/images/cakewallet_icon_120.png ICON_180_PATH=`pwd`/../../assets/images/cakewallet_icon_180.png ICON_1024_PATH=`pwd`/../../assets/images/cakewallet_icon_1024.png;; - "haven") - ICON_120_PATH=`pwd`/../../assets/images/cakewallet_icon_120.png - ICON_180_PATH=`pwd`/../../assets/images/cakewallet_icon_180.png - ICON_1024_PATH=`pwd`/../../assets/images/cakewallet_icon_1024.png;; esac rm $DEST_DIR_PATH/app_icon_120.png diff --git a/scripts/ios/build_decred.sh b/scripts/ios/build_decred.sh index e6b13d0da..6860c7776 100755 --- a/scripts/ios/build_decred.sh +++ b/scripts/ios/build_decred.sh @@ -1,12 +1,12 @@ -#!/bin/sh +#!/bin/bash set -e . ./config.sh LIBWALLET_PATH="${EXTERNAL_IOS_SOURCE_DIR}/libwallet" LIBWALLET_URL="https://github.com/decred/libwallet.git" -LIBWALLET_VERSION="87b2769538db3065b334d247b25774593fc6443d" +LIBWALLET_VERSION="dba5327d35cb5d5d1ff113b780869deee154511f" -if [ -e $LIBWALLET_PATH ]; then - rm -fr $LIBWALLET_PATH +if [[ -e $LIBWALLET_PATH ]]; then + rm -fr $LIBWALLET_PATH fi mkdir -p $LIBWALLET_PATH git clone $LIBWALLET_URL $LIBWALLET_PATH @@ -17,8 +17,8 @@ SYSROOT=`xcrun --sdk iphoneos --show-sdk-path` CLANG="clang -target arm64-apple-ios -isysroot ${SYSROOT}" CLANGXX="clang++ -target arm64-apple-ios -isysroot ${SYSROOT}" -if [ -e ./build ]; then - rm -fr ./build +if [[ -e ./build ]]; then + rm -fr ./build fi CGO_ENABLED=1 GOOS=ios GOARCH=arm64 CC=$CLANG CXX=$CLANGXX \ go build -v -buildmode=c-archive -o ./build/libdcrwallet.a ./cgo || exit 1 diff --git a/scripts/ios/build_mwebd.sh b/scripts/ios/build_mwebd.sh index 5bdd32e15..456d43bb8 100755 --- a/scripts/ios/build_mwebd.sh +++ b/scripts/ios/build_mwebd.sh @@ -2,7 +2,7 @@ if [[ "$1" == "--dont-install" ]]; then echo "Skipping Go installation as per --dont-install flag" else - # install go > 1.23: + # install go > 1.24: brew install go export PATH=$PATH:~/go/bin go install golang.org/x/mobile/cmd/gomobile@latest @@ -12,7 +12,7 @@ fi # build mwebd: git clone https://github.com/ltcmweb/mwebd cd mwebd -git reset --hard 555349415f76a42ec5c76152b64c4ab9aabc448f +git reset --hard f75cb9edef07d03360ee2d33e6edae4243a890b1 gomobile bind -target=ios . mv -fn ./Mwebd.xcframework ../../../cw_mweb/ios/ # cleanup: diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh index ef1747ba6..9d97b63cb 100755 --- a/scripts/linux/app_env.sh +++ b/scripts/linux/app_env.sh @@ -14,8 +14,8 @@ if [ -n "$1" ]; then fi CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.13.4" -CAKEWALLET_BUILD_NUMBER=49 +CAKEWALLET_VERSION="1.14.0" +CAKEWALLET_BUILD_NUMBER=50 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then echo "Wrong app type." diff --git a/scripts/linux/build_cake_release.sh b/scripts/linux/build_cake_release.sh new file mode 100755 index 000000000..e8ad6fc54 --- /dev/null +++ b/scripts/linux/build_cake_release.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +# build_cake_release.sh - Script to build Cake Wallet for Linux +# Usage: ./build_cake_release.sh --amd64 [--arm64] [--app=cakewallet|monero.com] + +set -e + + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd "$SCRIPT_DIR" + + +# Default values +BUILD_AMD64=false +BUILD_ARM64=false +APP_TYPE="cakewallet" +DOCKER_IMAGE="ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.4-go1.24.1" + +# Parse arguments +for arg in "$@" +do + case $arg in + --amd64) + BUILD_AMD64=true + shift + ;; + --arm64) + BUILD_ARM64=true + shift + ;; + --app=*) + APP_TYPE="${arg#*=}" + shift + ;; + *) + echo "Unknown argument: $arg" + echo "Usage: ./build_cake_release.sh --amd64 [--arm64] [--app=cakewallet|monero.com]" + exit 1 + ;; + esac +done + +cd ../.. + +# Validate arguments +if [[ "$BUILD_AMD64" == "false" && "$BUILD_ARM64" == "false" ]]; then + echo "Error: At least one architecture (--amd64 or --arm64) must be specified." + echo "Usage: ./build_cake_release.sh --amd64 [--arm64] [--app=cakewallet|monero.com]" + exit 1 +fi + +if [[ "$APP_TYPE" != "cakewallet" && "$APP_TYPE" != "monero.com" ]]; then + echo "Error: App type must be either 'cakewallet' or 'monero.com'" + echo "Usage: ./build_cake_release.sh --amd64 [--arm64] [--app=cakewallet|monero.com]" + exit 1 +fi + +# Function to build for a specific architecture +build_for_arch() { + local arch=$1 + local flutter_arch=$2 + echo "Building $APP_TYPE for Linux ($arch)" + + docker run --privileged -v$(pwd):$(pwd) -w $(pwd) -i --rm --platform linux/$arch $DOCKER_IMAGE bash -x << EOF +set -x -e +pushd scripts + ./gen_android_manifest.sh +popd +pushd scripts/linux + source ./app_env.sh $APP_TYPE + ./app_config.sh + ./build_monero_all.sh +popd +flutter clean +./model_generator.sh +dart run tool/generate_localization.dart +flutter build linux +rm -rf build/linux/current +cp -r build/linux/$flutter_arch build/linux/current +rm -rf .flatpak-builder +flatpak-builder --force-clean flatpak-build com.cakewallet.CakeWallet.yml +flatpak build-export export flatpak-build +flatpak build-bundle export build/linux/current/cake_wallet.flatpak com.cakewallet.CakeWallet +cp build/linux/current/cake_wallet.flatpak build/linux/$flutter_arch/ +EOF +} + +# Build for specified architectures +echo "Building $APP_TYPE for Linux" +if [[ "$BUILD_AMD64" == "true" ]]; then + build_for_arch "amd64" "x64" +fi + +if [[ "$BUILD_ARM64" == "true" ]]; then + build_for_arch "arm64" "arm64" +fi + +echo "Build process completed." diff --git a/scripts/linux/build_monero_all.sh b/scripts/linux/build_monero_all.sh index 7948d87a1..6c901052f 100755 --- a/scripts/linux/build_monero_all.sh +++ b/scripts/linux/build_monero_all.sh @@ -10,15 +10,19 @@ cd "$(dirname "$0")" for COIN in monero wownero; do pushd ../monero_c - for target in x86_64-linux-gnu # aarch64-linux-gnu - do - if [[ -f "release/${COIN}/${target}_libwallet2_api_c.so" ]]; - then - echo "file exist, not building monero_c for ${COIN}/$target."; - else - ./build_single.sh ${COIN} $target -j$MAKE_JOB_COUNT - unxz -f ../monero_c/release/${COIN}/${target}_libwallet2_api_c.so.xz - fi - done + # Determine target architecture based on system architecture + if [[ $(uname -m) == "arm64" || $(uname -m) == "aarch64" ]]; then + target="aarch64-linux-gnu" + else + target="x86_64-linux-gnu" + fi + + if [[ -f "release/${COIN}/${target}_libwallet2_api_c.so" ]]; + then + echo "file exist, not building monero_c for ${COIN}/$target."; + else + ./build_single.sh ${COIN} $target -j$MAKE_JOB_COUNT + unxz -f ../monero_c/release/${COIN}/${target}_libwallet2_api_c.so.xz + fi popd done \ No newline at end of file diff --git a/scripts/macos/app_config.sh b/scripts/macos/app_config.sh index c10116136..641a7b46b 100755 --- a/scripts/macos/app_config.sh +++ b/scripts/macos/app_config.sh @@ -36,7 +36,7 @@ case $APP_MACOS_TYPE in $MONERO_COM) CONFIG_ARGS="--monero";; $CAKEWALLET) - CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --decred";; + CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero";; esac cp -rf pubspec_description.yaml pubspec.yaml diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index 7410ee3a3..4ac64ba42 100755 --- a/scripts/macos/app_env.sh +++ b/scripts/macos/app_env.sh @@ -16,13 +16,13 @@ if [ -n "$1" ]; then fi MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.10.3" -MONERO_COM_BUILD_NUMBER=45 +MONERO_COM_VERSION="1.11.0" +MONERO_COM_BUILD_NUMBER=46 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.16.4" -CAKEWALLET_BUILD_NUMBER=107 +CAKEWALLET_VERSION="1.17.0" +CAKEWALLET_BUILD_NUMBER=108 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then diff --git a/scripts/macos/build_decred.sh b/scripts/macos/build_decred.sh index d4b7d4d65..e7e5d492f 100755 --- a/scripts/macos/build_decred.sh +++ b/scripts/macos/build_decred.sh @@ -4,7 +4,7 @@ LIBWALLET_PATH="${EXTERNAL_MACOS_SOURCE_DIR}/libwallet" LIBWALLET_URL="https://github.com/decred/libwallet.git" -LIBWALLET_VERSION="87b2769538db3065b334d247b25774593fc6443d" +LIBWALLET_VERSION="dba5327d35cb5d5d1ff113b780869deee154511f" echo "======================= DECRED LIBWALLET =========================" diff --git a/scripts/windows/build_exe_installer.iss b/scripts/windows/build_exe_installer.iss index 211017eff..3f433e1ae 100644 --- a/scripts/windows/build_exe_installer.iss +++ b/scripts/windows/build_exe_installer.iss @@ -1,5 +1,5 @@ #define MyAppName "Cake Wallet" -#define MyAppVersion "0.4.4" +#define MyAppVersion "0.5.0" #define MyAppPublisher "Cake Labs LLC" #define MyAppURL "https://cakewallet.com/" #define MyAppExeName "CakeWallet.exe" diff --git a/tool/append_translation.dart b/tool/append_translation.dart index 8ef646502..7232f308b 100644 --- a/tool/append_translation.dart +++ b/tool/append_translation.dart @@ -1,5 +1,4 @@ -import 'package:cw_core/utils/print_verbose.dart'; - +import 'print_verbose_dummy.dart'; import 'utils/translation/arb_file_utils.dart'; import 'utils/translation/translation_constants.dart'; import 'utils/translation/translation_utils.dart'; diff --git a/tool/configure.dart b/tool/configure.dart index a9272eb0c..c5d9ba1d9 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -494,6 +494,7 @@ abstract class Monero { void setLedgerConnection(Object wallet, ledger.LedgerConnection connection); void resetLedgerConnection(); void setGlobalLedgerConnection(ledger.LedgerConnection connection); + Map> debugCallLength(); } abstract class MoneroSubaddressList { @@ -679,6 +680,7 @@ abstract class Wownero { WalletService createWowneroWalletService(Box walletInfoSource, Box unspentCoinSource); Map pendingTransactionInfo(Object transaction); String getLegacySeed(Object wallet, String langName); + Map> debugCallLength(); } abstract class WowneroSubaddressList { @@ -1322,6 +1324,7 @@ import 'package:cw_zano/model/zano_transaction_info.dart'; import 'package:cw_zano/zano_formatter.dart'; import 'package:cw_zano/zano_wallet.dart'; import 'package:cw_zano/zano_wallet_service.dart'; +import 'package:cw_zano/zano_wallet_api.dart' as api; import 'package:cw_zano/zano_utils.dart'; """; const zanoCwPart = "part 'cw_zano.dart';"; @@ -1348,6 +1351,7 @@ abstract class Zano { Future getZanoAsset(WalletBase wallet, String contractAddress); String getAddress(WalletBase wallet); bool validateAddress(String address); + Map> debugCallLength(); } """; const zanoEmptyDefinition = 'Zano? zano;\n'; diff --git a/tool/download_moneroc_prebuilds.dart b/tool/download_moneroc_prebuilds.dart index 378d9293b..8889a1bc1 100644 --- a/tool/download_moneroc_prebuilds.dart +++ b/tool/download_moneroc_prebuilds.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:cw_core/utils/print_verbose.dart'; +import './print_verbose_dummy.dart'; import 'package:dio/dio.dart'; import 'package:archive/archive_io.dart'; diff --git a/tool/generate_localization.dart b/tool/generate_localization.dart index 0f9af8366..0e07dc2c3 100644 --- a/tool/generate_localization.dart +++ b/tool/generate_localization.dart @@ -1,6 +1,6 @@ import 'dart:io'; import 'dart:convert'; -import 'package:cw_core/utils/print_verbose.dart'; +import './print_verbose_dummy.dart'; import 'localization/localization_constants.dart'; import 'utils/utils.dart'; diff --git a/tool/print_verbose_dummy.dart b/tool/print_verbose_dummy.dart new file mode 100644 index 000000000..f7286e1f9 --- /dev/null +++ b/tool/print_verbose_dummy.dart @@ -0,0 +1 @@ +void printV(dynamic content) => print(content); \ No newline at end of file diff --git a/tool/translation_add_lang.dart b/tool/translation_add_lang.dart index 96f22158d..e3c372a8c 100644 --- a/tool/translation_add_lang.dart +++ b/tool/translation_add_lang.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:cw_core/utils/print_verbose.dart'; +import './print_verbose_dummy.dart'; import 'utils/translation/arb_file_utils.dart'; import 'utils/translation/translation_constants.dart'; diff --git a/tool/translation_consistence.dart b/tool/translation_consistence.dart index df24cce15..2cdd358c8 100644 --- a/tool/translation_consistence.dart +++ b/tool/translation_consistence.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:cw_core/utils/print_verbose.dart'; +import './print_verbose_dummy.dart'; import 'utils/translation/arb_file_utils.dart'; import 'utils/translation/translation_constants.dart'; diff --git a/tool/utils/translation/arb_file_utils.dart b/tool/utils/translation/arb_file_utils.dart index 0fe31d85d..92a8f6e2e 100644 --- a/tool/utils/translation/arb_file_utils.dart +++ b/tool/utils/translation/arb_file_utils.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'dart:io'; -import 'package:cw_core/utils/print_verbose.dart'; +import '../../print_verbose_dummy.dart'; void appendStringToArbFile(String fileName, String name, String text, {bool force = false}) { final file = File(fileName); diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 4deae3420..000000000 --- a/windows/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,35 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -void RegisterPlugins(flutter::PluginRegistry* registry) { - ConnectivityPlusWindowsPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); - FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi")); - FlutterLocalAuthenticationPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FlutterLocalAuthenticationPluginCApi")); - FlutterSecureStorageWindowsPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); - PermissionHandlerWindowsPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); - SharePlusWindowsPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); - UniversalBlePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("UniversalBlePluginCApi")); - UrlLauncherWindowsRegisterWithRegistrar( - registry->GetRegistrarForPlugin("UrlLauncherWindows")); -} diff --git a/windows/flutter/generated_plugin_registrant.h b/windows/flutter/generated_plugin_registrant.h deleted file mode 100644 index dc139d85a..000000000 --- a/windows/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake deleted file mode 100644 index e0f2c11c0..000000000 --- a/windows/flutter/generated_plugins.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - connectivity_plus - flutter_inappwebview_windows - flutter_local_authentication - flutter_secure_storage_windows - permission_handler_windows - share_plus - universal_ble - url_launcher_windows -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST - sp_scanner -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin)