diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index f59ec20aa..000000000 --- a/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -* \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 272f7bbee..18ad16e4b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,4 +11,3 @@ Please include a summary of the changes and which issue is fixed / feature is ad - [ ] Format code - [ ] Look for code duplication - [ ] Clear naming for variables and methods -- [ ] Manual tests in accessibility mode (TalkBack on Android) passed diff --git a/.github/workflows/automated_integration_test.yml b/.github/workflows/automated_integration_test.yml index 47b08c44d..0869db8ea 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-24.04 + runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: @@ -55,7 +55,7 @@ jobs: - name: Flutter action uses: subosito/flutter-action@v1 with: - flutter-version: "3.27.0" + flutter-version: "3.24.0" channel: stable - name: Install package dependencies @@ -153,8 +153,8 @@ jobs: echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart - echo "const changeNowCakeWalletApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart - echo "const changeNowMoneroApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart + echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart + echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart @@ -168,7 +168,6 @@ jobs: echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart - echo "const trocadorMoneroApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart @@ -179,8 +178,7 @@ jobs: echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart - echo "const exolixCakeWalletApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart - echo "const exolixMoneroApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart + echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart @@ -225,10 +223,6 @@ jobs: echo "const nanoTestWalletReceiveAddress = '${{ secrets.NANO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart echo "const wowneroTestWalletReceiveAddress = '${{ secrets.WOWNERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart echo "const moneroTestWalletBlockHeight = '${{ secrets.MONERO_TEST_WALLET_BLOCK_HEIGHT }}';" >> lib/.secrets.g.dart - # end of test secrets - echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart - echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart - echo "const walletGroupSalt = '${{ secrets.WALLET_GROUP_SALT }}';" >> lib/.secrets.g.dart - name: Rename app run: | diff --git a/.github/workflows/no_http_imports.yaml b/.github/workflows/no_http_imports.yaml deleted file mode 100644 index dad6821ac..000000000 --- a/.github/workflows/no_http_imports.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: No http imports - -on: [pull_request] - -jobs: - PR_test_build: - runs-on: ubuntu-24.04 - - steps: - - uses: actions/checkout@v4 - - name: Check for http package usage - if: github.event_name == 'pull_request' - run: | - GIT_GREP_OUT="$(git grep package:http | (grep .dart: || test $? = 1) | (grep -v proxy_wrapper.dart || test $? = 1) | (grep -v very_insecure_http_do_not_use || test $? = 1) || true)" - [[ "x$GIT_GREP_OUT" == "x" ]] && exit 0 - echo "$GIT_GREP_OUT" - echo "There are .dart files which use http imports" - echo "Using http package breaks proxy integration" - echo "Please use ProxyWrapper.getHttpClient() from package:cw_core/utils/proxy_wrapper.dart" - exit 1 - \ No newline at end of file diff --git a/.github/workflows/no_print_in_dart.yaml b/.github/workflows/no_print_in_dart.yaml index 507793bd8..8cd24edfe 100644 --- a/.github/workflows/no_print_in_dart.yaml +++ b/.github/workflows/no_print_in_dart.yaml @@ -1,19 +1,21 @@ name: No print statements in dart files -on: [pull_request] +on: + pull_request: + branches: [main] jobs: PR_test_build: - runs-on: ubuntu-24.04 + runs-on: ubuntu-20.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) | (grep -v print_verbose_dummy.dart || test $? = 1) || true)" + GIT_GREP_OUT="$(git grep ' print(' | (grep .dart: || test $? = 1) | (grep -v print_verbose.dart || test $? = 1) || true)" [[ "x$GIT_GREP_OUT" == "x" ]] && exit 0 echo "$GIT_GREP_OUT" echo "There are .dart files which use print() statements" - echo "Please use printV from package:cw_core/utils/print_verbose.dart" + echo "Please use printV from package: cw_core/utils/print_verbose.dart" exit 1 diff --git a/.github/workflows/no_restricted_imports.yaml b/.github/workflows/no_restricted_imports.yaml deleted file mode 100644 index 03c3de018..000000000 --- a/.github/workflows/no_restricted_imports.yaml +++ /dev/null @@ -1,47 +0,0 @@ -name: No restricted imports in lib directory - -on: [pull_request] - -jobs: - check_restricted_imports: - runs-on: ubuntu-24.04 - - steps: - - uses: actions/checkout@v4 - - name: Check for restricted imports in lib directory - if: github.event_name == 'pull_request' - run: | - RESTRICTED_PACKAGES=( - "cw_bitcoin" - "cw_bitcoin_cash" - "cw_ethereum" - "cw_evm" - "cw_haven" - "cw_mweb" - "cw_nano" - "cw_polygon" - "cw_solana" - "cw_tron" - "cw_wownero" - "cw_zano" - ) - - FOUND_RESTRICTED=false - - for package in "${RESTRICTED_PACKAGES[@]}"; do - GREP_RESULT=$(find lib -type f -name "*.dart" -exec grep -l "import.*package:$package" {} \; || true) - - if [ -n "$GREP_RESULT" ]; then - echo "Found restricted import of '$package' in the following files:" - echo "$GREP_RESULT" - FOUND_RESTRICTED=true - fi - done - - if [ "$FOUND_RESTRICTED" = true ]; then - echo "Error: Restricted package imports found in lib/ directory" - echo "Please remove these imports as they are not allowed in the lib/ directory" - exit 1 - else - echo "No restricted imports found. All good!" - fi \ No newline at end of file diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml index f7c226ce4..25fb144e3 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:debian12-flutter3.27.0-go1.24.1-ruststablenightly + image: ghcr.io/cake-tech/cake_wallet:main-linux env: STORE_PASS: test@cake_wallet KEY_PASS: test@cake_wallet @@ -47,7 +47,6 @@ jobs: echo "message<> $GITHUB_ENV echo "$FULL_MESSAGE" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV - - name: Add secrets run: | touch lib/.secrets.g.dart @@ -98,8 +97,8 @@ jobs: else echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart fi - echo "const changeNowCakeWalletApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart - echo "const changeNowMoneroApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart + echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart + echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart @@ -113,7 +112,6 @@ jobs: echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart - echo "const trocadorMoneroApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart @@ -125,8 +123,7 @@ jobs: echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart - echo "const exolixCakeWalletApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart - echo "const exolixMoneroApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart + echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart @@ -175,8 +172,6 @@ jobs: # end of test secrets echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart - echo "const kryptonimApiKey = '${{ secrets.KRYPTONIM_API_KEY }}';" >> lib/.secrets.g.dart - echo "const walletGroupSalt = '${{ secrets.WALLET_GROUP_SALT }}';" >> lib/.secrets.g.dart - name: prepare monero_c and cache run: | @@ -246,20 +241,8 @@ jobs: ./build_mwebd.sh --dont-install popd - - name: Build Decred - run: | - set -x -e - pushd scripts/android - ./build_decred.sh - popd - - name: Build generated code run: | - flutter --version - flutter clean - rm -rf .dart_tool - rm pubspec.lock - flutter pub get ./model_generator.sh async - name: Generate key properties @@ -281,7 +264,7 @@ jobs: - name: Build run: | - flutter build apk --dart-define=hasDevOptions=true --release --split-per-abi + flutter build apk --release --split-per-abi - name: Rename apk file run: | @@ -296,7 +279,7 @@ jobs: set -x apk_file=$(ls build/app/outputs/flutter-apk/test-apk/${BRANCH_NAME}.apk || exit 1) echo "APK_FILE=$apk_file" >> $GITHUB_ENV - + - name: Upload artifact to slack if: ${{ !contains(env.message, 'skip slack') }} continue-on-error: true @@ -309,9 +292,9 @@ jobs: - name: cleanup run: rm -rf build/app/outputs/flutter-apk/test-apk/ - + - name: Upload Artifact to github uses: actions/upload-artifact@v4 with: path: ${{ github.workspace }}/build/app/outputs/flutter-apk - name: "android apk" + name: "android apk" \ No newline at end of file diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml index f057b19e5..a9d8085b6 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:debian12-flutter3.27.0-go1.24.1-ruststablenightly + image: ghcr.io/cake-tech/cake_wallet:main-linux env: STORE_PASS: test@cake_wallet KEY_PASS: test@cake_wallet @@ -22,6 +22,9 @@ 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... @@ -29,7 +32,6 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - name: configure git run: | git config --global --add safe.directory '*' @@ -91,8 +93,8 @@ jobs: else echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart fi - echo "const changeNowCakeWalletApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart - echo "const changeNowMoneroApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart + echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart + echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart @@ -106,7 +108,6 @@ jobs: echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart - echo "const trocadorMoneroApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart @@ -118,8 +119,7 @@ jobs: echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart - echo "const exolixCakeWalletApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart - echo "const exolixMoneroApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart + echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart @@ -168,8 +168,6 @@ jobs: # end of test secrets echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart - echo "const kryptonimApiKey = '${{ secrets.KRYPTONIM_API_KEY }}';" >> lib/.secrets.g.dart - echo "const walletGroupSalt = '${{ secrets.WALLET_GROUP_SALT }}';" >> lib/.secrets.g.dart - name: prepare monero_c and cache run: | @@ -227,7 +225,7 @@ jobs: - name: Build linux run: | - flutter build linux --dart-define=hasDevOptions=true --release + flutter build linux --release - name: Compress release run: | @@ -285,9 +283,6 @@ jobs: xmessage -timeout 30 "restore_wallet_through_seeds_flow_test" & rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart - - name: Test [cw_monero] - timeout-minutes: 2 - run: cd cw_monero && flutter test - name: Stop screen recording, encrypt and upload if: always() run: | diff --git a/.gitignore b/.gitignore index 84a7ecdcd..c431a7f60 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,6 @@ .history .svn/ .fvm/ -.fvmrc # IntelliJ related *.iml @@ -139,30 +138,10 @@ lib/solana/solana.dart lib/tron/tron.dart lib/wownero/wownero.dart lib/zano/zano.dart -lib/decred/decred.dart - -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon@2x.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon@3x.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x~ipad.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-20~ipad.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x~ipad.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-29~ipad.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x~ipad.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-40~ipad.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x~car.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x~car.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x~ipad.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png -ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon~ipad.png +ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_180.png +ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_120.png +ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png ios/Runner/Info.plist android/app/src/main/res/mipmap-* android/app/src/main/res/drawable/ic_launcher.png @@ -192,7 +171,6 @@ macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png macos/Runner/Configs/AppInfo.xcconfig -macos/Runner.xcodeproj/project.pbxproj integration_test/playground.dart @@ -204,26 +182,3 @@ 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 deleted file mode 100644 index 151b7af20..000000000 --- a/Dockerfile +++ /dev/null @@ -1,190 +0,0 @@ -# docker buildx build --push --pull --platform linux/amd64,linux/arm64 . -f Dockerfile -t ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.0-go1.24.1-ruststablenightly - -# Heavily inspired by cirrusci images -# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/tools/Dockerfile -# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/34/Dockerfile -# 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 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.24.1 - -# Pin Flutter version to latest known-working version -ENV FLUTTER_VERSION=3.27.0 - -# Pin Android Studio, platform, and build tools versions to latest known-working version -# Comes from https://developer.android.com/studio/#command-tools -ENV ANDROID_SDK_TOOLS_VERSION=13114758 -# Comes from https://developer.android.com/studio/releases/build-tools -ENV ANDROID_PLATFORM_VERSION=35 -ENV ANDROID_BUILD_TOOLS_VERSION=34.0.0 - -# If we ever need to migrate the home directory... -RUN sed -i 's|^root:[^:]*:[^:]*:[^:]*:[^:]*:/root:|root:x:0:0:root:/root:|' /etc/passwd -# mkdir -p /root && rm -rf /root && cp -a /root /root -ENV HOME=/root -ENV ANDROID_HOME=/opt/android-sdk-linux \ - LANG=en_US.UTF-8 \ - LC_ALL=en_US.UTF-8 \ - LANGUAGE=en_US:en - -# Set Android SDK paths -ENV ANDROID_SDK_ROOT=$ANDROID_HOME \ - PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/emulator - -# Upgrade base image -RUN apt-get update \ - && apt-get upgrade -y - -# Install all build dependencies -RUN set -o xtrace \ - && cd /opt \ - && apt-get install -y --no-install-recommends --no-install-suggests \ - # Core dependencies - bc build-essential curl default-jdk git jq lcov libglu1-mesa libpulse0 libsqlite3-dev libstdc++6 locales openssh-client ruby-bundler ruby-full software-properties-common sudo unzip wget zip \ - # for x86 emulators - libatk-bridge2.0-0 libgdk-pixbuf2.0-0 libgtk-3-0 libnspr4 libnss3-dev libsqlite3-dev libxtst6 libxss1 lftp sqlite3 xxd \ - # Linux desktop dependencies - clang cmake libgtk-3-dev ninja-build pkg-config \ - # monero_c dependencies - autoconf automake build-essential ccache gperf libtool llvm \ - # extra stuff for KVM - bridge-utils libvirt-clients libvirt-daemon-system qemu-kvm udev \ - # Linux test dependencies - 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 && \ - apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# Install Go -ENV PATH=${PATH}:/usr/local/go/bin:${HOME}/go/bin -ENV GOROOT=/usr/local/go -ENV GOPATH=${HOME}/go -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 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 \ - && chown -R root:root $ANDROID_HOME \ - && rm android-sdk-tools.zip \ - && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \ - && yes | sdkmanager --licenses \ - && wget -O /usr/bin/android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/master/community-cookbooks/android-sdk/files/default/android-wait-for-emulator \ - && chmod +x /usr/bin/android-wait-for-emulator \ - && sdkmanager platform-tools \ - && mkdir -p ${HOME}/.android \ - && touch ${HOME}/.android/repositories.cfg \ - - -# Handle emulator not being available on linux/arm64 (https://issuetracker.google.com/issues/227219818) -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 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" \ - "platforms;android-34" \ - "platforms;android-35" \ - "build-tools;33.0.2" \ - "build-tools;33.0.1" \ - "build-tools;33.0.0" \ - "build-tools;35.0.0" - -# Install extra NDK dependency for sp_scanner -ENV ANDROID_NDK_VERSION=27.2.12479018 -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 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" \ - "platforms;android-31" - -# Fake the KVM status so the Android emulator doesn't complain (that much) -RUN (addgroup kvm || true) && \ - adduser root kvm && \ - mkdir -p /etc/udev/rules.d/ && \ - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | tee /etc/udev/rules.d/99-kvm4all.rules - -# Install rustup, rust toolchains, and cargo-ndk -ENV PATH=${HOME}/.cargo/bin:${PATH} -RUN curl https://sh.rustup.rs -sSf | bash -s -- -y && \ - cargo install cargo-ndk && \ - for toolchain in stable nightly; \ - do \ - 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 $toolchain $target; \ - done \ - done - -# Download and install Flutter -ENV HOME=${HOME} -ENV FLUTTER_HOME=${HOME}/sdks/flutter/${FLUTTER_VERSION} -ENV FLUTTER_ROOT=$FLUTTER_HOME -ENV PATH=${PATH}:${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin - -RUN git clone --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git ${FLUTTER_HOME} && \ - cd ${FLUTTER_HOME} && \ - git fetch -a - -RUN yes | flutter doctor --android-licenses \ - && flutter doctor \ - && chown -R root:root ${FLUTTER_HOME} - -# Download and pre-cache necessary Flutter artifacts to speed up builds -RUN flutter precache diff --git a/README.md b/README.md index ea796dbf2..ea8f34624 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,10 @@ Cake Wallet includes support for several cryptocurrencies, including: * Ethereum (ETH) * Litecoin (LTC) * Bitcoin Cash (BCH) -* Polygon (POL) +* Polygon (Pol) * Solana (SOL) -* Tron (TRX) * Nano (XNO) -* Zano (ZANO) -* Decred (DCR) -* Wownero (WOW) +* Haven (XHV) ## Features @@ -84,6 +81,10 @@ Cake Wallet includes support for several cryptocurrencies, including: * Automatically generate new addresses * Specify multiple recipients for batch sending +### Haven Specific Features + +* Send, receive, and store XHV and all xAssets like xUSD, xEUR, xAG, etc. + # Monero.com by Cake Wallet for Android and iOS ## Open Source Monero-Only Wallet diff --git a/docs/SECURITY.md b/SECURITY.md similarity index 100% rename from docs/SECURITY.md rename to SECURITY.md diff --git a/android/app/build.gradle b/android/app/build.gradle index 4a8045bb3..b65c54108 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,9 +1,3 @@ -plugins { - id "com.android.application" - id "kotlin-android" - id "dev.flutter.flutter-gradle-plugin" -} - def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -12,6 +6,11 @@ if (localPropertiesFile.exists()) { } } +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' @@ -22,6 +21,9 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { @@ -35,21 +37,13 @@ if (appPropertiesFile.exists()) { } android { - compileSdkVersion 35 - buildToolsVersion "35.0.0" + compileSdkVersion 34 + buildToolsVersion "34.0.0" lintOptions { disable 'InvalidPackage' } - compileOptions { - coreLibraryDesugaringEnabled true - - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 - } - - namespace "com.cakewallet.cake_wallet" defaultConfig { @@ -81,11 +75,12 @@ android { buildTypes { release { signingConfig signingConfigs.release + + shrinkResources false + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } - debug { - signingConfig signingConfigs.release - } } ndkVersion "27.0.12077973" @@ -99,7 +94,6 @@ dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' } configurations { implementation.exclude module:'proto-google-common-protos' diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index a733bae9e..d24d7f10a 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -5,98 +5,4 @@ -keep class io.flutter.view.** { *; } -keep class io.flutter.** { *; } -keep class io.flutter.plugins.** { *; } --dontwarn io.flutter.embedding.** --dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication - -# start reown --dontwarn com.github.luben.zstd.BufferPool --dontwarn com.github.luben.zstd.ZstdInputStream --dontwarn com.github.luben.zstd.ZstdOutputStream --dontwarn com.google.api.client.http.GenericUrl --dontwarn com.google.api.client.http.HttpHeaders --dontwarn com.google.api.client.http.HttpRequest --dontwarn com.google.api.client.http.HttpRequestFactory --dontwarn com.google.api.client.http.HttpResponse --dontwarn com.google.api.client.http.HttpTransport --dontwarn com.google.api.client.http.javanet.NetHttpTransport$Builder --dontwarn com.google.api.client.http.javanet.NetHttpTransport --dontwarn java.awt.Color --dontwarn java.awt.Dimension --dontwarn java.awt.Graphics2D --dontwarn java.awt.Graphics --dontwarn java.awt.Image --dontwarn java.awt.Point --dontwarn java.awt.Polygon --dontwarn java.awt.Shape --dontwarn java.awt.color.ColorSpace --dontwarn java.awt.geom.AffineTransform --dontwarn java.awt.image.BufferedImage --dontwarn java.awt.image.ColorModel --dontwarn java.awt.image.ComponentColorModel --dontwarn java.awt.image.ComponentSampleModel --dontwarn java.awt.image.DataBuffer --dontwarn java.awt.image.DataBufferByte --dontwarn java.awt.image.DataBufferInt --dontwarn java.awt.image.DataBufferUShort --dontwarn java.awt.image.ImageObserver --dontwarn java.awt.image.MultiPixelPackedSampleModel --dontwarn java.awt.image.Raster --dontwarn java.awt.image.RenderedImage --dontwarn java.awt.image.SampleModel --dontwarn java.awt.image.SinglePixelPackedSampleModel --dontwarn java.awt.image.WritableRaster --dontwarn java.beans.BeanInfo --dontwarn java.beans.FeatureDescriptor --dontwarn java.beans.IntrospectionException --dontwarn java.beans.Introspector --dontwarn java.beans.PropertyDescriptor --dontwarn java.lang.reflect.InaccessibleObjectException --dontwarn javax.imageio.IIOImage --dontwarn javax.imageio.ImageIO --dontwarn javax.imageio.ImageWriteParam --dontwarn javax.imageio.ImageWriter --dontwarn javax.imageio.metadata.IIOMetadata --dontwarn javax.imageio.stream.ImageOutputStream --dontwarn javax.swing.JComponent --dontwarn javax.swing.JFileChooser --dontwarn javax.swing.JFrame --dontwarn javax.swing.JPanel --dontwarn javax.swing.ProgressMonitor --dontwarn javax.swing.SwingUtilities --dontwarn org.brotli.dec.BrotliInputStream --dontwarn org.joda.time.Instant --dontwarn org.objectweb.asm.AnnotationVisitor --dontwarn org.objectweb.asm.Attribute --dontwarn org.objectweb.asm.ClassReader --dontwarn org.objectweb.asm.ClassVisitor --dontwarn org.objectweb.asm.FieldVisitor --dontwarn org.objectweb.asm.Label --dontwarn org.objectweb.asm.MethodVisitor --dontwarn org.objectweb.asm.Type --dontwarn org.tukaani.xz.ARMOptions --dontwarn org.tukaani.xz.ARMThumbOptions --dontwarn org.tukaani.xz.DeltaOptions --dontwarn org.tukaani.xz.FilterOptions --dontwarn org.tukaani.xz.FinishableOutputStream --dontwarn org.tukaani.xz.FinishableWrapperOutputStream --dontwarn org.tukaani.xz.IA64Options --dontwarn org.tukaani.xz.LZMA2InputStream --dontwarn org.tukaani.xz.LZMA2Options --dontwarn org.tukaani.xz.LZMAInputStream --dontwarn org.tukaani.xz.LZMAOutputStream --dontwarn org.tukaani.xz.MemoryLimitException --dontwarn org.tukaani.xz.PowerPCOptions --dontwarn org.tukaani.xz.SPARCOptions --dontwarn org.tukaani.xz.SingleXZInputStream --dontwarn org.tukaani.xz.UnsupportedOptionsException --dontwarn org.tukaani.xz.X86Options --dontwarn org.tukaani.xz.XZ --dontwarn org.tukaani.xz.XZInputStream --dontwarn org.tukaani.xz.XZOutputStream --dontwarn us.hebi.matlab.mat.ejml.Mat5Ejml --dontwarn us.hebi.matlab.mat.format.Mat5 --dontwarn us.hebi.matlab.mat.format.Mat5File --dontwarn us.hebi.matlab.mat.types.Array --dontwarn us.hebi.matlab.mat.types.MatFile$Entry --dontwarn us.hebi.matlab.mat.types.MatFile -# end reown \ No newline at end of file +-dontwarn io.flutter.embedding.** \ No newline at end of file diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index 8283a7c8c..5a1824a17 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -24,10 +24,6 @@ - - - - - - - - @@ -111,15 +100,10 @@ - - - plugins.load(reader) } } -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.7.1" apply false - id "org.jetbrains.kotlin.android" version "2.0.21" apply false - id "com.google.gms.google-services" version "4.3.8" apply false +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory } - -include ":app" \ No newline at end of file diff --git a/assets/decred_node_list.yml b/assets/decred_node_list.yml deleted file mode 100644 index cb171e701..000000000 --- a/assets/decred_node_list.yml +++ /dev/null @@ -1,6 +0,0 @@ -- - uri: default-spv-nodes - is_default: true -- - uri: dcrd.sethforprivacy.com:9108 - useSSL: true \ No newline at end of file diff --git a/assets/faq/faq_pl.json b/assets/faq/faq_pl.json index b41841cd8..a38d79068 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 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" + "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" }, { "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 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" : "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" : "Czy zbieracie jakieś informacje o moim portfelu?", + "question" : "Czy zbierasz 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 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" + "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" }, { "question" : "Co to jest ID transakcji?", diff --git a/assets/images/2.0x/decred.png b/assets/images/2.0x/decred.png deleted file mode 100644 index 2f4919cec..000000000 Binary files a/assets/images/2.0x/decred.png and /dev/null differ diff --git a/assets/images/2.0x/decred_menu.png b/assets/images/2.0x/decred_menu.png deleted file mode 100644 index 4a41efef1..000000000 Binary files a/assets/images/2.0x/decred_menu.png and /dev/null differ diff --git a/assets/images/2fa.png b/assets/images/2fa.png deleted file mode 100644 index 36c99beab..000000000 Binary files a/assets/images/2fa.png and /dev/null differ diff --git a/assets/images/2fa_warning_dark.svg b/assets/images/2fa_warning_dark.svg deleted file mode 100644 index c9fcad341..000000000 --- a/assets/images/2fa_warning_dark.svg +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/2fa_warning_light.svg b/assets/images/2fa_warning_light.svg deleted file mode 100644 index 087d8e99b..000000000 --- a/assets/images/2fa_warning_light.svg +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/3.0x/decred.png b/assets/images/3.0x/decred.png deleted file mode 100644 index b2c9ac818..000000000 Binary files a/assets/images/3.0x/decred.png and /dev/null differ diff --git a/assets/images/3.0x/decred_menu.png b/assets/images/3.0x/decred_menu.png deleted file mode 100644 index e55b3fb5c..000000000 Binary files a/assets/images/3.0x/decred_menu.png and /dev/null differ diff --git a/assets/images/birthday_cake.png b/assets/images/birthday_cake.png index 293cd10f6..84b084fba 100644 Binary files a/assets/images/birthday_cake.png and b/assets/images/birthday_cake.png differ diff --git a/assets/images/btc_lock_dark.png b/assets/images/btc_lock_dark.png deleted file mode 100644 index f5b3d7e27..000000000 Binary files a/assets/images/btc_lock_dark.png and /dev/null differ diff --git a/assets/images/btc_lock_light.png b/assets/images/btc_lock_light.png deleted file mode 100644 index 4320d96e3..000000000 Binary files a/assets/images/btc_lock_light.png and /dev/null differ diff --git a/assets/images/buy.png b/assets/images/buy.png index 32c116e6b..ff4549d5a 100644 Binary files a/assets/images/buy.png and b/assets/images/buy.png differ diff --git a/assets/images/cake_logo.png b/assets/images/cake_logo.png index abbb4e62b..8a85bf225 100644 Binary files a/assets/images/cake_logo.png and b/assets/images/cake_logo.png differ diff --git a/assets/images/cake_logo_dark.svg b/assets/images/cake_logo_dark.svg deleted file mode 100644 index 095077443..000000000 --- a/assets/images/cake_logo_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/cake_logo_light.svg b/assets/images/cake_logo_light.svg deleted file mode 100644 index 767e205d1..000000000 --- a/assets/images/cake_logo_light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/cakewallet_android_icon.png b/assets/images/cakewallet_android_icon.png old mode 100644 new mode 100755 index 7f15c62f5..59cc69414 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 345888d26..c8bd4b26c 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 89c9b0571..10d0a1a82 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 new file mode 100644 index 000000000..5b0fde827 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_back.png 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 new file mode 100644 index 000000000..9c16f0a27 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_fore.png 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 new file mode 100644 index 000000000..27f939b41 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_adaptive_mono.png 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 deleted file mode 100644 index 19669488f..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_background.png and /dev/null 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 deleted file mode 100644 index 1411a5da5..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_foreground.png and /dev/null 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 deleted file mode 100644 index 1411a5da5..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-hdpi/ic_launcher_monochrome.png and /dev/null 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 8f1d1c28b..8c59ec33e 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 new file mode 100644 index 000000000..5d25e42e7 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_back.png 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 new file mode 100644 index 000000000..021fe65de Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_fore.png 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 new file mode 100644 index 000000000..7bdb298c1 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_mono.png 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 deleted file mode 100644 index 75025cfd5..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_background.png and /dev/null 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 deleted file mode 100644 index e8c47adb3..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_foreground.png and /dev/null 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 deleted file mode 100644 index e8c47adb3..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_monochrome.png and /dev/null 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 f775a8fac..10c3acd7f 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 new file mode 100644 index 000000000..c4b66dc58 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_back.png 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 new file mode 100644 index 000000000..b440b154d Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_fore.png 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 new file mode 100644 index 000000000..79e9df08d Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_mono.png 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 deleted file mode 100644 index 9784f16c8..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_background.png and /dev/null 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 deleted file mode 100644 index 6ba8eb301..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null 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 deleted file mode 100644 index 6ba8eb301..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_monochrome.png and /dev/null 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 31458fa02..813a3678d 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 new file mode 100644 index 000000000..75dc0219d Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_back.png 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 new file mode 100644 index 000000000..90afb19e8 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_fore.png 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 new file mode 100644 index 000000000..0bb1c7430 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_mono.png 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 deleted file mode 100644 index 04ef206c8..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_background.png and /dev/null 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 deleted file mode 100644 index cc93d633b..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null 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 deleted file mode 100644 index cc93d633b..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_monochrome.png and /dev/null 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 158afbbf9..671422b96 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 new file mode 100644 index 000000000..46b1e2cb1 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_back.png 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 new file mode 100644 index 000000000..0a2025220 Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png 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 new file mode 100644 index 000000000..205f2ad2a Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png 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 deleted file mode 100644 index 66a5487a2..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_background.png and /dev/null 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 deleted file mode 100644 index 0ecd56e8c..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null 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 deleted file mode 100644 index 0ecd56e8c..000000000 Binary files a/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_monochrome.png and /dev/null differ diff --git a/assets/images/cakewallet_app_logo.png b/assets/images/cakewallet_app_logo.png new file mode 100644 index 000000000..59cc69414 Binary files /dev/null and b/assets/images/cakewallet_app_logo.png differ diff --git a/assets/images/cakewallet_icon_1024.png b/assets/images/cakewallet_icon_1024.png index 35cf42245..64682cd1d 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 6e45f6423..1a2c1b99c 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 da585ca42..ff69a866a 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 c465fa26c..bf6896ad2 100644 Binary files a/assets/images/cakewallet_logo.png and b/assets/images/cakewallet_logo.png differ diff --git a/assets/images/contact.png b/assets/images/contact.png deleted file mode 100644 index 5cf96694b..000000000 Binary files a/assets/images/contact.png and /dev/null differ diff --git a/assets/images/contact_icon.svg b/assets/images/contact_icon.svg deleted file mode 100644 index 6dbfcd5f4..000000000 --- a/assets/images/contact_icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/dcr_icon.png b/assets/images/dcr_icon.png index 757cd0388..609873611 100644 Binary files a/assets/images/dcr_icon.png and b/assets/images/dcr_icon.png differ diff --git a/assets/images/decred.png b/assets/images/decred.png deleted file mode 100644 index 0b12f2ef0..000000000 Binary files a/assets/images/decred.png and /dev/null differ diff --git a/assets/images/decred_icon.png b/assets/images/decred_icon.png deleted file mode 100644 index 9391abc3d..000000000 Binary files a/assets/images/decred_icon.png and /dev/null differ diff --git a/assets/images/decred_menu.png b/assets/images/decred_menu.png deleted file mode 100644 index 5c67923c5..000000000 Binary files a/assets/images/decred_menu.png and /dev/null differ diff --git a/assets/images/deuro_icon.png b/assets/images/deuro_icon.png deleted file mode 100644 index 4dc068ff8..000000000 Binary files a/assets/images/deuro_icon.png and /dev/null differ diff --git a/assets/images/hero/cw_welcome_dark.svg b/assets/images/hero/cw_welcome_dark.svg deleted file mode 100644 index 5479cb1ee..000000000 --- a/assets/images/hero/cw_welcome_dark.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/assets/images/hero/cw_welcome_light.svg b/assets/images/hero/cw_welcome_light.svg deleted file mode 100644 index ece7d1f84..000000000 --- a/assets/images/hero/cw_welcome_light.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/assets/images/history.svg b/assets/images/history.svg deleted file mode 100644 index f308ab7e3..000000000 --- a/assets/images/history.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/assets/images/home_screen_setting_icon.svg b/assets/images/home_screen_setting_icon.svg deleted file mode 100644 index 7b3aa7b4c..000000000 --- a/assets/images/home_screen_setting_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@2x.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@2x.png deleted file mode 100644 index 3fd15f3ce..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@2x.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@2x~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@2x~ipad.png deleted file mode 100644 index 3fd15f3ce..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@3x.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@3x.png deleted file mode 100644 index b6ff994f6..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20@3x.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20~ipad.png deleted file mode 100644 index 4be1a2317..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-20~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29.png deleted file mode 100644 index 219f2c6be..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@2x.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@2x.png deleted file mode 100644 index ae94bb0ac..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@2x.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@2x~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@2x~ipad.png deleted file mode 100644 index ae94bb0ac..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@3x.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@3x.png deleted file mode 100644 index 0ef9d3bbf..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29@3x.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29~ipad.png deleted file mode 100644 index 219f2c6be..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-29~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@2x.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@2x.png deleted file mode 100644 index 9fdb32376..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@2x.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@2x~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@2x~ipad.png deleted file mode 100644 index 9fdb32376..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@3x.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@3x.png deleted file mode 100644 index 485f8b37b..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40@3x.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40~ipad.png deleted file mode 100644 index 3fd15f3ce..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-40~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-60@2x~car.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-60@2x~car.png deleted file mode 100644 index 485f8b37b..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-60@2x~car.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-60@3x~car.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-60@3x~car.png deleted file mode 100644 index 50148e6dc..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-60@3x~car.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-83.5@2x~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-83.5@2x~ipad.png deleted file mode 100644 index 8f290ada2..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon-83.5@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@2x.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@2x.png deleted file mode 100644 index 485f8b37b..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@2x.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@2x~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@2x~ipad.png deleted file mode 100644 index b11d7332f..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@3x.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@3x.png deleted file mode 100644 index 50148e6dc..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon@3x.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon~ios-marketing.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon~ios-marketing.png deleted file mode 100644 index 1fce95553..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon~ios-marketing.png and /dev/null differ diff --git a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon~ipad.png b/assets/images/ios_icons/cakewallet_ios_icons/AppIcon~ipad.png deleted file mode 100644 index 7d4a82186..000000000 Binary files a/assets/images/ios_icons/cakewallet_ios_icons/AppIcon~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-20@2x.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-20@2x.png deleted file mode 100644 index 7ea540caf..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-20@2x.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-20@2x~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-20@2x~ipad.png deleted file mode 100644 index 7ea540caf..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-20@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-20@3x.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-20@3x.png deleted file mode 100644 index 6ac773754..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-20@3x.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-20~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-20~ipad.png deleted file mode 100644 index 57864a9b3..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-20~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-29.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-29.png deleted file mode 100644 index 27f817dfc..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-29.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-29@2x.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-29@2x.png deleted file mode 100644 index 0455b4409..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-29@2x.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-29@2x~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-29@2x~ipad.png deleted file mode 100644 index 0455b4409..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-29@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-29@3x.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-29@3x.png deleted file mode 100644 index 1b8a73481..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-29@3x.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-29~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-29~ipad.png deleted file mode 100644 index 27f817dfc..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-29~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-40@2x.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-40@2x.png deleted file mode 100644 index 963612d0c..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-40@2x.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-40@2x~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-40@2x~ipad.png deleted file mode 100644 index 963612d0c..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-40@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-40@3x.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-40@3x.png deleted file mode 100644 index b6da404cb..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-40@3x.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-40~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-40~ipad.png deleted file mode 100644 index 7ea540caf..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-40~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-60@2x~car.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-60@2x~car.png deleted file mode 100644 index b6da404cb..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-60@2x~car.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-60@3x~car.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-60@3x~car.png deleted file mode 100644 index 37f7651a5..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-60@3x~car.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon-83.5@2x~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon-83.5@2x~ipad.png deleted file mode 100644 index 21aa12463..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon-83.5@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon@2x.png b/assets/images/ios_icons/monero_ios_icons/AppIcon@2x.png deleted file mode 100644 index b6da404cb..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon@2x.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon@2x~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon@2x~ipad.png deleted file mode 100644 index b6b63a61e..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon@2x~ipad.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon@3x.png b/assets/images/ios_icons/monero_ios_icons/AppIcon@3x.png deleted file mode 100644 index 37f7651a5..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon@3x.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon~ios-marketing.png b/assets/images/ios_icons/monero_ios_icons/AppIcon~ios-marketing.png deleted file mode 100644 index 0c977110a..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon~ios-marketing.png and /dev/null differ diff --git a/assets/images/ios_icons/monero_ios_icons/AppIcon~ipad.png b/assets/images/ios_icons/monero_ios_icons/AppIcon~ipad.png deleted file mode 100644 index 849c5612a..000000000 Binary files a/assets/images/ios_icons/monero_ios_icons/AppIcon~ipad.png and /dev/null differ diff --git a/assets/images/kryptonim_dark.png b/assets/images/kryptonim_dark.png deleted file mode 100644 index 646d550ba..000000000 Binary files a/assets/images/kryptonim_dark.png and /dev/null differ diff --git a/assets/images/kryptonim_light.png b/assets/images/kryptonim_light.png deleted file mode 100644 index 85e64a3f2..000000000 Binary files a/assets/images/kryptonim_light.png and /dev/null differ diff --git a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_1024.png b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_1024.png index c465fa26c..73101354a 100644 Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_1024.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_1024.png differ diff --git a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_128.png b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_128.png index e79db4d99..9ceee3c5e 100644 Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_128.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_128.png differ diff --git a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_16.png b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_16.png index 2d030845b..ef46cd805 100644 Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_16.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_16.png differ diff --git a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_256.png b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_256.png index eef607c2c..6547a1b1b 100644 Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_256.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_256.png differ diff --git a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_32.png b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_32.png index a09896830..e436872e8 100644 Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_32.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_32.png differ diff --git a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_512.png b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_512.png index a98c5faf8..157b00493 100644 Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_512.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_512.png differ diff --git a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_64.png b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_64.png index d8141a250..a46ed4535 100644 Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_64.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_64.png differ diff --git a/assets/images/menu.svg b/assets/images/menu.svg deleted file mode 100644 index 0a4cc3784..000000000 --- a/assets/images/menu.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/notif.svg b/assets/images/notif.svg deleted file mode 100644 index b1ff5b4fa..000000000 --- a/assets/images/notif.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/notification_icon.svg b/assets/images/notification_icon.svg index 360d0b4e6..099039e67 100644 --- a/assets/images/notification_icon.svg +++ b/assets/images/notification_icon.svg @@ -1,3 +1,69 @@ - - - + + + +image/svg+xml \ No newline at end of file diff --git a/assets/images/passphrase_dark.png b/assets/images/passphrase_dark.png deleted file mode 100644 index f72d1e1a1..000000000 Binary files a/assets/images/passphrase_dark.png and /dev/null differ diff --git a/assets/images/passphrase_key.svg b/assets/images/passphrase_key.svg deleted file mode 100644 index c577dc30a..000000000 --- a/assets/images/passphrase_key.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/passphrase_light.png b/assets/images/passphrase_light.png deleted file mode 100644 index f86f68156..000000000 Binary files a/assets/images/passphrase_light.png and /dev/null differ diff --git a/assets/images/payjoin.png b/assets/images/payjoin.png deleted file mode 100644 index 1ba3dccdb..000000000 Binary files a/assets/images/payjoin.png and /dev/null differ diff --git a/assets/images/qr-cake.png b/assets/images/qr-cake.png deleted file mode 100644 index 7c54dedb0..000000000 Binary files a/assets/images/qr-cake.png and /dev/null differ diff --git a/assets/images/receive.png b/assets/images/receive.png deleted file mode 100644 index 180a4e5b3..000000000 Binary files a/assets/images/receive.png and /dev/null differ diff --git a/assets/images/seed_verified_dark.png b/assets/images/seed_verified_dark.png deleted file mode 100644 index cbefa5d8c..000000000 Binary files a/assets/images/seed_verified_dark.png and /dev/null differ diff --git a/assets/images/seed_verified_light.png b/assets/images/seed_verified_light.png deleted file mode 100644 index a51eddcd7..000000000 Binary files a/assets/images/seed_verified_light.png and /dev/null differ diff --git a/assets/images/seed_warning_dark.svg b/assets/images/seed_warning_dark.svg deleted file mode 100644 index 0a47254ff..000000000 --- a/assets/images/seed_warning_dark.svg +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/seed_warning_light.svg b/assets/images/seed_warning_light.svg deleted file mode 100644 index cab27ec31..000000000 --- a/assets/images/seed_warning_light.svg +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/send.png b/assets/images/send.png new file mode 100644 index 000000000..aef504999 Binary files /dev/null and b/assets/images/send.png differ diff --git a/assets/images/send2.png b/assets/images/send2.png deleted file mode 100644 index 85fc570a8..000000000 Binary files a/assets/images/send2.png and /dev/null differ diff --git a/assets/images/swap.png b/assets/images/swap.png deleted file mode 100644 index fe3fc0893..000000000 Binary files a/assets/images/swap.png and /dev/null differ diff --git a/assets/images/tor_logo.svg b/assets/images/tor_logo.svg deleted file mode 100644 index ebd00324d..000000000 --- a/assets/images/tor_logo.svg +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/usdtbsc_icon.png b/assets/images/usdtbsc_icon.png deleted file mode 100644 index 9f2cda237..000000000 Binary files a/assets/images/usdtbsc_icon.png and /dev/null differ diff --git a/assets/images/wallet_group_bright.png b/assets/images/wallet_group_bright.png new file mode 100644 index 000000000..263361db6 Binary files /dev/null and b/assets/images/wallet_group_bright.png differ diff --git a/assets/images/wallet_group_confirmed_dark.png b/assets/images/wallet_group_confirmed_dark.png deleted file mode 100644 index a047cb29c..000000000 Binary files a/assets/images/wallet_group_confirmed_dark.png and /dev/null differ diff --git a/assets/images/wallet_group_confirmed_light.png b/assets/images/wallet_group_confirmed_light.png deleted file mode 100644 index 851d32300..000000000 Binary files a/assets/images/wallet_group_confirmed_light.png and /dev/null differ diff --git a/assets/images/wallet_group_dark.png b/assets/images/wallet_group_dark.png new file mode 100644 index 000000000..7cd08d2cd Binary files /dev/null and b/assets/images/wallet_group_dark.png differ diff --git a/assets/images/wallet_group_empty_dark.png b/assets/images/wallet_group_empty_dark.png deleted file mode 100644 index e613d876e..000000000 Binary files a/assets/images/wallet_group_empty_dark.png and /dev/null differ diff --git a/assets/images/wallet_group_empty_light.png b/assets/images/wallet_group_empty_light.png deleted file mode 100644 index f795648ae..000000000 Binary files a/assets/images/wallet_group_empty_light.png and /dev/null differ diff --git a/assets/images/wallet_group_light.png b/assets/images/wallet_group_light.png new file mode 100644 index 000000000..7827971e7 Binary files /dev/null and b/assets/images/wallet_group_light.png differ diff --git a/assets/images/wallet_group_options_dark.png b/assets/images/wallet_group_options_dark.png deleted file mode 100644 index 479aac57c..000000000 Binary files a/assets/images/wallet_group_options_dark.png and /dev/null differ diff --git a/assets/images/wallet_group_options_light.png b/assets/images/wallet_group_options_light.png deleted file mode 100644 index 308930520..000000000 Binary files a/assets/images/wallet_group_options_light.png and /dev/null differ diff --git a/assets/images/wallet_name.png b/assets/images/wallet_name.png new file mode 100644 index 000000000..f586682bd Binary files /dev/null and b/assets/images/wallet_name.png differ diff --git a/assets/images/wallet_name_light.png b/assets/images/wallet_name_light.png new file mode 100644 index 000000000..0199c1b30 Binary files /dev/null and b/assets/images/wallet_name_light.png differ diff --git a/assets/images/wallet_type.png b/assets/images/wallet_type.png new file mode 100644 index 000000000..4e0eba8b5 Binary files /dev/null and b/assets/images/wallet_type.png differ diff --git a/assets/images/wallet_type_light.png b/assets/images/wallet_type_light.png new file mode 100644 index 000000000..e36c0d3aa Binary files /dev/null and b/assets/images/wallet_type_light.png differ diff --git a/assets/images/wallet_type_wallet_dark.png b/assets/images/wallet_type_wallet_dark.png deleted file mode 100644 index b840f5547..000000000 Binary files a/assets/images/wallet_type_wallet_dark.png and /dev/null differ diff --git a/assets/images/wallet_type_wallet_light.png b/assets/images/wallet_type_wallet_light.png deleted file mode 100644 index ee759a109..000000000 Binary files a/assets/images/wallet_type_wallet_light.png and /dev/null differ diff --git a/assets/images/wallets.png b/assets/images/wallets.png deleted file mode 100644 index 62ea20039..000000000 Binary files a/assets/images/wallets.png and /dev/null differ diff --git a/assets/images/welcome.png b/assets/images/welcome.png new file mode 100644 index 000000000..f1132d253 Binary files /dev/null and b/assets/images/welcome.png differ diff --git a/assets/images/welcome_dark_theme.svg b/assets/images/welcome_dark_theme.svg deleted file mode 100644 index 8f60c931a..000000000 --- a/assets/images/welcome_dark_theme.svg +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/welcome_light.png b/assets/images/welcome_light.png new file mode 100644 index 000000000..6feff85d1 Binary files /dev/null and b/assets/images/welcome_light.png differ diff --git a/assets/images/welcome_light_theme.svg b/assets/images/welcome_light_theme.svg deleted file mode 100644 index 178b2853d..000000000 --- a/assets/images/welcome_light_theme.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/assets/images/welcome_wallet_dark.png b/assets/images/welcome_wallet_dark.png deleted file mode 100644 index 771a600d3..000000000 Binary files a/assets/images/welcome_wallet_dark.png and /dev/null differ diff --git a/assets/images/welcome_wallet_light.png b/assets/images/welcome_wallet_light.png deleted file mode 100644 index 2a738be0b..000000000 Binary files a/assets/images/welcome_wallet_light.png and /dev/null differ diff --git a/assets/images/wyre-icon.png b/assets/images/wyre-icon.png new file mode 100644 index 000000000..a2810948e Binary files /dev/null and b/assets/images/wyre-icon.png differ diff --git a/assets/images/wyre.png b/assets/images/wyre.png new file mode 100644 index 000000000..a16bbdc8b Binary files /dev/null and b/assets/images/wyre.png differ diff --git a/assets/images/xoswap.svg b/assets/images/xoswap.svg deleted file mode 100644 index ef83c58b1..000000000 --- a/assets/images/xoswap.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/yat_crypto.png b/assets/images/yat_crypto.png new file mode 100644 index 000000000..fbd5d2483 Binary files /dev/null and b/assets/images/yat_crypto.png differ diff --git a/assets/nano_node_list.yml b/assets/nano_node_list.yml index cda931b5e..be550177e 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/node_list.yml b/assets/node_list.yml index 917dadfd9..49cc00a94 100644 --- a/assets/node_list.yml +++ b/assets/node_list.yml @@ -13,3 +13,9 @@ - uri: nodes.hashvault.pro:18081 is_default: false +- + uri: node.c3pool.com:18081 + is_default: false +- + uri: node.community.rino.io:18081 + is_default: false diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt index faf57258a..011435baa 100644 --- a/assets/text/Monerocom_Release_Notes.txt +++ b/assets/text/Monerocom_Release_Notes.txt @@ -1,4 +1,3 @@ -Add built-in Tor support (experimental) -Ledger improvements -UI/UX improvements +Ledger fixes +UI enhancements Bug fixes \ No newline at end of file diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt index c49b895e3..ca69e0b98 100644 --- a/assets/text/Release_Notes.txt +++ b/assets/text/Release_Notes.txt @@ -1,9 +1,5 @@ -Add built-in Tor support (experimental) -Add dEuro investments -Solana fixes/enhancements -Polygon fixes/enhancements -WalletConnect improvements -Ledger improvements -Payjoin improvements -UI/UX improvements +Zano enhancements +Ethereum enhancements +Ledger fixes +UI enhancements Bug fixes \ No newline at end of file diff --git a/build-guide-linux.md b/build-guide-linux.md new file mode 100644 index 000000000..df5f0f601 --- /dev/null +++ b/build-guide-linux.md @@ -0,0 +1,176 @@ +# Building CakeWallet for Linux + +## Requirements and Setup + +The following are the system requirements to build CakeWallet for your Linux device. + +``` +Ubuntu >= 16.04 +Flutter 3.10.x +``` + +## Building CakeWallet on Linux + +These steps will help you configure and execute a build of CakeWallet from its source code. + +### 1. Installing Package Dependencies + +CakeWallet requires some packages to be installed on your build system. You may easily install them on your build system with the following command: + +`$ sudo apt install build-essential cmake pkg-config git curl autoconf libtool` + +> [!WARNING] +> +> ### Check gcc version +> +> It is needed to use gcc 10 or 9 to successfully link dependencies with flutter.\ +> To check what gcc version you are using: +> +> ```bash +> $ gcc --version +> $ g++ --version +> ``` +> +> If you are using gcc version newer than 10, then you need to downgrade to version 10.4.0: +> +> ```bash +> $ sudo apt install gcc-10 g++-10 +> $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10 +> $ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10 +> ``` + +> [!NOTE] +> +> Alternatively, you can use the [nix-shell](https://nixos.org/) with the `gcc10.nix` file\ +> present on `scripts/linux` like so: +> ```bash +> $ nix-shell gcc10.nix +> ``` +> This will get you in a nix environment with all the required dependencies that you can use to build the software from,\ +> and it works in any linux distro. + +### 2. Installing Flutter + +Need to install flutter. For this please check section [How to install flutter on Linux](https://docs.flutter.dev/get-started/install/linux). + +### 3. Verify Installations + +Verify that the Flutter has been correctly installed on your system with the following command: + +`$ flutter doctor` + +The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding. + +``` +Doctor summary (to see all details, run flutter doctor -v): +[✓] Flutter (Channel stable, 3.10.x, on Linux, locale en_US.UTF-8) +``` + +### 4. Acquiring the CakeWallet Source Code + +Download CakeWallet source code + +`$ git clone https://github.com/cake-tech/cake_wallet.git --branch linux/password-direct-input` + +Proceed into the source code before proceeding with the next steps: + +`$ cd cake_wallet/scripts/linux/` + +To configure some project properties run: + +`$ ./cakewallet.sh` + +Build the Monero libraries and their dependencies: + +`$ ./build_all.sh` + +Now the dependencies need to be copied into the CakeWallet project with this command: + +`$ ./setup.sh` + +It is now time to change back to the base directory of the CakeWallet source code: + +`$ cd ../../` + +Install Flutter package dependencies with this command: + +`$ flutter pub get` + +> #### If you will get an error like: +> +> ``` +> The plugin `cw_shared_external` requires your app to be migrated to the Android embedding v2. Follow the steps on the migration doc above and re-run +> this command. +> ``` +> +> Then need to config Android project settings. For this open `scripts/android` (`$ cd scripts/android`) directory and run followed commands: +> +> ``` +> $ source ./app_env.sh cakewallet +> $ ./app_config.sh +> $ cd ../.. +> ``` +> +> Then re-configure Linux project again. For this open `scripts/linux` (`$cd scripts/linux`) directory and run: +> `$ ./cakewallet.sh` +> and back to project root directory: +> `$ cd ../..` +> and fetch dependencies again +> `$ flutter pub get` + +Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command: + +`$ dart run tool/generate_new_secrets.dart` + +We will generate mobx models for the project. + +`$ ./model_generator.sh` + +Then we need to generate localization files. + +`$ dart run tool/generate_localization.dart` + +### 5. Build! + +`$ flutter build linux --release` + +Path to executable file will be: + +`build/linux/x64/release/bundle/cake_wallet` + +> ### Troubleshooting +> +> If you got an error while building the application with `$ flutter build linux --release` command, add `-v` argument to the command (`$ flutter build linux -v --release`) to get details.\ +> If you got in flutter build logs: undefined reference to `hid_free_enumeration`, or another error with undefined reference to `hid_*`, then rebuild monero lib without hidapi lib. Check does exists `libhidapi-dev` in your scope and remove it from your scope for build without it. + +# Flatpak + +For package the built application into flatpak you need firstly to install `flatpak` and `flatpak-builder`: + +`$ sudo apt install flatpak flatpak-builder` + +Then need to [add flathub](https://flatpak.org/setup/Ubuntu) (or just `$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`). Then need to install freedesktop runtime and sdk: + +`$ flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08` + +To build with using of `flatpak-build` directory run next: + +`$ flatpak-builder --force-clean flatpak-build com.cakewallet.CakeWallet.yml` + +And then export bundle: + +`$ flatpak build-export export flatpak-build` + +`$ flatpak build-bundle export cake_wallet.flatpak com.cakewallet.CakeWallet` + +Result file: `cake_wallet.flatpak` should be generated in the current directory. + +For install generated flatpak file use: + +`$ flatpak --user install cake_wallet.flatpak` + +For run the installed application run: + +`$ flatpak run com.cakewallet.CakeWallet` + +Copyright (c) 2023 Cake Technologies LLC. diff --git a/build-guide-win.md b/build-guide-win.md new file mode 100644 index 000000000..8cfd02c4c --- /dev/null +++ b/build-guide-win.md @@ -0,0 +1,38 @@ +# Building CakeWallet for Windows + +## Requirements and Setup + +The following are the system requirements to build CakeWallet for your Windows PC. + +``` +Windows 10 or later (64-bit), x86-64 based +Flutter 3 or above +``` + +## Building CakeWallet on Windows + +These steps will help you configure and execute a build of CakeWallet from its source code. + +### 1. Installing Package Dependencies + +For build CakeWallet windows application from sources you will be needed to have: +> [Install Flutter]Follow installation guide (https://docs.flutter.dev/get-started/install/windows) and install do not miss to dev tools (install https://docs.flutter.dev/get-started/install/windows/desktop#development-tools) which are required for windows desktop development (need to install Git for Windows and Visual Studio 2022). Then install `Desktop development with C++` packages via GUI Visual Studio 2022, or Visual Studio Build Tools 2022 including: `C++ Build Tools core features`, `C++ 2022 Redistributable Update`, `C++ core desktop features`, `MVC v143 - VS 2022 C++ x64/x86 build tools`, `C++ CMake tools for Windows`, `Testing tools core features - Build Tools`, `C++ AddressSanitizer`. +> [Install WSL] for building monero dependencies need to install Windows WSL (https://learn.microsoft.com/en-us/windows/wsl/install) and required packages for WSL (Ubuntu): +`$ sudo apt update ` +`$ sudo apt build-essential cmake gcc-mingw-w64 g++-mingw-w64 autoconf libtool pkg-config` + +### 2. Pull CakeWallet source code + +You can download CakeWallet source code from our [GitHub repository](github.com/cake-tech/cake_wallet) via git by following next command: +`$ git clone https://github.com/cake-tech/cake_wallet.git --branch MrCyjaneK-cyjan-monerodart` +OR you can download it as [Zip archive](https://github.com/cake-tech/cake_wallet/archive/refs/heads/MrCyjaneK-cyjan-monerodart.zip) + +### 3. Build Monero, Monero_c and their dependencies + +For use monero in the application need to build Monero wrapper - Monero_C which will be used by monero.dart package. For that need to run shell (bash - typically same named utility should be available after WSL is enabled in your system) with previously installed WSL, then change current directory to the application project directory with your used shell and then change current directory to `scripts/windows`: `$ cd scripts/windows`. Run build script: `$ ./build_all.sh`. + +### 4. Configure and build CakeWallet application + +To configure the application open directory where you have downloaded or unarchived CakeWallet sources and run `cakewallet.bat`. +Or if you used WSL and have active shell session you can run `$ ./cakewallet.sh` script in `scripts/windows` which will run `cakewallet.bat` in WSL. +After execution of `cakewallet.bat` you should to get `Cake Wallet.zip` in project root directory which will contains `CakeWallet.exe` file and another needed files for run the application. Now you can extract files from `Cake Wallet.zip` archive and run the application. diff --git a/com.cakewallet.CakeWallet.yml b/com.cakewallet.CakeWallet.yml index 6a19c3dda..83efa1388 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: '24.08' +runtime-version: '22.08' sdk: org.freedesktop.Sdk command: cake_wallet separate-locales: false @@ -15,6 +15,8 @@ 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" diff --git a/cw_bitcoin/lib/address_from_output.dart b/cw_bitcoin/lib/address_from_output.dart index 0d985b237..73bc101c4 100644 --- a/cw_bitcoin/lib/address_from_output.dart +++ b/cw_bitcoin/lib/address_from_output.dart @@ -2,37 +2,22 @@ import 'package:bitcoin_base/bitcoin_base.dart'; String addressFromOutputScript(Script script, BasedUtxoNetwork network) { try { - return addressFromScript(script, network).toAddress(network); + switch (script.getAddressType()) { + case P2pkhAddressType.p2pkh: + return P2pkhAddress.fromScriptPubkey(script: script).toAddress(network); + case P2shAddressType.p2pkInP2sh: + return P2shAddress.fromScriptPubkey(script: script).toAddress(network); + case SegwitAddresType.p2wpkh: + return P2wpkhAddress.fromScriptPubkey(script: script).toAddress(network); + case P2shAddressType.p2pkhInP2sh: + return P2shAddress.fromScriptPubkey(script: script).toAddress(network); + case SegwitAddresType.p2wsh: + return P2wshAddress.fromScriptPubkey(script: script).toAddress(network); + case SegwitAddresType.p2tr: + return P2trAddress.fromScriptPubkey(script: script).toAddress(network); + default: + } } catch (_) {} return ''; } - -BitcoinBaseAddress addressFromScript(Script script, - [BasedUtxoNetwork network = BitcoinNetwork.mainnet]) { - final addressType = script.getAddressType(); - if (addressType == null) { - throw ArgumentError("Invalid script"); - } - - switch (addressType) { - case P2pkhAddressType.p2pkh: - return P2pkhAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); - case P2shAddressType.p2pkhInP2sh: - case P2shAddressType.p2pkInP2sh: - return P2shAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); - case SegwitAddresType.p2wpkh: - return P2wpkhAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); - case SegwitAddresType.p2wsh: - return P2wshAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); - case SegwitAddresType.p2tr: - return P2trAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); - } - - throw ArgumentError("Invalid script"); -} diff --git a/cw_bitcoin/lib/bitcoin_address_record.dart b/cw_bitcoin/lib/bitcoin_address_record.dart index 1509f913a..7e4b5f58f 100644 --- a/cw_bitcoin/lib/bitcoin_address_record.dart +++ b/cw_bitcoin/lib/bitcoin_address_record.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'package:mobx/mobx.dart'; import 'package:bitcoin_base/bitcoin_base.dart'; @@ -17,7 +16,7 @@ abstract class BaseBitcoinAddressRecord { }) : _txCount = txCount, _balance = balance, _name = name, - _isUsed = Observable(isUsed); + _isUsed = isUsed; @override bool operator ==(Object o) => o is BaseBitcoinAddressRecord && address == o.address; @@ -28,7 +27,7 @@ abstract class BaseBitcoinAddressRecord { int _txCount; int _balance; String _name; - final Observable _isUsed; + bool _isUsed; BasedUtxoNetwork? network; int get txCount => _txCount; @@ -41,9 +40,9 @@ abstract class BaseBitcoinAddressRecord { set balance(int value) => _balance = value; - bool get isUsed => _isUsed.value; + bool get isUsed => _isUsed; - void setAsUsed() => _isUsed.value = true; + void setAsUsed() => _isUsed = true; void setNewName(String label) => _name = label; int get hashCode => address.hashCode; diff --git a/cw_bitcoin/lib/bitcoin_transaction_credentials.dart b/cw_bitcoin/lib/bitcoin_transaction_credentials.dart index 7d6894e14..01e905fb0 100644 --- a/cw_bitcoin/lib/bitcoin_transaction_credentials.dart +++ b/cw_bitcoin/lib/bitcoin_transaction_credentials.dart @@ -3,17 +3,11 @@ import 'package:cw_core/output_info.dart'; import 'package:cw_core/unspent_coin_type.dart'; class BitcoinTransactionCredentials { - BitcoinTransactionCredentials( - this.outputs, { - required this.priority, - this.feeRate, - this.coinTypeToSpendFrom = UnspentCoinType.any, - this.payjoinUri, - }); + BitcoinTransactionCredentials(this.outputs, + {required this.priority, this.feeRate, this.coinTypeToSpendFrom = UnspentCoinType.any}); final List outputs; final BitcoinTransactionPriority? priority; final int? feeRate; final UnspentCoinType coinTypeToSpendFrom; - final String? payjoinUri; } diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart index 9231022f6..908897845 100644 --- a/cw_bitcoin/lib/bitcoin_wallet.dart +++ b/cw_bitcoin/lib/bitcoin_wallet.dart @@ -3,33 +3,22 @@ import 'dart:convert'; import 'package:bip39/bip39.dart' as bip39; import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:blockchain_utils/blockchain_utils.dart'; -import 'package:cw_bitcoin/address_from_output.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; -import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart'; +import 'package:cw_bitcoin/psbt_transaction_builder.dart'; +import 'package:cw_core/encryption_file_utils.dart'; +import 'package:cw_bitcoin/electrum_derivations.dart'; import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart'; import 'package:cw_bitcoin/electrum_balance.dart'; -import 'package:cw_bitcoin/electrum_derivations.dart'; import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/electrum_wallet_snapshot.dart'; -import 'package:cw_bitcoin/payjoin/manager.dart'; -import 'package:cw_bitcoin/payjoin/storage.dart'; -import 'package:cw_bitcoin/pending_bitcoin_transaction.dart'; -import 'package:cw_bitcoin/psbt/signer.dart'; -import 'package:cw_bitcoin/psbt/transaction_builder.dart'; -import 'package:cw_bitcoin/psbt/v0_deserialize.dart'; -import 'package:cw_bitcoin/psbt/v0_finalizer.dart'; import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/encryption_file_utils.dart'; -import 'package:cw_core/payjoin_session.dart'; -import 'package:cw_core/pending_transaction.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_keys_file.dart'; import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; import 'package:ledger_bitcoin/ledger_bitcoin.dart'; -import 'package:ledger_bitcoin/psbt.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; import 'package:mobx/mobx.dart'; @@ -42,7 +31,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { required String password, required WalletInfo walletInfo, required Box unspentCoinsInfo, - required Box payjoinBox, required EncryptionFileUtils encryptionFileUtils, Uint8List? seedBytes, String? mnemonic, @@ -83,21 +71,20 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { // String derivationPath = walletInfo.derivationInfo!.derivationPath!; // String sideDerivationPath = derivationPath.substring(0, derivationPath.length - 1) + "1"; // final hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType); - - payjoinManager = PayjoinManager(PayjoinStorage(payjoinBox), this); - walletAddresses = BitcoinWalletAddresses(walletInfo, - initialAddresses: initialAddresses, - initialRegularAddressIndex: initialRegularAddressIndex, - initialChangeAddressIndex: initialChangeAddressIndex, - initialSilentAddresses: initialSilentAddresses, - initialSilentAddressIndex: initialSilentAddressIndex, - mainHd: hd, - sideHd: accountHD.childKey(Bip32KeyIndex(1)), - network: networkParam ?? network, - masterHd: - seedBytes != null ? Bip32Slip10Secp256k1.fromSeed(seedBytes) : null, - isHardwareWallet: walletInfo.isHardwareWallet, - payjoinManager: payjoinManager); + walletAddresses = BitcoinWalletAddresses( + walletInfo, + initialAddresses: initialAddresses, + initialRegularAddressIndex: initialRegularAddressIndex, + initialChangeAddressIndex: initialChangeAddressIndex, + initialSilentAddresses: initialSilentAddresses, + initialSilentAddressIndex: initialSilentAddressIndex, + mainHd: hd, + sideHd: accountHD.childKey(Bip32KeyIndex(1)), + network: networkParam ?? network, + masterHd: + seedBytes != null ? Bip32Slip10Secp256k1.fromSeed(seedBytes) : null, + isHardwareWallet: walletInfo.isHardwareWallet, + ); autorun((_) { this.walletAddresses.isEnabledAutoGenerateSubaddress = @@ -105,15 +92,11 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { }); } - @override - bool get hasRescan => true; - static Future create({ required String mnemonic, required String password, required WalletInfo walletInfo, required Box unspentCoinsInfo, - required Box payjoinBox, required EncryptionFileUtils encryptionFileUtils, String? passphrase, String? addressPageType, @@ -136,11 +119,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { break; case DerivationType.electrum: default: - seedBytes = - await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? ""); + seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? ""); break; } - return BitcoinWallet( mnemonic: mnemonic, passphrase: passphrase ?? "", @@ -157,7 +138,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { initialChangeAddressIndex: initialChangeAddressIndex, addressPageType: addressPageType, networkParam: network, - payjoinBox: payjoinBox, ); } @@ -165,7 +145,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { required String name, required WalletInfo walletInfo, required Box unspentCoinsInfo, - required Box payjoinBox, required String password, required EncryptionFileUtils encryptionFileUtils, required bool alwaysScan, @@ -222,8 +201,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { if (mnemonic != null) { switch (walletInfo.derivationInfo!.derivationType) { case DerivationType.electrum: - seedBytes = - await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? ""); + seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? ""); break; case DerivationType.bip39: default: @@ -236,24 +214,24 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { } return BitcoinWallet( - mnemonic: mnemonic, - xpub: keysData.xPub, - password: password, - passphrase: passphrase, - walletInfo: walletInfo, - unspentCoinsInfo: unspentCoinsInfo, - initialAddresses: snp?.addresses, - initialSilentAddresses: snp?.silentAddresses, - initialSilentAddressIndex: snp?.silentAddressIndex ?? 0, - initialBalance: snp?.balance, - encryptionFileUtils: encryptionFileUtils, - seedBytes: seedBytes, - initialRegularAddressIndex: snp?.regularAddressIndex, - initialChangeAddressIndex: snp?.changeAddressIndex, - addressPageType: snp?.addressPageType, - networkParam: network, - alwaysScan: alwaysScan, - payjoinBox: payjoinBox); + mnemonic: mnemonic, + xpub: keysData.xPub, + password: password, + passphrase: passphrase, + walletInfo: walletInfo, + unspentCoinsInfo: unspentCoinsInfo, + initialAddresses: snp?.addresses, + initialSilentAddresses: snp?.silentAddresses, + initialSilentAddressIndex: snp?.silentAddressIndex ?? 0, + initialBalance: snp?.balance, + encryptionFileUtils: encryptionFileUtils, + seedBytes: seedBytes, + initialRegularAddressIndex: snp?.regularAddressIndex, + initialChangeAddressIndex: snp?.changeAddressIndex, + addressPageType: snp?.addressPageType, + networkParam: network, + alwaysScan: alwaysScan, + ); } LedgerConnection? _ledgerConnection; @@ -267,30 +245,19 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { } @override - Future close({bool shouldCleanup = false}) async { - payjoinManager.cleanupSessions(); - super.close(shouldCleanup: shouldCleanup); - } - - late final PayjoinManager payjoinManager; - - bool get isPayjoinAvailable => unspentCoinsInfo.values - .where((element) => - element.walletId == id && element.isSending && !element.isFrozen) - .isNotEmpty; - - Future buildPsbt({ + Future buildHardwareWalletTransaction({ required List outputs, required BigInt fee, required BasedUtxoNetwork network, required List utxos, required Map publicKeys, - required Uint8List masterFingerprint, String? memo, bool enableRBF = false, BitcoinOrdering inputOrdering = BitcoinOrdering.bip69, BitcoinOrdering outputOrdering = BitcoinOrdering.bip69, }) async { + final masterFingerprint = await _bitcoinLedgerApp!.getMasterFingerprint(); + final psbtReadyInputs = []; for (final utxo in utxos) { final rawTx = @@ -308,128 +275,13 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { )); } - return PSBTTransactionBuild( - inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF) - .psbt; - } + final psbt = PSBTTransactionBuild( + inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF); - @override - Future buildHardwareWalletTransaction({ - required List outputs, - required BigInt fee, - required BasedUtxoNetwork network, - required List utxos, - required Map publicKeys, - String? memo, - bool enableRBF = false, - BitcoinOrdering inputOrdering = BitcoinOrdering.bip69, - BitcoinOrdering outputOrdering = BitcoinOrdering.bip69, - }) async { - final masterFingerprint = await _bitcoinLedgerApp!.getMasterFingerprint(); - - final psbt = await buildPsbt( - outputs: outputs, - fee: fee, - network: network, - utxos: utxos, - publicKeys: publicKeys, - masterFingerprint: masterFingerprint, - memo: memo, - enableRBF: enableRBF, - inputOrdering: inputOrdering, - outputOrdering: outputOrdering, - ); - - final rawHex = await _bitcoinLedgerApp!.signPsbt(psbt: psbt); + final rawHex = await _bitcoinLedgerApp!.signPsbt(psbt: psbt.psbt); return BtcTransaction.fromRaw(BytesUtils.toHexString(rawHex)); } - @override - Future createTransaction(Object credentials) async { - credentials = credentials as BitcoinTransactionCredentials; - - final tx = (await super.createTransaction(credentials)) - as PendingBitcoinTransaction; - - final payjoinUri = credentials.payjoinUri; - if (payjoinUri == null) return tx; - - final transaction = await buildPsbt( - utxos: tx.utxos, - outputs: tx.outputs - .map((e) => BitcoinOutput( - address: addressFromScript(e.scriptPubKey), - value: e.amount, - isSilentPayment: e.isSilentPayment, - isChange: e.isChange, - )) - .toList(), - fee: BigInt.from(tx.fee), - network: network, - memo: credentials.outputs.first.memo, - outputOrdering: BitcoinOrdering.none, - enableRBF: true, - publicKeys: tx.publicKeys!, - masterFingerprint: Uint8List(0)); - - final originalPsbt = await signPsbt( - base64.encode(transaction.asPsbtV0()), getUtxoWithPrivateKeys()); - - tx.commitOverride = () async { - final sender = await payjoinManager.initSender( - payjoinUri, originalPsbt, int.parse(tx.feeRate)); - payjoinManager.spawnNewSender( - sender: sender, pjUrl: payjoinUri, amount: BigInt.from(tx.amount)); - }; - - return tx; - } - - List getUtxoWithPrivateKeys() => unspentCoins - .where((e) => (e.isSending && !e.isFrozen)) - .map((unspent) => UtxoWithPrivateKey.fromUnspent(unspent, this)) - .toList(); - - Future commitPsbt(String finalizedPsbt) { - final psbt = PsbtV2()..deserializeV0(base64.decode(finalizedPsbt)); - - final btcTx = - BtcTransaction.fromRaw(BytesUtils.toHexString(psbt.extract())); - - return PendingBitcoinTransaction( - btcTx, - type, - electrumClient: electrumClient, - amount: 0, - fee: 0, - feeRate: "", - network: network, - hasChange: true, - ).commit(); - } - - Future signPsbt( - String preProcessedPsbt, List utxos) async { - final psbt = PsbtV2()..deserializeV0(base64Decode(preProcessedPsbt)); - - await psbt.signWithUTXO(utxos, (txDigest, utxo, key, sighash) { - return utxo.utxo.isP2tr() - ? key.signTapRoot( - txDigest, - sighash: sighash, - tweak: utxo.utxo.isSilentPayment != true, - ) - : key.signInput(txDigest, sigHash: sighash); - }, (txId, vout) async { - final txHex = await electrumClient.getTransactionHex(hash: txId); - final output = BtcTransaction.fromRaw(txHex).outputs[vout]; - return TaprootAmountScriptPair(output.amount, output.scriptPubKey); - }); - - psbt.finalizeV0(); - return base64Encode(psbt.asPsbtV0()); - } - @override Future signMessage(String message, {String? address = null}) async { if (walletInfo.isHardwareWallet) { diff --git a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart index d84d958be..1a122ef9e 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart @@ -1,13 +1,10 @@ import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:blockchain_utils/bip/bip/bip32/bip32.dart'; import 'package:cw_bitcoin/electrum_wallet_addresses.dart'; -import 'package:cw_bitcoin/payjoin/manager.dart'; import 'package:cw_bitcoin/utils.dart'; import 'package:cw_core/unspent_coin_type.dart'; -import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:mobx/mobx.dart'; -import 'package:payjoin_flutter/receive.dart' as payjoin; part 'bitcoin_wallet_addresses.g.dart'; @@ -20,7 +17,6 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S required super.sideHd, required super.network, required super.isHardwareWallet, - required this.payjoinManager, super.initialAddresses, super.initialRegularAddressIndex, super.initialChangeAddressIndex, @@ -29,13 +25,6 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S super.masterHd, }) : super(walletInfo); - final PayjoinManager payjoinManager; - - payjoin.Receiver? currentPayjoinReceiver; - - @observable - String? payjoinEndpoint = null; - @override String getAddress( {required int index, @@ -56,33 +45,4 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S return generateP2WPKHAddress(hd: hd, index: index, network: network); } - - @action - Future initPayjoin() async { - try { - await payjoinManager.initPayjoin(); - currentPayjoinReceiver = await payjoinManager.getUnusedReceiver(primaryAddress); - payjoinEndpoint = (await currentPayjoinReceiver?.pjUri())?.pjEndpoint(); - - payjoinManager.resumeSessions(); - } catch (e) { - printV(e); - // Ignore Connectivity errors - if (!e.toString().contains("error sending request for url")) rethrow; - } - } - - @action - Future newPayjoinReceiver() async { - try { - currentPayjoinReceiver = await payjoinManager.getUnusedReceiver(primaryAddress); - payjoinEndpoint = (await currentPayjoinReceiver?.pjUri())?.pjEndpoint(); - - payjoinManager.spawnReceiver(receiver: currentPayjoinReceiver!); - } catch (e) { - printV(e); - // Ignore Connectivity errors - if (!e.toString().contains("error sending request for url")) rethrow; - } - } } diff --git a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart index 177d61e87..a1b1418b8 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart @@ -11,11 +11,13 @@ class BitcoinNewWalletCredentials extends WalletCredentials { String? derivationPath, String? passphrase, this.mnemonic, + String? parentAddress, }) : super( name: name, walletInfo: walletInfo, password: password, passphrase: passphrase, + parentAddress: parentAddress, ); final String? mnemonic; diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart index 317b25bcd..7ee1534bf 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_service.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart @@ -5,7 +5,6 @@ import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart'; import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart'; import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart'; import 'package:cw_core/encryption_file_utils.dart'; -import 'package:cw_core/payjoin_session.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_service.dart'; @@ -22,12 +21,10 @@ class BitcoinWalletService extends WalletService< BitcoinRestoreWalletFromSeedCredentials, BitcoinRestoreWalletFromWIFCredentials, BitcoinRestoreWalletFromHardware> { - BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, - this.payjoinSessionSource, this.alwaysScan, this.isDirect); + BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan, this.isDirect); final Box walletInfoSource; final Box unspentCoinsInfoSource; - final Box payjoinSessionSource; final bool alwaysScan; final bool isDirect; @@ -58,7 +55,6 @@ class BitcoinWalletService extends WalletService< passphrase: credentials.passphrase, walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource, - payjoinBox: payjoinSessionSource, network: network, encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); @@ -83,7 +79,6 @@ class BitcoinWalletService extends WalletService< name: name, walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource, - payjoinBox: payjoinSessionSource, alwaysScan: alwaysScan, encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); @@ -97,7 +92,6 @@ class BitcoinWalletService extends WalletService< name: name, walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource, - payjoinBox: payjoinSessionSource, alwaysScan: alwaysScan, encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); @@ -132,7 +126,6 @@ class BitcoinWalletService extends WalletService< name: currentName, walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource, - payjoinBox: payjoinSessionSource, alwaysScan: alwaysScan, encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); @@ -154,6 +147,7 @@ class BitcoinWalletService extends WalletService< credentials.walletInfo?.network = network.value; credentials.walletInfo?.derivationInfo?.derivationPath = credentials.hwAccountData.derivationPath; + final wallet = await BitcoinWallet( password: credentials.password!, xpub: credentials.hwAccountData.xpub, @@ -161,7 +155,6 @@ class BitcoinWalletService extends WalletService< unspentCoinsInfo: unspentCoinsInfoSource, networkParam: network, encryptionFileUtils: encryptionFileUtilsFor(isDirect), - payjoinBox: payjoinSessionSource, ); await wallet.save(); await wallet.init(); @@ -189,7 +182,6 @@ class BitcoinWalletService extends WalletService< mnemonic: credentials.mnemonic, walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource, - payjoinBox: payjoinSessionSource, network: network, encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart index 2ddd30df6..1f5c369e3 100644 --- a/cw_bitcoin/lib/electrum.dart +++ b/cw_bitcoin/lib/electrum.dart @@ -5,8 +5,6 @@ import 'dart:typed_data'; import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:cw_bitcoin/bitcoin_amount_format.dart'; import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/utils/proxy_socket/abstract.dart'; -import 'package:cw_core/utils/proxy_wrapper.dart'; import 'package:flutter/foundation.dart'; import 'package:rxdart/rxdart.dart'; @@ -44,7 +42,7 @@ class ElectrumClient { static const aliveTimerDuration = Duration(seconds: 4); bool get isConnected => _isConnected; - ProxySocket? socket; + Socket? socket; void Function(ConnectionStatus)? onConnectionStatusChange; int _id; final Map _tasks; @@ -74,11 +72,18 @@ class ElectrumClient { } catch (_) {} socket = null; - final ssl = !(useSSL == false || (useSSL == null && uri.toString().contains("btc-electrum"))); try { - socket = await ProxyWrapper().getSocksSocket(ssl, host, port, connectionTimeout: connectionTimeout); + if (useSSL == false || (useSSL == null && uri.toString().contains("btc-electrum"))) { + socket = await Socket.connect(host, port, timeout: connectionTimeout); + } else { + socket = await SecureSocket.connect( + host, + port, + timeout: connectionTimeout, + onBadCertificate: (_) => true, + ); + } } catch (e) { - printV("connect: $e"); if (e is HandshakeException) { useSSL = !(useSSL ?? false); } @@ -100,6 +105,7 @@ class ElectrumClient { // use ping to determine actual connection status since we could've just not timed out yet: // _setConnectionStatus(ConnectionStatus.connected); + socket!.listen( (Uint8List event) { try { diff --git a/cw_bitcoin/lib/electrum_balance.dart b/cw_bitcoin/lib/electrum_balance.dart index aeb06f1f0..37c34058b 100644 --- a/cw_bitcoin/lib/electrum_balance.dart +++ b/cw_bitcoin/lib/electrum_balance.dart @@ -65,6 +65,6 @@ class ElectrumBalance extends Balance { 'unconfirmed': unconfirmed, 'frozen': frozen, 'secondConfirmed': secondConfirmed, - 'secondUnconfirmed': secondUnconfirmed, + 'secondUnconfirmed': secondUnconfirmed }); } diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index bb9cea1bc..e7b8be156 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -4,9 +4,6 @@ import 'dart:io'; import 'dart:isolate'; import 'package:bitcoin_base/bitcoin_base.dart'; -import 'package:cw_core/utils/proxy_wrapper.dart'; -import 'package:cw_bitcoin/bitcoin_amount_format.dart'; -import 'package:cw_core/format_amount.dart'; import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_bitcoin/bitcoin_wallet.dart'; import 'package:cw_bitcoin/litecoin_wallet.dart'; @@ -50,6 +47,7 @@ import 'package:mobx/mobx.dart'; import 'package:rxdart/subjects.dart'; import 'package:sp_scanner/sp_scanner.dart'; import 'package:hex/hex.dart'; +import 'package:http/http.dart' as http; part 'electrum_wallet.g.dart'; @@ -493,9 +491,10 @@ abstract class ElectrumWalletBase Future updateFeeRates() async { if (await checkIfMempoolAPIIsEnabled() && type == WalletType.bitcoin) { try { - final response = await ProxyWrapper() - .get(clearnetUri: Uri.parse("https://mempool.cakewallet.com/api/v1/fees/recommended")) - .timeout(Duration(seconds: 15)); + final response = await http + .get(Uri.parse("https://mempool.cakewallet.com/api/v1/fees/recommended")) + .timeout(Duration(seconds: 5)); + final result = json.decode(response.body) as Map; final slowFee = (result['economyFee'] as num?)?.toInt() ?? 0; int mediumFee = (result['hourFee'] as num?)?.toInt() ?? 0; @@ -633,8 +632,8 @@ abstract class ElectrumWalletBase }).toList(); final unconfirmedCoins = availableInputs.where((utx) => utx.confirmations == 0).toList(); - // sort the unconfirmed coins so that mweb coins are last: - availableInputs.sort((a, b) => a.bitcoinAddressRecord.type == SegwitAddresType.mweb ? 1 : -1); + // sort the unconfirmed coins so that mweb coins are first: + availableInputs.sort((a, b) => a.bitcoinAddressRecord.type == SegwitAddresType.mweb ? -1 : 1); for (int i = 0; i < availableInputs.length; i++) { final utx = availableInputs[i]; @@ -916,10 +915,6 @@ abstract class ElectrumWalletBase } } - // if the amount left for change is less than dust, but not less than 0 - // then add it to the fees - fee += amountLeftForChange; - return EstimatedTxResult( utxos: utxoDetails.utxos, inputPrivKeyInfos: utxoDetails.inputPrivKeyInfos, @@ -1175,18 +1170,19 @@ abstract class ElectrumWalletBase } }); - return PendingBitcoinTransaction(transaction, type, - electrumClient: electrumClient, - amount: estimatedTx.amount, - fee: estimatedTx.fee, - feeRate: feeRateInt.toString(), - network: network, - hasChange: estimatedTx.hasChange, - isSendAll: estimatedTx.isSendAll, - hasTaprootInputs: hasTaprootInputs, - utxos: estimatedTx.utxos, - publicKeys: estimatedTx.publicKeys) - ..addListener((transaction) async { + return PendingBitcoinTransaction( + transaction, + type, + electrumClient: electrumClient, + amount: estimatedTx.amount, + fee: estimatedTx.fee, + feeRate: feeRateInt.toString(), + network: network, + hasChange: estimatedTx.hasChange, + isSendAll: estimatedTx.isSendAll, + hasTaprootInputs: hasTaprootInputs, + utxos: estimatedTx.utxos, + )..addListener((transaction) async { transactionHistory.addOne(transaction); if (estimatedTx.spendsSilentPayment) { transactionHistory.transactions.values.forEach((tx) { @@ -1370,7 +1366,7 @@ abstract class ElectrumWalletBase List updatedUnspentCoins = []; final previousUnspentCoins = List.from(unspentCoins.where((utxo) => - utxo.bitcoinAddressRecord.type != SegwitAddresType.mweb && + utxo.bitcoinAddressRecord.type != SegwitAddresType.mweb && utxo.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)); if (hasSilentPaymentsScanning) { @@ -1428,6 +1424,7 @@ abstract class ElectrumWalletBase required List updatedUnspentCoins, required List?> results, }) { + if (failedCount == results.length) { printV("All UTXOs failed to fetch, falling back to previous UTXOs"); return previousUnspentCoins; @@ -1877,17 +1874,20 @@ abstract class ElectrumWalletBase if (height != null && height > 0 && await checkIfMempoolAPIIsEnabled()) { try { - final blockHash = await ProxyWrapper() - .get(clearnetUri: Uri.parse("https://mempool.cakewallet.com/api/v1/block-height/$height")) - .timeout(Duration(seconds: 15)); + final blockHash = await http.get( + Uri.parse( + "https://mempool.cakewallet.com/api/v1/block-height/$height", + ), + ); if (blockHash.statusCode == 200 && blockHash.body.isNotEmpty && jsonDecode(blockHash.body) != null) { - final blockResponse = await ProxyWrapper() - .get(clearnetUri: Uri.parse("https://mempool.cakewallet.com/api/v1/block/${blockHash}")) - .timeout(Duration(seconds: 15)); - + final blockResponse = await http.get( + Uri.parse( + "https://mempool.cakewallet.com/api/v1/block/${blockHash.body}", + ), + ); if (blockResponse.statusCode == 200 && blockResponse.body.isNotEmpty && jsonDecode(blockResponse.body)['timestamp'] != null) { @@ -1960,11 +1960,6 @@ abstract class ElectrumWalletBase } } - bool isMine(Script script) { - final derivedAddress = addressFromOutputScript(script, network); - return addressesSet.contains(derivedAddress); - } - @override Future> fetchTransactions() async { try { @@ -2242,11 +2237,10 @@ abstract class ElectrumWalletBase if (element.hash == info.hash && element.vout == info.vout && + info.isFrozen && element.bitcoinAddressRecord.address == info.address && element.value == info.value) { - if (info.isFrozen) { - totalFrozen += element.value; - } + totalFrozen += element.value; } }); }); @@ -2502,12 +2496,6 @@ abstract class ElectrumWalletBase transactionHistory.addOne(tx); } } - - @override - String formatCryptoAmount(String amount) { - final amountInt = int.parse(amount); - return bitcoinAmountToString(amount: amountInt); - } } class ScanNode { diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart index 614a06a3b..35c15e578 100644 --- a/cw_bitcoin/lib/electrum_wallet_addresses.dart +++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart @@ -144,32 +144,27 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { return silentAddress.toString(); } - final typeMatchingAddresses = _addresses.where((addr) => !addr.isHidden && _isAddressPageTypeMatch(addr)).toList(); - final typeMatchingReceiveAddresses = typeMatchingAddresses.where((addr) => !addr.isUsed).toList(); + String receiveAddress; - if (!isEnabledAutoGenerateSubaddress) { - if (previousAddressRecord != null && - previousAddressRecord!.type == addressPageType) { - return previousAddressRecord!.address; + final typeMatchingReceiveAddresses = + receiveAddresses.where(_isAddressPageTypeMatch).where((addr) => !addr.isUsed); + + if ((isEnabledAutoGenerateSubaddress && receiveAddresses.isEmpty) || + typeMatchingReceiveAddresses.isEmpty) { + receiveAddress = generateNewAddress().address; + } else { + final previousAddressMatchesType = + previousAddressRecord != null && previousAddressRecord!.type == addressPageType; + + if (previousAddressMatchesType && + typeMatchingReceiveAddresses.first.address != addressesByReceiveType.first.address) { + receiveAddress = previousAddressRecord!.address; + } else { + receiveAddress = typeMatchingReceiveAddresses.first.address; } - - if (typeMatchingAddresses.isNotEmpty) { - return typeMatchingAddresses.first.address; - } - - return generateNewAddress().address; } - if (typeMatchingAddresses.isEmpty || typeMatchingReceiveAddresses.isEmpty) { - return generateNewAddress().address; - } - - final prev = previousAddressRecord; - if (prev != null && prev.type == addressPageType && !prev.isUsed) { - return prev.address; - } - - return typeMatchingReceiveAddresses.first.address; + return receiveAddress; } @observable diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index 08c56c600..5bd25785f 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:typed_data'; import 'package:convert/convert.dart' as convert; import 'dart:math'; @@ -76,7 +77,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { }) : super( mnemonic: mnemonic, password: password, - passphrase: passphrase, xpub: xpub, walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfo, @@ -155,9 +155,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { @observable SyncStatus mwebSyncStatus = NotConnectedSyncStatus(); - @override - bool get hasRescan => true; - List get scanSecret => mwebHd!.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw; List get spendSecret => mwebHd!.childKey(Bip32KeyIndex(0x80000001)).privateKey.privKey.raw; @@ -329,7 +326,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { try { await subscribeForUpdates(); } catch (e) { - printV("failed to subscribe for updates: $e"); + printV("failed to subcribe for updates: $e"); } updateFeeRates(); _feeRatesTimer?.cancel(); @@ -464,9 +461,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { final oldBox = await CakeHive.openBox(oldBoxName); mwebUtxosBox = await CakeHive.openBox(newBoxName); for (final key in oldBox.keys) { - final value = oldBox.get(key); - await oldBox.delete(key); - await mwebUtxosBox.put(key, value!); + await mwebUtxosBox.put(key, oldBox.get(key)!); } oldBox.deleteFromDisk(); @@ -603,7 +598,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { } _utxoStream = responseStream.listen( (Utxo sUtxo) async { - // we're processing utxos, so our balance could still be inaccurate: + // we're processing utxos, so our balance could still be innacurate: if (mwebSyncStatus is! SyncronizingSyncStatus && mwebSyncStatus is! SyncingSyncStatus) { mwebSyncStatus = SyncronizingSyncStatus(); processingUtxos = true; diff --git a/cw_bitcoin/lib/payjoin/manager.dart b/cw_bitcoin/lib/payjoin/manager.dart deleted file mode 100644 index 95a523d89..000000000 --- a/cw_bitcoin/lib/payjoin/manager.dart +++ /dev/null @@ -1,310 +0,0 @@ -import 'dart:async'; -import 'dart:isolate'; -import 'dart:math'; -import 'dart:typed_data'; - -import 'package:bitcoin_base/bitcoin_base.dart'; -import 'package:cw_bitcoin/bitcoin_wallet.dart'; -import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart'; -import 'package:cw_bitcoin/payjoin/payjoin_persister.dart'; -import 'package:cw_bitcoin/payjoin/payjoin_receive_worker.dart'; -import 'package:cw_bitcoin/payjoin/payjoin_send_worker.dart'; -import 'package:cw_bitcoin/payjoin/payjoin_session_errors.dart'; -import 'package:cw_bitcoin/payjoin/storage.dart'; -import 'package:cw_bitcoin/psbt/signer.dart'; -import 'package:cw_bitcoin/psbt/utils.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:payjoin_flutter/common.dart'; -import 'package:payjoin_flutter/receive.dart'; -import 'package:payjoin_flutter/send.dart'; -import 'package:payjoin_flutter/src/config.dart' as pj_config; -import 'package:payjoin_flutter/uri.dart' as PayjoinUri; - -class PayjoinManager { - PayjoinManager(this._payjoinStorage, this._wallet); - - final PayjoinStorage _payjoinStorage; - final BitcoinWalletBase _wallet; - final Map _activePollers = {}; - - static const List ohttpRelayUrls = [ - 'https://pj.bobspacebkk.com', - 'https://ohttp.achow101.com', - 'https://ohttp.cakewallet.com', - ]; - - static String randomOhttpRelayUrl() => - ohttpRelayUrls[Random.secure().nextInt(ohttpRelayUrls.length)]; - - static const payjoinDirectoryUrl = 'https://payjo.in'; - - Future initPayjoin() => pj_config.PConfig.initializeApp(); - - Future resumeSessions() async { - final allSessions = _payjoinStorage.readAllOpenSessions(_wallet.id); - - final spawnedSessions = allSessions.map((session) { - if (session.isSenderSession) { - printV("Resuming Payjoin Sender Session ${session.pjUri!}"); - return _spawnSender( - sender: Sender.fromJson(json: session.sender!), - pjUri: session.pjUri!, - ); - } - final receiver = Receiver.fromJson(json: session.receiver!); - printV("Resuming Payjoin Receiver Session ${receiver.id()}"); - return spawnReceiver(receiver: receiver); - }); - - printV("Resumed ${spawnedSessions.length} Payjoin Sessions"); - await Future.wait(spawnedSessions); - } - - Future initSender( - String pjUriString, String originalPsbt, int networkFeesSatPerVb) async { - try { - final pjUri = - (await PayjoinUri.Uri.fromStr(pjUriString)).checkPjSupported(); - final minFeeRateSatPerKwu = BigInt.from(networkFeesSatPerVb * 250); - final senderBuilder = await SenderBuilder.fromPsbtAndUri( - psbtBase64: originalPsbt, - pjUri: pjUri, - ); - final persister = PayjoinSenderPersister.impl(); - final newSender = - await senderBuilder.buildRecommended(minFeeRate: minFeeRateSatPerKwu); - final senderToken = await newSender.persist(persister: persister); - - return Sender.load(token: senderToken, persister: persister); - } catch (e) { - throw Exception('Error initializing Payjoin Sender: $e'); - } - } - - Future spawnNewSender({ - required Sender sender, - required String pjUrl, - required BigInt amount, - bool isTestnet = false, - }) async { - final pjUri = Uri.parse(pjUrl).queryParameters['pj']!; - await _payjoinStorage.insertSenderSession( - sender, pjUri, _wallet.id, amount); - - return _spawnSender(isTestnet: isTestnet, sender: sender, pjUri: pjUri); - } - - Future _spawnSender({ - required Sender sender, - required String pjUri, - bool isTestnet = false, - }) async { - final completer = Completer(); - final receivePort = ReceivePort(); - - receivePort.listen((message) async { - if (message is Map) { - try { - switch (message['type'] as PayjoinSenderRequestTypes) { - case PayjoinSenderRequestTypes.requestPosted: - return; - case PayjoinSenderRequestTypes.psbtToSign: - final proposalPsbt = message['psbt'] as String; - final utxos = _wallet.getUtxoWithPrivateKeys(); - final finalizedPsbt = await _wallet.signPsbt(proposalPsbt, utxos); - final txId = getTxIdFromPsbtV0(finalizedPsbt); - _wallet.commitPsbt(finalizedPsbt); - - _cleanupSession(pjUri); - await _payjoinStorage.markSenderSessionComplete(pjUri, txId); - completer.complete(); - } - } catch (e) { - _cleanupSession(pjUri); - await _payjoinStorage.markSenderSessionUnrecoverable(pjUri, e.toString()); - completer.complete(); - } - } else if (message is PayjoinSessionError) { - _cleanupSession(pjUri); - if (message is UnrecoverableError) { - await _payjoinStorage.markSenderSessionUnrecoverable(pjUri, message.message); - completer.complete(); - } else if (message is RecoverableError) { - completer.complete(); - } else { - completer.completeError(message); - } - } - }); - - final isolate = await Isolate.spawn( - PayjoinSenderWorker.run, - [receivePort.sendPort, sender.toJson(), pjUri], - ); - - _activePollers[pjUri] = PayjoinPollerSession(isolate, receivePort); - - return completer.future; - } - - Future getUnusedReceiver(String address, - [bool isTestnet = false]) async { - final session = _payjoinStorage.getUnusedActiveReceiverSession(_wallet.id); - - if (session != null) { - await PayjoinUri.Url.fromStr(payjoinDirectoryUrl); - - return Receiver.fromJson(json: session.receiver!); - } - - return initReceiver(address); - } - - Future initReceiver(String address, [bool isTestnet = false]) async { - final ohttpKeys = await PayjoinUri.fetchOhttpKeys( - ohttpRelay: await randomOhttpRelayUrl(), - payjoinDirectory: payjoinDirectoryUrl, - ); - - final newReceiver = await NewReceiver.create( - address: address, - network: isTestnet ? Network.testnet : Network.bitcoin, - directory: payjoinDirectoryUrl, - ohttpKeys: ohttpKeys, - ); - final persister = PayjoinReceiverPersister.impl(); - final receiverToken = await newReceiver.persist(persister: persister); - final receiver = await Receiver.load(persister: persister, token: receiverToken); - - await _payjoinStorage.insertReceiverSession(receiver, _wallet.id); - - return receiver; - } - - Future spawnReceiver({ - required Receiver receiver, - bool isTestnet = false, - }) async { - final completer = Completer(); - final receivePort = ReceivePort(); - - SendPort? mainToIsolateSendPort; - List utxos = []; - String rawAmount = '0'; - - receivePort.listen((message) async { - if (message is Map) { - try { - switch (message['type'] as PayjoinReceiverRequestTypes) { - case PayjoinReceiverRequestTypes.processOriginalTx: - final tx = message['tx'] as String; - rawAmount = getOutputAmountFromTx(tx, _wallet); - break; - case PayjoinReceiverRequestTypes.checkIsOwned: - (_wallet.walletAddresses as BitcoinWalletAddresses) - .newPayjoinReceiver(); - _payjoinStorage.markReceiverSessionInProgress(receiver.id()); - - final inputScript = message['input_script'] as Uint8List; - final isOwned = - _wallet.isMine(Script.fromRaw(byteData: inputScript)); - mainToIsolateSendPort?.send({ - 'requestId': message['requestId'], - 'result': isOwned, - }); - break; - - case PayjoinReceiverRequestTypes.checkIsReceiverOutput: - final outputScript = message['output_script'] as Uint8List; - final isReceiverOutput = - _wallet.isMine(Script.fromRaw(byteData: outputScript)); - mainToIsolateSendPort?.send({ - 'requestId': message['requestId'], - 'result': isReceiverOutput, - }); - break; - - case PayjoinReceiverRequestTypes.getCandidateInputs: - utxos = _wallet.getUtxoWithPrivateKeys(); - if (utxos.isEmpty) { - await _wallet.updateAllUnspents(); - utxos = _wallet.getUtxoWithPrivateKeys(); - } - mainToIsolateSendPort?.send({ - 'requestId': message['requestId'], - 'result': utxos, - }); - break; - - case PayjoinReceiverRequestTypes.processPsbt: - final psbt = message['psbt'] as String; - final signedPsbt = await _wallet.signPsbt(psbt, utxos); - mainToIsolateSendPort?.send({ - 'requestId': message['requestId'], - 'result': signedPsbt, - }); - break; - - case PayjoinReceiverRequestTypes.proposalSent: - _cleanupSession(receiver.id()); - final psbt = message['psbt'] as String; - await _payjoinStorage.markReceiverSessionComplete( - receiver.id(), getTxIdFromPsbtV0(psbt), rawAmount); - completer.complete(); - } - } catch (e) { - _cleanupSession(receiver.id()); - await _payjoinStorage.markReceiverSessionUnrecoverable( - receiver.id(), e.toString()); - completer.completeError(e); - } - } else if (message is PayjoinSessionError) { - _cleanupSession(receiver.id()); - if (message is UnrecoverableError) { - await _payjoinStorage.markReceiverSessionUnrecoverable( - receiver.id(), message.message); - completer.complete(); - } else if (message is RecoverableError) { - completer.complete(); - } else { - completer.completeError(message); - } - } else if (message is SendPort) { - mainToIsolateSendPort = message; - } - }); - - final isolate = await Isolate.spawn( - PayjoinReceiverWorker.run, - [receivePort.sendPort, receiver.toJson()], - ); - - _activePollers[receiver.id()] = PayjoinPollerSession(isolate, receivePort); - - return completer.future; - } - - void cleanupSessions() { - final sessionIds = _activePollers.keys.toList(); - for (final sessionId in sessionIds) { - _cleanupSession(sessionId); - } - } - - void _cleanupSession(String sessionId) { - _activePollers[sessionId]?.close(); - _activePollers.remove(sessionId); - } -} - -class PayjoinPollerSession { - final Isolate isolate; - final ReceivePort port; - - PayjoinPollerSession(this.isolate, this.port); - - void close() { - isolate.kill(); - port.close(); - } -} diff --git a/cw_bitcoin/lib/payjoin/payjoin_persister.dart b/cw_bitcoin/lib/payjoin/payjoin_persister.dart deleted file mode 100644 index 4e395e36a..000000000 --- a/cw_bitcoin/lib/payjoin/payjoin_persister.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:payjoin_flutter/src/generated/api/receive.dart'; -import 'package:payjoin_flutter/src/generated/api/send.dart'; - -class PayjoinSenderPersister implements DartSenderPersister { - static DartSenderPersister impl() { - final impl = PayjoinSenderPersister(); - return DartSenderPersister( - save: (sender) => impl.save(sender: sender), - load: (token) => impl.load(token: token), - ); - } - - final Map _store = {}; - - Future save({required FfiSender sender}) async { - final token = sender.key(); - _store[token.toBytes().toString()] = sender; - return token; - } - - Future load({required SenderToken token}) async { - final sender = _store[token.toBytes().toString()]; - if (sender == null) { - throw Exception('Sender not found for the provided token.'); - } - return sender; - } - - @override - void dispose() => _store.clear(); - - @override - bool get isDisposed => _store.isEmpty; -} - -class PayjoinReceiverPersister implements DartReceiverPersister { - static DartReceiverPersister impl() { - final impl = PayjoinReceiverPersister(); - return DartReceiverPersister( - save: (receiver) => impl.save(receiver: receiver), - load: (token) => impl.load(token: token), - ); - } - - final Map _store = {}; - - Future save({required FfiReceiver receiver}) async { - final token = receiver.key(); - _store[token.toBytes().toString()] = receiver; - return token; - } - - Future load({required ReceiverToken token}) async { - final receiver = _store[token.toBytes().toString()]; - if (receiver == null) { - throw Exception('Receiver not found for the provided token.'); - } - return receiver; - } - - @override - void dispose() => _store.clear(); - - @override - bool get isDisposed => _store.isEmpty; -} diff --git a/cw_bitcoin/lib/payjoin/payjoin_receive_worker.dart b/cw_bitcoin/lib/payjoin/payjoin_receive_worker.dart deleted file mode 100644 index c56148de2..000000000 --- a/cw_bitcoin/lib/payjoin/payjoin_receive_worker.dart +++ /dev/null @@ -1,222 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'dart:isolate'; -import 'dart:typed_data'; - -import 'package:blockchain_utils/blockchain_utils.dart'; -import 'package:cw_bitcoin/payjoin/manager.dart'; -import 'package:cw_bitcoin/payjoin/payjoin_session_errors.dart'; -import 'package:cw_bitcoin/psbt/signer.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/utils/proxy_wrapper.dart'; -import 'package:payjoin_flutter/bitcoin_ffi.dart'; -import 'package:payjoin_flutter/common.dart'; -import 'package:payjoin_flutter/receive.dart'; -import 'package:payjoin_flutter/src/generated/frb_generated.dart' as pj; -import 'package:http/http.dart' as very_insecure_http_do_not_use; // for errors - -enum PayjoinReceiverRequestTypes { - processOriginalTx, - proposalSent, - getCandidateInputs, - checkIsOwned, - checkIsReceiverOutput, - processPsbt; -} - -class PayjoinReceiverWorker { - final SendPort sendPort; - final pendingRequests = >{}; - - PayjoinReceiverWorker._(this.sendPort); - static final client = ProxyWrapper().getHttpIOClient(); - static Future run(List args) async { - await pj.core.init(); - - final sendPort = args[0] as SendPort; - final receiverJson = args[1] as String; - - final worker = PayjoinReceiverWorker._(sendPort); - final receivePort = ReceivePort(); - - sendPort.send(receivePort.sendPort); - receivePort.listen(worker.handleMessage); - - try { - final receiver = Receiver.fromJson(json: receiverJson); - - final uncheckedProposal = - await worker.receiveUncheckedProposal(receiver); - - final originalTx = await uncheckedProposal.extractTxToScheduleBroadcast(); - sendPort.send({ - 'type': PayjoinReceiverRequestTypes.processOriginalTx, - 'tx': BytesUtils.toHexString(originalTx), - }); - - final payjoinProposal = await worker.processPayjoinProposal( - uncheckedProposal, - ); - final psbt = await worker.sendFinalProposal(payjoinProposal); - sendPort.send({ - 'type': PayjoinReceiverRequestTypes.proposalSent, - 'psbt': psbt, - }); - } catch (e) { - if (e is HttpException || - (e is very_insecure_http_do_not_use.ClientException && - e.message.contains("Software caused connection abort"))) { - sendPort.send(PayjoinSessionError.recoverable(e.toString())); - } else { - sendPort.send(PayjoinSessionError.unrecoverable(e.toString())); - } - } - } - - void handleMessage(dynamic message) async { - if (message is Map) { - final requestId = message['requestId'] as String?; - if (requestId != null && pendingRequests.containsKey(requestId)) { - pendingRequests[requestId]!.complete(message['result']); - pendingRequests.remove(requestId); - } - } - } - - Future _sendRequest(PayjoinReceiverRequestTypes type, - [Map data = const {}]) async { - final completer = Completer(); - final requestId = DateTime.now().millisecondsSinceEpoch.toString(); - pendingRequests[requestId] = completer; - - sendPort.send({ - ...data, - 'type': type, - 'requestId': requestId, - }); - - return completer.future; - } - - Future receiveUncheckedProposal(Receiver session) async { - while (true) { - printV("Polling for Proposal (${session.id()})"); - final extractReq = await session.extractReq( - ohttpRelay: await PayjoinManager.randomOhttpRelayUrl(), - ); - final request = extractReq.$1; - - final url = Uri.parse(request.url.asString()); - final httpRequest = await client.post(url, - headers: {'Content-Type': request.contentType}, body: request.body); - - final proposal = await session.processRes( - body: httpRequest.bodyBytes, ctx: extractReq.$2); - if (proposal != null) return proposal; - } - } - - Future sendFinalProposal(PayjoinProposal finalProposal) async { - final req = await finalProposal.extractReq( - ohttpRelay: await PayjoinManager.randomOhttpRelayUrl(), - ); - final proposalReq = req.$1; - final proposalCtx = req.$2; - - final request = await client.post( - Uri.parse(proposalReq.url.asString()), - headers: {"Content-Type": proposalReq.contentType}, - body: proposalReq.body, - ); - - await finalProposal.processRes( - res: request.bodyBytes, - ohttpContext: proposalCtx, - ); - - return await finalProposal.psbt(); - } - - Future processPayjoinProposal( - UncheckedProposal proposal) async { - await proposal.extractTxToScheduleBroadcast(); - // TODO Handle this. send to the main port on a timer? - - try { - // Receive Check 1: can broadcast - final pj1 = await proposal.assumeInteractiveReceiver(); - - // Receive Check 2: original PSBT has no receiver-owned inputs - final pj2 = await pj1.checkInputsNotOwned( - isOwned: (inputScript) async { - final result = await _sendRequest( - PayjoinReceiverRequestTypes.checkIsOwned, - {'input_script': inputScript}, - ); - return result as bool; - }, - ); - // Receive Check 3: sender inputs have not been seen before (prevent probing attacks) - final pj3 = await pj2.checkNoInputsSeenBefore(isKnown: (input) => false); - - // Identify receiver outputs - final pj4 = await pj3.identifyReceiverOutputs( - isReceiverOutput: (outputScript) async { - final result = await _sendRequest( - PayjoinReceiverRequestTypes.checkIsReceiverOutput, - {'output_script': outputScript}, - ); - return result as bool; - }, - ); - final pj5 = await pj4.commitOutputs(); - - final listUnspent = - await _sendRequest(PayjoinReceiverRequestTypes.getCandidateInputs); - final unspent = listUnspent as List; - if (unspent.isEmpty) throw RecoverableError('No unspent outputs available'); - - final selectedUtxo = await _inputPairFromUtxo(unspent[0]); - final pj6 = await pj5.contributeInputs(replacementInputs: [selectedUtxo]); - final pj7 = await pj6.commitInputs(); - - // Finalize proposal - final payjoinProposal = await pj7.finalizeProposal( - processPsbt: (String psbt) async { - final result = await _sendRequest( - PayjoinReceiverRequestTypes.processPsbt, {'psbt': psbt}); - return result as String; - }, - // TODO set maxFeeRateSatPerVb - maxFeeRateSatPerVb: BigInt.from(10000), - ); - return payjoinProposal; - } catch (e) { - printV('Error occurred while finalizing proposal: $e'); - rethrow; - } - } - - Future _inputPairFromUtxo(UtxoWithPrivateKey utxo) async { - final txout = TxOut( - value: utxo.utxo.value, - scriptPubkey: Uint8List.fromList( - utxo.ownerDetails.address.toScriptPubKey().toBytes()), - ); - - final psbtin = - PsbtInput(witnessUtxo: txout, redeemScript: null, witnessScript: null); - - final previousOutput = - OutPoint(txid: utxo.utxo.txHash, vout: utxo.utxo.vout); - - final txin = TxIn( - previousOutput: previousOutput, - scriptSig: await Script.newInstance(rawOutputScript: []), - witness: [], - sequence: 0, - ); - - return InputPair.newInstance(txin: txin, psbtin: psbtin); - } -} diff --git a/cw_bitcoin/lib/payjoin/payjoin_send_worker.dart b/cw_bitcoin/lib/payjoin/payjoin_send_worker.dart deleted file mode 100644 index 7e85cc773..000000000 --- a/cw_bitcoin/lib/payjoin/payjoin_send_worker.dart +++ /dev/null @@ -1,120 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'dart:isolate'; - -import 'package:cw_bitcoin/payjoin/manager.dart'; -import 'package:cw_bitcoin/payjoin/payjoin_session_errors.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/utils/proxy_wrapper.dart'; -import 'package:payjoin_flutter/common.dart'; -import 'package:payjoin_flutter/send.dart'; -import 'package:payjoin_flutter/src/generated/frb_generated.dart' as pj; -import 'package:payjoin_flutter/src/generated/api/send/error.dart' as pj_error; -import 'package:payjoin_flutter/uri.dart' as pj_uri; - -enum PayjoinSenderRequestTypes { - requestPosted, - psbtToSign; -} - -class PayjoinSenderWorker { - final SendPort sendPort; - final pendingRequests = >{}; - final String pjUrl; - - PayjoinSenderWorker._(this.sendPort, this.pjUrl); - - static Future run(List args) async { - await pj.core.init(); - - final sendPort = args[0] as SendPort; - final senderJson = args[1] as String; - final pjUrl = args[2] as String; - - final sender = Sender.fromJson(json: senderJson); - final worker = PayjoinSenderWorker._(sendPort, pjUrl); - - try { - final proposalPsbt = await worker.runSender(sender); - sendPort.send({ - 'type': PayjoinSenderRequestTypes.psbtToSign, - 'psbt': proposalPsbt, - }); - } catch (e) { - sendPort.send(e); - } - } - final client = ProxyWrapper().getHttpIOClient(); - - /// Run a payjoin sender (V2 protocol first, fallback to V1). - Future runSender(Sender sender) async { - - try { - return await _runSenderV2(sender); - } catch (e) { - printV(e); - if (e is pj_error.FfiCreateRequestError) { - return await _runSenderV1(sender); - } else if (e is HttpException) { - printV(e); - throw Exception(PayjoinSessionError.recoverable(e.toString())); - } else { - throw Exception(PayjoinSessionError.unrecoverable(e.toString())); - } - } - } - - /// Attempt to send payjoin using the V2 of the protocol. - Future _runSenderV2(Sender sender) async { - try { - final postRequest = await sender.extractV2( - ohttpProxyUrl: - await pj_uri.Url.fromStr(PayjoinManager.randomOhttpRelayUrl()), - ); - - final postResult = await _postRequest(postRequest.$1); - final getContext = - await postRequest.$2.processResponse(response: postResult); - - sendPort.send({'type': PayjoinSenderRequestTypes.requestPosted, "pj": pjUrl}); - - while (true) { - printV('Polling V2 Proposal Request (${pjUrl})'); - - final getRequest = await getContext.extractReq( - ohttpRelay: await PayjoinManager.randomOhttpRelayUrl(), - ); - final getRes = await _postRequest(getRequest.$1); - final proposalPsbt = await getContext.processResponse( - response: getRes, - ohttpCtx: getRequest.$2, - ); - printV("$proposalPsbt"); - if (proposalPsbt != null) return proposalPsbt; - } - } catch (e) { - rethrow; - } - } - - /// Attempt to send payjoin using the V1 of the protocol. - Future _runSenderV1(Sender sender) async { - try { - final postRequest = await sender.extractV1(); - final response = await _postRequest(postRequest.$1); - - sendPort.send({'type': PayjoinSenderRequestTypes.requestPosted}); - - return await postRequest.$2.processResponse(response: response); - } catch (e, stack) { - throw PayjoinSessionError.unrecoverable('Send V1 payjoin error: $e, $stack'); - } - } - - Future> _postRequest(Request req) async { - final httpRequest = await client.post(Uri.parse(req.url.asString()), - headers: {'Content-Type': req.contentType}, body: req.body); - - return httpRequest.bodyBytes; - } -} diff --git a/cw_bitcoin/lib/payjoin/payjoin_session_errors.dart b/cw_bitcoin/lib/payjoin/payjoin_session_errors.dart deleted file mode 100644 index 06e0a5431..000000000 --- a/cw_bitcoin/lib/payjoin/payjoin_session_errors.dart +++ /dev/null @@ -1,16 +0,0 @@ -class PayjoinSessionError { - final String message; - - const PayjoinSessionError._(this.message); - - factory PayjoinSessionError.recoverable(String message) = RecoverableError; - factory PayjoinSessionError.unrecoverable(String message) = UnrecoverableError; -} - -class RecoverableError extends PayjoinSessionError { - const RecoverableError(super.message) : super._(); -} - -class UnrecoverableError extends PayjoinSessionError { - const UnrecoverableError(super.message) : super._(); -} diff --git a/cw_bitcoin/lib/payjoin/storage.dart b/cw_bitcoin/lib/payjoin/storage.dart deleted file mode 100644 index 5fb9d5716..000000000 --- a/cw_bitcoin/lib/payjoin/storage.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:cw_core/payjoin_session.dart'; -import 'package:hive/hive.dart'; -import 'package:payjoin_flutter/receive.dart'; -import 'package:payjoin_flutter/send.dart'; - -class PayjoinStorage { - PayjoinStorage(this._payjoinSessionSources); - - final Box _payjoinSessionSources; - - static const String _receiverPrefix = 'pj_recv_'; - static const String _senderPrefix = 'pj_send_'; - - Future insertReceiverSession( - Receiver receiver, - String walletId, - ) => - _payjoinSessionSources.put( - "$_receiverPrefix${receiver.id()}", - PayjoinSession( - walletId: walletId, - receiver: receiver.toJson(), - ), - ); - - PayjoinSession? getUnusedActiveReceiverSession(String walletId) => - _payjoinSessionSources.values - .where((session) => - session.walletId == walletId && - session.status == PayjoinSessionStatus.created.name && - !session.isSenderSession) - .firstOrNull; - - Future markReceiverSessionComplete( - String sessionId, String txId, String amount) async { - final session = _payjoinSessionSources.get("$_receiverPrefix${sessionId}")!; - - session.status = PayjoinSessionStatus.success.name; - session.txId = txId; - session.rawAmount = amount; - await session.save(); - } - - Future markReceiverSessionUnrecoverable( - String sessionId, String reason) async { - final session = _payjoinSessionSources.get("$_receiverPrefix${sessionId}")!; - - session.status = PayjoinSessionStatus.unrecoverable.name; - session.error = reason; - await session.save(); - } - - Future markReceiverSessionInProgress(String sessionId) async { - final session = _payjoinSessionSources.get("$_receiverPrefix${sessionId}")!; - - session.status = PayjoinSessionStatus.inProgress.name; - session.inProgressSince = DateTime.now(); - await session.save(); - } - - Future insertSenderSession( - Sender sender, - String pjUrl, - String walletId, - BigInt amount, - ) => - _payjoinSessionSources.put( - "$_senderPrefix$pjUrl", - PayjoinSession( - walletId: walletId, - pjUri: pjUrl, - sender: sender.toJson(), - status: PayjoinSessionStatus.inProgress.name, - inProgressSince: DateTime.now(), - rawAmount: amount.toString(), - ), - ); - - Future markSenderSessionComplete(String pjUrl, String txId) async { - final session = _payjoinSessionSources.get("$_senderPrefix$pjUrl")!; - - session.status = PayjoinSessionStatus.success.name; - session.txId = txId; - await session.save(); - } - - Future markSenderSessionUnrecoverable(String pjUrl, String reason) async { - final session = _payjoinSessionSources.get("$_senderPrefix$pjUrl")!; - - session.status = PayjoinSessionStatus.unrecoverable.name; - session.error = reason; - await session.save(); - } - - List readAllOpenSessions(String walletId) => - _payjoinSessionSources.values - .where((session) => - session.walletId == walletId && - ![ - PayjoinSessionStatus.success.name, - PayjoinSessionStatus.unrecoverable.name - ].contains(session.status)) - .toList(); -} diff --git a/cw_bitcoin/lib/pending_bitcoin_transaction.dart b/cw_bitcoin/lib/pending_bitcoin_transaction.dart index 6930524eb..411c7de16 100644 --- a/cw_bitcoin/lib/pending_bitcoin_transaction.dart +++ b/cw_bitcoin/lib/pending_bitcoin_transaction.dart @@ -1,4 +1,3 @@ -import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:grpc/grpc.dart'; import 'package:cw_bitcoin/exceptions.dart'; import 'package:bitcoin_base/bitcoin_base.dart'; @@ -26,8 +25,6 @@ class PendingBitcoinTransaction with PendingTransaction { this.hasTaprootInputs = false, this.isMweb = false, this.utxos = const [], - this.publicKeys, - this.commitOverride, }) : _listeners = []; final WalletType type; @@ -46,8 +43,6 @@ class PendingBitcoinTransaction with PendingTransaction { String? idOverride; String? hexOverride; List? outputAddresses; - final Map? publicKeys; - Future Function()? commitOverride; @override String get id => idOverride ?? _tx.txId(); @@ -134,10 +129,6 @@ class PendingBitcoinTransaction with PendingTransaction { @override Future commit() async { - if (commitOverride != null) { - return commitOverride?.call(); - } - if (isMweb) { await _ltcCommit(); } else { diff --git a/cw_bitcoin/lib/psbt/signer.dart b/cw_bitcoin/lib/psbt/signer.dart deleted file mode 100644 index 1d0ceba8b..000000000 --- a/cw_bitcoin/lib/psbt/signer.dart +++ /dev/null @@ -1,263 +0,0 @@ -import 'dart:typed_data'; - -import 'package:bitcoin_base/bitcoin_base.dart'; -import 'package:blockchain_utils/blockchain_utils.dart'; -import 'package:collection/collection.dart'; -import 'package:cw_bitcoin/bitcoin_address_record.dart'; -import 'package:cw_bitcoin/bitcoin_unspent.dart'; -import 'package:cw_bitcoin/bitcoin_wallet.dart'; -import 'package:cw_bitcoin/utils.dart'; -import 'package:ledger_bitcoin/psbt.dart'; -import 'package:ledger_bitcoin/src/utils/buffer_writer.dart'; - -extension PsbtSigner on PsbtV2 { - Uint8List extractUnsignedTX({bool getSegwit = true}) { - final tx = BufferWriter()..writeUInt32(getGlobalTxVersion()); - - final isSegwit = getInputWitnessUtxo(0) != null; - if (isSegwit && getSegwit) { - tx.writeSlice(Uint8List.fromList([0, 1])); - } - - final inputCount = getGlobalInputCount(); - tx.writeVarInt(inputCount); - - for (var i = 0; i < inputCount; i++) { - tx - ..writeSlice(getInputPreviousTxid(i)) - ..writeUInt32(getInputOutputIndex(i)) - ..writeVarSlice(Uint8List(0)) - ..writeUInt32(getInputSequence(i)); - } - - final outputCount = getGlobalOutputCount(); - tx.writeVarInt(outputCount); - for (var i = 0; i < outputCount; i++) { - tx.writeUInt64(getOutputAmount(i)); - tx.writeVarSlice(getOutputScript(i)); - } - tx.writeUInt32(getGlobalFallbackLocktime() ?? 0); - return tx.buffer(); - } - - Future signWithUTXO( - List utxos, UTXOSignerCallBack signer, - [UTXOGetterCallBack? getTaprootPair]) async { - final raw = BytesUtils.toHexString(extractUnsignedTX(getSegwit: false)); - final tx = BtcTransaction.fromRaw(raw); - - /// when the transaction is taproot and we must use getTaproot transaction - /// digest we need all of inputs amounts and owner script pub keys - List taprootAmounts = []; - List