diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
deleted file mode 100644
index cb2afa3962..0000000000
--- a/.github/workflows/cache_dependencies.yml
+++ /dev/null
@@ -1,84 +0,0 @@
-name: Cache Dependencies
-
-on:
- workflow_dispatch:
- push:
- branches: [ main ]
-
-jobs:
- test:
-
- runs-on: ubuntu-20.04
-
- steps:
- - name: Free Disk Space (Ubuntu)
- uses: insightsengineering/disk-space-reclaimer@v1
- with:
- tools-cache: true
- android: false
- dotnet: true
- haskell: true
- large-packages: true
- swap-storage: true
- docker-images: true
-
- - uses: actions/checkout@v2
- - uses: actions/setup-java@v2
- with:
- distribution: "temurin"
- java-version: "17"
- - name: Configure placeholder git details
- run: |
- git config --global user.email "CI@cakewallet.com"
- git config --global user.name "Cake Github Actions"
- - name: Flutter action
- uses: subosito/flutter-action@v1
- with:
- flutter-version: "3.24.4"
- channel: stable
-
- - name: Install package dependencies
- run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
-
- - name: Execute Build and Setup Commands
- run: |
- sudo mkdir -p /opt/android
- sudo chown $USER /opt/android
- cd /opt/android
- -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- cargo install cargo-ndk
- git clone https://github.com/cake-tech/cake_wallet.git --branch main
- cd cake_wallet/scripts/android/
- ./install_ndk.sh
- source ./app_env.sh cakewallet
- chmod +x pubspec_gen.sh
- ./app_config.sh
-
- - name: Cache Externals
- id: cache-externals
- uses: actions/cache@v3
- with:
- path: |
- /opt/android/cake_wallet/cw_haven/android/.cxx
- /opt/android/cake_wallet/scripts/monero_c/release
- key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
-
- - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
- name: Generate Externals
- run: |
- cd /opt/android/cake_wallet/scripts/android/
- source ./app_env.sh cakewallet
- ./build_monero_all.sh
-
- - name: Cache Keystore
- id: cache-keystore
- uses: actions/cache@v3
- with:
- path: /opt/android/cake_wallet/android/app
- key: keystore
-
- - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
- name: Generate KeyStore
- run: |
- cd /opt/android/cake_wallet/android/app
- keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml
index cdd0e40b44..c5f8751287 100644
--- a/.github/workflows/pr_test_build_android.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -1,169 +1,93 @@
-name: PR Test Build
+name: Cake Wallet Android
-on:
- pull_request:
- branches: [main]
- workflow_dispatch:
- inputs:
- branch:
- description: "Branch name to build"
- required: true
- default: "main"
+on: [push]
+defaults:
+ run:
+ shell: bash
jobs:
PR_test_build:
- runs-on: ubuntu-20.04
+ runs-on: linux-amd64
+ container:
+ image: ghcr.io/cake-tech/cake_wallet:main-linux
+ env:
+ STORE_PASS: test@cake_wallet
+ KEY_PASS: test@cake_wallet
+ MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
+ BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
+ ANDROID_AVD_HOME: /root/.android/avd
+ volumes:
+ - /opt/cw_cache_android/root/.cache:/root/.cache
+ - /opt/cw_cache_android/root/.android/avd/:/root/.android/avd
+ - /opt/cw_cache_android/root/.ccache:/root/.ccache
+ - /opt/cw_cache_android/root/.pub-cache/:/root/.pub-cache
+ - /opt/cw_cache_android/root/.gradle/:/root/.gradle
+ - /opt/cw_cache_android/root/.android/:/root/.android
+ - /opt/cw_cache_android/root/go/pkg:/root/go/pkg
+ - /opt/cw_cache_android/opt/generic_cache:/opt/generic_cache
+ - /dev/kvm:/dev/kvm
strategy:
matrix:
api-level: [29]
- env:
- STORE_PASS: test@cake_wallet
- KEY_PASS: test@cake_wallet
- PR_NUMBER: ${{ github.event.number }}
steps:
- - name: is pr
- if: github.event_name == 'pull_request'
- run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
-
- - name: is not pr
- if: github.event_name != 'pull_request'
- run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENV
-
- - name: Free Disk Space (Ubuntu)
- uses: insightsengineering/disk-space-reclaimer@v1
- with:
- tools-cache: true
- android: false
- dotnet: true
- haskell: true
- large-packages: true
- swap-storage: true
- docker-images: true
-
- - uses: actions/checkout@v2
- - uses: actions/setup-java@v2
- with:
- distribution: "temurin"
- java-version: "17"
- - name: Configure placeholder git details
- run: |
- git config --global user.email "CI@cakewallet.com"
- git config --global user.name "Cake Github Actions"
- - name: Flutter action
- uses: subosito/flutter-action@v1
- with:
- flutter-version: "3.24.0"
- channel: stable
-
- - name: Install package dependencies
- run: |
- sudo apt update
- sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
-
-
- - name: Clone Repo
- run: |
- sudo mkdir -p /opt/android
- sudo chown $USER /opt/android
- cd /opt/android
- git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
-
-# - name: Cache Keystore
-# id: cache-keystore
-# uses: actions/cache@v3
-# with:
-# path: /opt/android/cake_wallet/android/app
-# key: keystore
-#
-# - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
- - name: Generate KeyStore
- run: |
- cd /opt/android/cake_wallet/android/app
- keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
-
- - name: Execute Build and Setup Commands
- run: |
- cd /opt/android
- -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- cargo install cargo-ndk
- cd cake_wallet/scripts/android/
- ./install_ndk.sh
- source ./app_env.sh cakewallet
- chmod +x pubspec_gen.sh
- ./app_config.sh
-
- - name: Cache Externals
- id: cache-externals
- uses: actions/cache@v3
- with:
- path: |
- /opt/android/cake_wallet/cw_haven/android/.cxx
- /opt/android/cake_wallet/scripts/monero_c/release
- key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
-
- - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
- name: Generate Externals
- run: |
- cd /opt/android/cake_wallet/scripts/android/
- source ./app_env.sh cakewallet
- ./build_monero_all.sh
-
- - name: Install Flutter dependencies
- run: |
- cd /opt/android/cake_wallet
- flutter pub get
-
-
- - name: Install go and gomobile
- run: |
- # install go > 1.23:
- wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz
- sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz
- export PATH=$PATH:/usr/local/go/bin
- export PATH=$PATH:~/go/bin
- go install golang.org/x/mobile/cmd/gomobile@latest
- gomobile init
-
- - name: Build mwebd
- run: |
- # paths are reset after each step, so we need to set them again:
- export PATH=$PATH:/usr/local/go/bin
- export PATH=$PATH:~/go/bin
- cd /opt/android/cake_wallet/scripts/android/
- ./build_mwebd.sh --dont-install
-
- - name: Generate key properties
- run: |
- cd /opt/android/cake_wallet
- dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
-
- - name: Generate localization
- run: |
- cd /opt/android/cake_wallet
- dart run tool/generate_localization.dart
-
- - name: Build generated code
+ - name: Fix github actions messing up $HOME...
+ run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
+ - uses: actions/checkout@v4
+ - name: configure git
run: |
- cd /opt/android/cake_wallet
- ./model_generator.sh
-
+ git config --global user.email "ci@cakewallet.com"
+ git config --global user.name "CakeWallet CI"
- name: Add secrets
run: |
- cd /opt/android/cake_wallet
touch lib/.secrets.g.dart
touch cw_evm/lib/.secrets.g.dart
touch cw_solana/lib/.secrets.g.dart
touch cw_core/lib/.secrets.g.dart
touch cw_nano/lib/.secrets.g.dart
touch cw_tron/lib/.secrets.g.dart
- echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
- echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
- echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
- echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
- 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
+ if [[ "x${{ secrets.SALT }}" == "x" ]];
+ then
+ echo "const salt = '954f787f12622067f7e548d9450c3832';" > lib/.secrets.g.dart
+ else
+ echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.KEY_CHAIN_SALT }}" == "x" ]];
+ then
+ echo "const keychainSalt = '2d2beba777dbf7dff7013b7a';" >> lib/.secrets.g.dart
+ else
+ echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.KEY }}" == "x" ]];
+ then
+ echo "const key = '638e98820ec10a2945e968435c9397a3';" >> lib/.secrets.g.dart
+ else
+ echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.WALLET_SALT }}" == "x" ]];
+ then
+ echo "const walletSalt = '8f7f1b70';" >> lib/.secrets.g.dart
+ else
+ echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.SHORT_KEY }}" == "x" ]];
+ then
+ echo "const shortKey = '653f270c2c152bc7ec864afe';" >> lib/.secrets.g.dart
+ else
+ echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.BACKUP_SALT }}" == "x" ]];
+ then
+ echo "const backupSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
+ else
+ echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.BACKUP_KEY_CHAIN_SALT }}" == "x" ]];
+ then
+ echo "const backupKeychainSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
+ else
+ echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+ fi
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
@@ -213,86 +137,153 @@ jobs:
echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
+ # for tests
+ echo "const moneroTestWalletSeeds ='${{ secrets.MONERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const moneroLegacyTestWalletSeeds = '${{ secrets.MONERO_LEGACY_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const bitcoinTestWalletSeeds = '${{ secrets.BITCOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const ethereumTestWalletSeeds = '${{ secrets.ETHEREUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const litecoinTestWalletSeeds = '${{ secrets.LITECOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const bitcoinCashTestWalletSeeds = '${{ secrets.BITCOIN_CASH_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const polygonTestWalletSeeds = '${{ secrets.POLYGON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const solanaTestWalletSeeds = '${{ secrets.SOLANA_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const tronTestWalletSeeds = '${{ secrets.TRON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const nanoTestWalletSeeds = '${{ secrets.NANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const wowneroTestWalletSeeds = '${{ secrets.WOWNERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const moneroTestWalletReceiveAddress = '${{ secrets.MONERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const bitcoinTestWalletReceiveAddress = '${{ secrets.BITCOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const ethereumTestWalletReceiveAddress = '${{ secrets.ETHEREUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const litecoinTestWalletReceiveAddress = '${{ secrets.LITECOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const bitcoinCashTestWalletReceiveAddress = '${{ secrets.BITCOIN_CASH_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const polygonTestWalletReceiveAddress = '${{ secrets.POLYGON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const solanaTestWalletReceiveAddress = '${{ secrets.SOLANA_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const tronTestWalletReceiveAddress = '${{ secrets.TRON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ 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
+ - name: prepare monero_c and cache
+ run: |
+ export MONEROC_HASH=$(cat scripts/prepare_moneroc.sh | grep 'git checkout' | xargs | awk '{ print $3 }')
+ echo MONEROC_HASH=$MONEROC_HASH >> /etc/environment
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
+ pushd scripts
+ ln -s "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
+ ./prepare_moneroc.sh
+ popd
+ pushd scripts/monero_c
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" || true
+
+ rm -rf "$PWD/contrib/depends/built" "$PWD/monero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
+ rm -rf "$PWD/contrib/depends/sources" "$PWD/monero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
+ mkdir -p contrib/depends || true
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" "$PWD/contrib/depends/built"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" "$PWD/monero/contrib/depends/built"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" "$PWD/contrib/depends/sources"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" "$PWD/monero/contrib/depends/sources"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
+ popd
- - name: Rename app
+ - name: Generate KeyStore
run: |
- echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+ pushd /opt/generic_cache
+ if [[ ! -f key.jks ]];
+ then
+ keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
+ else
+ echo "$PWD/key.jks exist, not generating"
+ fi
+ popd
+ cp /opt/generic_cache/key.jks android/app
- # Step 3: Download previous build number
- - name: Download previous build number
- id: download-build-number
+ - name: Execute Build and Setup Commands
run: |
- # Download the artifact if it exists
- if [[ ! -f build_number.txt ]]; then
- echo "1" > build_number.txt
- fi
+ pushd scripts/android
+ source ./app_env.sh cakewallet
+ ./app_config.sh
+ popd
+
+ - name: Build monero_c
+ run: |
+ pushd scripts/android/
+ source ./app_env.sh cakewallet
+ ./build_monero_all.sh
+ popd
+
+ - name: Install Flutter dependencies
+ run: |
+ flutter pub get
- # Step 4: Read and Increment Build Number
- - name: Increment Build Number
- id: increment-build-number
+ - name: Build mwebd
+ run: |
+ set -x -e
+ export MWEBD_HASH=$(cat scripts/android/build_mwebd.sh | grep 'git reset --hard' | xargs | awk '{ print $4 }')
+ echo MWEBD_HASH=$MWEBD_HASH >> /etc/environment
+ pushd scripts/android
+ gomobile init;
+ ./build_mwebd.sh --dont-install
+ popd
+
+ - name: Build generated code
run: |
- # Read current build number from file
- BUILD_NUMBER=$(cat build_number.txt)
- BUILD_NUMBER=$((BUILD_NUMBER + 1))
- echo "New build number: $BUILD_NUMBER"
+ ./model_generator.sh async
- # Save the incremented build number
- echo "$BUILD_NUMBER" > build_number.txt
+ - name: Generate key properties
+ run: |
+ dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
- # Export the build number to use in later steps
- echo "BUILD_NUMBER=$BUILD_NUMBER" >> $GITHUB_ENV
+ - name: Generate localization
+ run: |
+ dart run tool/generate_localization.dart
- # Step 5: Update pubspec.yaml with new build number
- - name: Update build number
+ - name: Rename app
run: |
- cd /opt/android/cake_wallet
- sed -i "s/^version: .*/version: 1.0.$BUILD_NUMBER/" pubspec.yaml
+ sanitized_branch_name=${BRANCH_NAME#origin/} # Remove 'origin/' prefix if it exists
+ sanitized_branch_name=${sanitized_branch_name:0:16} # Take only the first 16 characters
+ sanitized_branch_name=$(echo "$sanitized_branch_name" | tr '[:upper:]' '[:lower:]') # Convert to lowercase
+ sanitized_branch_name=$(echo "$sanitized_branch_name" | sed 's/[^a-z0-9]//g') # Remove all special characters
+
+ echo -e "id=com.cakewallet.test_${sanitized_branch_name}\nname=${BRANCH_NAME}" > android/app.properties
- name: Build
run: |
- cd /opt/android/cake_wallet
flutter build apk --release --split-per-abi
- # - name: Push to App Center
- # run: |
- # echo 'Installing App Center CLI tools'
- # npm install -g appcenter-cli
- # echo "Publishing test to App Center"
- # appcenter distribute release \
- # --group "Testers" \
- # --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \
- # --release-notes ${{ env.BRANCH_NAME }} \
- # --app Cake-Labs/Cake-Wallet \
- # --token ${{ secrets.APP_CENTER_TOKEN }} \
- # --quiet
-
- name: Rename apk file
run: |
- cd /opt/android/cake_wallet/build/app/outputs/flutter-apk
+ cd build/app/outputs/flutter-apk
mkdir test-apk
- cp app-arm64-v8a-release.apk test-apk/${{env.BRANCH_NAME}}.apk
- cp app-x86_64-release.apk test-apk/${{env.BRANCH_NAME}}_x86.apk
-
- - name: Upload Artifact
- uses: kittaakos/upload-artifact-as-is@v0
- with:
- path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/
-
- # Re-upload updated build number for the next run
- - name: Upload updated build number
- uses: actions/upload-artifact@v3
- with:
- name: build_number
- path: build_number.txt
+ cp app-arm64-v8a-release.apk test-apk/${BRANCH_NAME}.apk
+ cp app-x86_64-release.apk test-apk/${BRANCH_NAME}_x86.apk
+ cd test-apk
+ cp ${BRANCH_NAME}.apk ${BRANCH_NAME}_slack.apk
- - name: Send Test APK
+ - name: Find APK file
+ id: find_apk
+ run: |
+ set -x
+ apk_file=$(ls build/app/outputs/flutter-apk/test-apk/*_slack.apk || exit 1)
+ echo "APK_FILE=$apk_file" >> $GITHUB_ENV
+
+ - name: Upload artifact to slack
+ if: ${{ !contains(github.event.head_commit.message, 'skip slack') }}
continue-on-error: true
uses: adrey/slack-file-upload-action@1.0.5
with:
token: ${{ secrets.SLACK_APP_TOKEN }}
- path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/${{env.BRANCH_NAME}}.apk
+ path: ${{ env.APK_FILE }}
channel: ${{ secrets.SLACK_APK_CHANNEL }}
- title: "${{ env.BRANCH_NAME }}.apk"
- filename: ${{ env.BRANCH_NAME }}.apk
initial_comment: ${{ github.event.head_commit.message }}
+ - 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"
\ 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 891327d1e7..345c95c4f7 100644
--- a/.github/workflows/pr_test_build_linux.yml
+++ b/.github/workflows/pr_test_build_linux.yml
@@ -1,139 +1,89 @@
-name: PR Test Build linux
+name: Cake Wallet Linux
-on:
- pull_request:
- branches: [main]
- workflow_dispatch:
- inputs:
- branch:
- description: "Branch name to build"
- required: true
- default: "main"
+on: [push]
+defaults:
+ run:
+ shell: bash
jobs:
PR_test_build:
- runs-on: ubuntu-20.04
- env:
- STORE_PASS: test@cake_wallet
- KEY_PASS: test@cake_wallet
- PR_NUMBER: ${{ github.event.number }}
+ runs-on: linux-amd64
+ container:
+ image: ghcr.io/cake-tech/cake_wallet:main-linux
+ env:
+ STORE_PASS: test@cake_wallet
+ KEY_PASS: test@cake_wallet
+ MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
+ BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
+ DESKTOP_FORCE_MOBILE: Y
+ volumes:
+ - /opt/cw_cache_linux/root/.cache:/root/.cache
+ - /opt/cw_cache_linux/root/.ccache:/root/.ccache
+ - /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: is pr
- if: github.event_name == 'pull_request'
- run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
-
- - name: is not pr
- if: github.event_name != 'pull_request'
- run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENVg
-
- - uses: actions/checkout@v2
- - uses: actions/setup-java@v1
- with:
- java-version: "17.x"
- - name: Configure placeholder git details
- run: |
- git config --global user.email "CI@cakewallet.com"
- git config --global user.name "Cake Github Actions"
- - name: Flutter action
- uses: subosito/flutter-action@v1
- with:
- flutter-version: "3.24.0"
- channel: stable
-
- - name: Install package dependencies
- run: |
- sudo apt update
- sudo apt-get install -y curl unzip automake build-essential file pkg-config git python-is-python3 libtool libtinfo5 cmake clang
-
- - name: Install desktop dependencies
- run: |
- sudo apt update
- sudo apt install -y ninja-build libgtk-3-dev gperf
- - name: Execute Build and Setup Commands
- run: |
- sudo mkdir -p /opt/android
- sudo chown $USER /opt/android
- cd /opt/android
- -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- cargo install cargo-ndk
- git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
- cd scripts && ./gen_android_manifest.sh && cd ..
- cd cake_wallet/scripts/android/
- source ./app_env.sh cakewallet
- ./app_config.sh
- cd ../../..
- cd cake_wallet/scripts/linux/
- source ./app_env.sh cakewallet
- ./app_config.sh
- cd ../../..
-
- - name: Cache Externals
- id: cache-externals
- uses: actions/cache@v3
- with:
- path: |
- /opt/android/cake_wallet/cw_haven/android/.cxx
- /opt/android/cake_wallet/scripts/monero_c/release
- key: linux_${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
-
- - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
- name: Generate Externals
- run: |
- cd /opt/android/cake_wallet/scripts/linux/
- source ./app_env.sh cakewallet
- ./build_monero_all.sh
-
- - name: Install Flutter dependencies
- run: |
- cd /opt/android/cake_wallet
- flutter pub get
-
- - name: Install go and gomobile
- run: |
- # install go > 1.23:
- wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz
- sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz
- export PATH=$PATH:/usr/local/go/bin
- export PATH=$PATH:~/go/bin
- go install golang.org/x/mobile/cmd/gomobile@latest
- gomobile init
-
- - name: Build mwebd
- run: |
- # paths are reset after each step, so we need to set them again:
- export PATH=$PATH:/usr/local/go/bin
- export PATH=$PATH:~/go/bin
- # build mwebd:
- cd /opt/android/cake_wallet/scripts/android/
- ./build_mwebd.sh --dont-install
-
- - name: Generate localization
+ - name: Fix github actions messing up $HOME...
+ run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
+ - uses: actions/checkout@v4
+ - name: configure git
run: |
- cd /opt/android/cake_wallet
- dart run tool/generate_localization.dart
-
- - name: Build generated code
- run: |
- cd /opt/android/cake_wallet
- ./model_generator.sh
-
+ git config --global user.email "ci@cakewallet.com"
+ git config --global user.name "CakeWallet CI"
- name: Add secrets
run: |
- cd /opt/android/cake_wallet
touch lib/.secrets.g.dart
touch cw_evm/lib/.secrets.g.dart
touch cw_solana/lib/.secrets.g.dart
touch cw_core/lib/.secrets.g.dart
touch cw_nano/lib/.secrets.g.dart
touch cw_tron/lib/.secrets.g.dart
- echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
- echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
- echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
- echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
- 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
+ if [[ "x${{ secrets.SALT }}" == "x" ]];
+ then
+ echo "const salt = '954f787f12622067f7e548d9450c3832';" > lib/.secrets.g.dart
+ else
+ echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.KEY_CHAIN_SALT }}" == "x" ]];
+ then
+ echo "const keychainSalt = '2d2beba777dbf7dff7013b7a';" >> lib/.secrets.g.dart
+ else
+ echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.KEY }}" == "x" ]];
+ then
+ echo "const key = '638e98820ec10a2945e968435c9397a3';" >> lib/.secrets.g.dart
+ else
+ echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.WALLET_SALT }}" == "x" ]];
+ then
+ echo "const walletSalt = '8f7f1b70';" >> lib/.secrets.g.dart
+ else
+ echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.SHORT_KEY }}" == "x" ]];
+ then
+ echo "const shortKey = '653f270c2c152bc7ec864afe';" >> lib/.secrets.g.dart
+ else
+ echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.BACKUP_SALT }}" == "x" ]];
+ then
+ echo "const backupSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
+ else
+ echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
+ fi
+ if [[ "x${{ secrets.BACKUP_KEY_CHAIN_SALT }}" == "x" ]];
+ then
+ echo "const backupKeychainSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
+ else
+ echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+ fi
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
@@ -144,8 +94,6 @@ jobs:
echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
- echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
- echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
@@ -156,8 +104,11 @@ jobs:
echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
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 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 exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
@@ -165,7 +116,6 @@ jobs:
echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
- echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
@@ -178,39 +128,172 @@ jobs:
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
- echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dar
+ echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dart
echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
+ # tests
+ echo "const moneroTestWalletSeeds ='${{ secrets.MONERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const moneroLegacyTestWalletSeeds = '${{ secrets.MONERO_LEGACY_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const bitcoinTestWalletSeeds = '${{ secrets.BITCOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const ethereumTestWalletSeeds = '${{ secrets.ETHEREUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const litecoinTestWalletSeeds = '${{ secrets.LITECOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const bitcoinCashTestWalletSeeds = '${{ secrets.BITCOIN_CASH_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const polygonTestWalletSeeds = '${{ secrets.POLYGON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const solanaTestWalletSeeds = '${{ secrets.SOLANA_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const tronTestWalletSeeds = '${{ secrets.TRON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const nanoTestWalletSeeds = '${{ secrets.NANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const wowneroTestWalletSeeds = '${{ secrets.WOWNERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
+ echo "const moneroTestWalletReceiveAddress = '${{ secrets.MONERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const bitcoinTestWalletReceiveAddress = '${{ secrets.BITCOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const ethereumTestWalletReceiveAddress = '${{ secrets.ETHEREUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const litecoinTestWalletReceiveAddress = '${{ secrets.LITECOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const bitcoinCashTestWalletReceiveAddress = '${{ secrets.BITCOIN_CASH_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const polygonTestWalletReceiveAddress = '${{ secrets.POLYGON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const solanaTestWalletReceiveAddress = '${{ secrets.SOLANA_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ echo "const tronTestWalletReceiveAddress = '${{ secrets.TRON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
+ 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
+ - name: prepare monero_c and cache
+ run: |
+ export MONEROC_HASH=$(cat scripts/prepare_moneroc.sh | grep 'git checkout' | xargs | awk '{ print $3 }')
+ echo MONEROC_HASH=$MONEROC_HASH >> /etc/environment
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
+ pushd scripts
+ ln -s "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
+ ./prepare_moneroc.sh
+ popd
+ pushd scripts/monero_c
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" || true
+ mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" || true
+
+ rm -rf "$PWD/contrib/depends/built" "$PWD/monero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
+ rm -rf "$PWD/contrib/depends/sources" "$PWD/monero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
+ mkdir -p contrib/depends || true
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" "$PWD/contrib/depends/built"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" "$PWD/monero/contrib/depends/built"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" "$PWD/contrib/depends/sources"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" "$PWD/monero/contrib/depends/sources"
+ ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
+ popd
- - name: Rename app
+ - name: Execute Build and Setup Commands
run: |
- echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+ pushd scripts/linux
+ source ./app_env.sh cakewallet
+ ./app_config.sh
+ popd
- - name: Build
+ - name: Build monero_c
+ run: |
+ pushd scripts/linux/
+ source ./app_env.sh cakewallet
+ ./build_monero_all.sh
+ popd
+
+ - name: Install Flutter dependencies
+ run: |
+ flutter pub get
+
+ - name: Build generated code
+ run: |
+ ./model_generator.sh async
+
+ - name: Generate localization
+ run: |
+ dart run tool/generate_localization.dart
+
+ - name: Build linux
run: |
- cd /opt/android/cake_wallet
flutter build linux --release
- - name: Prepare release zip file
+ - name: Compress release
run: |
- cd /opt/android/cake_wallet/build/linux/x64/release
- zip -r ${{env.BRANCH_NAME}}.zip bundle
+ pushd build/linux/x64/release
+ zip -r cakewallet_linux.zip bundle
+ popd
- - name: Upload Artifact
- uses: kittaakos/upload-artifact-as-is@v0
+ - name: Upload Artifact to github
+ uses: actions/upload-artifact@v4
with:
- path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
+ path: ${{ github.workspace }}/build/linux/x64/release/cakewallet_linux.zip
+ name: cakewallet_linux
+
+ - name: Prepare virtual desktop
+ if: ${{ contains(github.event.head_commit.message, 'run tests') }}
+ run: |
+ nohup Xvfb :99 -screen 0 720x1280x16 &
+ echo DISPLAY=:99 | sudo tee -a $GITHUB_ENV
+ dbus-daemon --system --fork
+ nohup NetworkManager &
+ nohup ffmpeg -framerate 60 -video_size 720x1280 -f x11grab -i :99 -c:v libx264 -c:a aac /opt/screen_grab.mkv &
-# Just as an artifact would be enough
-# - name: Send Test APK
-# continue-on-error: true
-# uses: adrey/slack-file-upload-action@1.0.5
-# with:
-# token: ${{ secrets.SLACK_APP_TOKEN }}
-# path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
-# channel: ${{ secrets.SLACK_APK_CHANNEL }}
-# title: "${{ env.BRANCH_NAME }}_linux.zip"
-# filename: ${{ env.BRANCH_NAME }}_linux.zip
-# initial_comment: ${{ github.event.head_commit.message }}
+ # Note for people adding tests:
+ # - Tests are ran on Linux, with some things being mocked out.
+ # - Screen recording is being provided for the entire length of the test, you can download it in github articats.
+ # - Screen recordeding is encrypted, look at step "Stop screen recording, encrypt and upload", and add your key if you want
+ # Reason for encryption is the fact that we restore the wallet from seed, and we don't want to leak that, while there
+ # isn't much in those wallets anyway, we still wouldn't like to leak it to anyone who is able to access github.
+
+ - name: Test [confirm_seeds_flow_test]
+ if: ${{ contains(github.event.head_commit.message, 'run tests') }}
+ timeout-minutes: 20
+ run: |
+ xmessage -timeout 30 "confirm_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/confirm_seeds_flow_test.dart
+ - name: Test [create_wallet_flow_test]
+ if: ${{ contains(github.event.head_commit.message, 'run tests') }}
+ timeout-minutes: 20
+ run: |
+ xmessage -timeout 30 "create_wallet_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/create_wallet_flow_test.dart
+ - name: Test [exchange_flow_test]
+ if: ${{ contains(github.event.head_commit.message, 'run tests') }}
+ timeout-minutes: 20
+ run: |
+ xmessage -timeout 30 "exchange_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/exchange_flow_test.dart
+ - name: Test [restore_wallet_through_seeds_flow_test]
+ if: ${{ contains(github.event.head_commit.message, 'run tests') }}
+ timeout-minutes: 20
+ run: |
+ 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: Stop screen recording, encrypt and upload
+ if: always()
+ run: |
+ if [[ ! -f "/opt/screen_grab.mkv" ]];
+ then
+ exit 0;
+ fi
+ killall ffmpeg
+ sleep 5
+ killall -9 ffmpeg || true
+ sleep 5
+ # Feel free to add your own public key if you wish
+ gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 6B3199AD9B3D23B8 # konstantin@cakewallet.com
+ gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 35C8DBAFB8D9ACAC # cyjan@mrcyjanek.net
+ gpg --trust-model always --encrypt --output /opt/screen_grab.mkv.gpg \
+ --recipient 6B3199AD9B3D23B8 \
+ --recipient 35C8DBAFB8D9ACAC \
+ /opt/screen_grab.mkv
+ rm /opt/screen_grab.mkv
+ mv /opt/screen_grab.mkv.gpg ./screen_grab.mkv.gpg
+ - name: Upload Artifact to github
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@v4
+ with:
+ path: ${{ github.workspace }}/screen_grab.mkv.gpg
+ name: tests_screen_grab
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 00d9241710..c8bd4b26c6 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
@@ -2,4 +2,5 @@
+
\ No newline at end of file
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 0000000000..27f939b416
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-mdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-mdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..7bdb298c12
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-xhdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-xhdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..79e9df08d8
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-xxhdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..0bb1c74308
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-xxxhdpi/ic_launcher_adaptive_mono.png b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..205f2ad2a5
Binary files /dev/null and b/assets/images/cakewallet_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png differ
diff --git a/assets/images/monerocom_android_icon/mipmap-anydpi-v26/ic_launcher.xml b/assets/images/monerocom_android_icon/mipmap-anydpi-v26/ic_launcher.xml
index 00d9241710..c8bd4b26c6 100644
--- a/assets/images/monerocom_android_icon/mipmap-anydpi-v26/ic_launcher.xml
+++ b/assets/images/monerocom_android_icon/mipmap-anydpi-v26/ic_launcher.xml
@@ -2,4 +2,5 @@
+
\ No newline at end of file
diff --git a/assets/images/monerocom_android_icon/mipmap-hdpi/ic_launcher_adaptive_mono.png b/assets/images/monerocom_android_icon/mipmap-hdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..af8126ea9f
Binary files /dev/null and b/assets/images/monerocom_android_icon/mipmap-hdpi/ic_launcher_adaptive_mono.png differ
diff --git a/assets/images/monerocom_android_icon/mipmap-mdpi/ic_launcher_adaptive_mono.png b/assets/images/monerocom_android_icon/mipmap-mdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..0778b841f1
Binary files /dev/null and b/assets/images/monerocom_android_icon/mipmap-mdpi/ic_launcher_adaptive_mono.png differ
diff --git a/assets/images/monerocom_android_icon/mipmap-xhdpi/ic_launcher_adaptive_mono.png b/assets/images/monerocom_android_icon/mipmap-xhdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..318914c59e
Binary files /dev/null and b/assets/images/monerocom_android_icon/mipmap-xhdpi/ic_launcher_adaptive_mono.png differ
diff --git a/assets/images/monerocom_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_mono.png b/assets/images/monerocom_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..b1165abe85
Binary files /dev/null and b/assets/images/monerocom_android_icon/mipmap-xxhdpi/ic_launcher_adaptive_mono.png differ
diff --git a/assets/images/monerocom_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png b/assets/images/monerocom_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png
new file mode 100644
index 0000000000..ea11a01d31
Binary files /dev/null and b/assets/images/monerocom_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png differ
diff --git a/build-guide-linux.md b/build-guide-linux.md
index 99c2ed0c84..df5f0f6017 100644
--- a/build-guide-linux.md
+++ b/build-guide-linux.md
@@ -115,7 +115,7 @@ Install Flutter package dependencies with this command:
> `$ ./cakewallet.sh`
> and back to project root directory:
> `$ cd ../..`
-> and fetch dependecies again
+> 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:
diff --git a/build-guide-win.md b/build-guide-win.md
index 6ace961af5..8cfd02c4ca 100644
--- a/build-guide-win.md
+++ b/build-guide-win.md
@@ -16,14 +16,14 @@ These steps will help you configure and execute a build of CakeWallet from its s
### 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 Windwos`, `Testing tools core features - Build Tools`, `C++ AddressSanitizer`.
+> [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 downlaod CakeWallet source code from our [GitHub repository](github.com/cake-tech/cake_wallet) via git by following next command:
+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)
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index d383162287..f57b0cf27d 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -452,7 +452,7 @@ abstract class ElectrumWalletBase
@action
@override
- Future startSync() async {
+ Future startSync({bool isBackgroundSync = false}) async {
try {
if (syncStatus is SyncronizingSyncStatus) {
return;
@@ -490,7 +490,7 @@ abstract class ElectrumWalletBase
@action
@override
- Future stopSync() async {
+ Future stopSync({bool isBackgroundSync = false}) async {
syncStatus = NotConnectedSyncStatus();
try {
await _receiveStream?.cancel();
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 44d1fa47a0..643f1ca230 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -302,7 +302,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
@action
@override
- Future startSync() async {
+ Future startSync({bool isBackgroundSync = false}) async {
printV("startSync() called!");
printV("STARTING SYNC - MWEB ENABLED: $mwebEnabled");
if (!mwebEnabled) {
@@ -437,7 +437,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
@action
@override
- Future stopSync() async {
+ Future stopSync({bool isBackgroundSync = false}) async {
printV("stopSync() called!");
_syncTimer?.cancel();
_utxoStream?.cancel();
diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart
index 16c794a25f..a895b35375 100644
--- a/cw_core/lib/wallet_base.dart
+++ b/cw_core/lib/wallet_base.dart
@@ -60,14 +60,16 @@ abstract class WalletBase walletInfo.isHardwareWallet;
+ Future init();
+
Future connectToNode({required Node node});
// there is a default definition here because only coins with a pow node (nano based) need to override this
Future connectToPowNode({required Node node}) async {}
- Future startSync();
+ Future startSync({bool isBackgroundSync = false});
- Future stopSync() async {}
+ Future stopSync({bool isBackgroundSync = false}) async {}
Future createTransaction(Object credentials);
@@ -100,4 +102,7 @@ abstract class WalletBase verifyMessage(String message, String signature, {String? address = null});
bool isTestnet = false;
+
+ // TODO: use proxy layer
+ Future reopenWallet() async {}
}
diff --git a/cw_evm/lib/evm_chain_wallet.dart b/cw_evm/lib/evm_chain_wallet.dart
index 9ccb05e7f3..b2c9640382 100644
--- a/cw_evm/lib/evm_chain_wallet.dart
+++ b/cw_evm/lib/evm_chain_wallet.dart
@@ -299,7 +299,7 @@ abstract class EVMChainWalletBase
@action
@override
- Future startSync() async {
+ Future startSync({bool isBackgroundSync = false}) async {
try {
syncStatus = AttemptingSyncStatus();
await _updateBalance();
diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart
index 537c9802e7..d6063069ce 100644
--- a/cw_monero/lib/api/wallet.dart
+++ b/cw_monero/lib/api/wallet.dart
@@ -9,6 +9,8 @@ import 'package:flutter/foundation.dart';
import 'package:monero/monero.dart' as monero;
import 'package:mutex/mutex.dart';
+bool debugMonero = false;
+
int getSyncingHeight() {
// final height = monero.MONERO_cw_WalletListener_height(getWlptr());
final h2 = monero.Wallet_blockChainHeight(wptr!);
@@ -32,8 +34,7 @@ String getFilename() => monero.Wallet_filename(wptr!);
String getSeed() {
// monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
- final cakepolyseed =
- monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
+ final cakepolyseed = monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
if (cakepolyseed != "") {
return cakepolyseed;
}
@@ -48,11 +49,21 @@ String getSeed() {
String getSeedLegacy(String? language) {
var legacy = monero.Wallet_seed(wptr!, seedOffset: '');
switch (language) {
- case "Chinese (Traditional)": language = "Chinese (simplified)"; break;
- case "Chinese (Simplified)": language = "Chinese (simplified)"; break;
- case "Korean": language = "English"; break;
- case "Czech": language = "English"; break;
- case "Japanese": language = "English"; break;
+ case "Chinese (Traditional)":
+ language = "Chinese (simplified)";
+ break;
+ case "Chinese (Simplified)":
+ language = "Chinese (simplified)";
+ break;
+ case "Korean":
+ language = "English";
+ break;
+ case "Czech":
+ language = "English";
+ break;
+ case "Japanese":
+ language = "English";
+ break;
}
if (monero.Wallet_status(wptr!) != 0) {
monero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
@@ -71,15 +82,22 @@ String getSeedLegacy(String? language) {
Map>> addressCache = {};
String getAddress({int accountIndex = 0, int addressIndex = 0}) {
- // printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
- while (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) {
+
+ int count = 0;
+
+ while (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex) - 1 < addressIndex) {
printV("adding subaddress");
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
+ if (count > 50) {
+ throw Exception("Failed to add subaddress");
+ }
+ count++;
}
+
addressCache[wptr!.address] ??= {};
addressCache[wptr!.address]![accountIndex] ??= {};
- addressCache[wptr!.address]![accountIndex]![addressIndex] ??= monero.Wallet_address(wptr!,
- accountIndex: accountIndex, addressIndex: addressIndex);
+ addressCache[wptr!.address]![accountIndex]![addressIndex] ??=
+ monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
return addressCache[wptr!.address]![accountIndex]![addressIndex]!;
}
@@ -132,9 +150,10 @@ Future setupNodeSync(
}
}
- if (kDebugMode) {
+ if (kDebugMode && debugMonero) {
monero.Wallet_init3(
- wptr!, argv0: '',
+ wptr!,
+ argv0: '',
defaultLogBaseName: 'moneroc',
console: true,
logPath: '',
@@ -149,17 +168,38 @@ void startRefreshSync() {
monero.Wallet_startRefresh(wptr!);
}
+void setupBackgroundSync(
+ {required int backgroundSyncType,
+ required String walletPassword,
+ required String backgroundCachePassword}) {
+ monero.Wallet_setupBackgroundSync(wptr!,
+ backgroundSyncType: backgroundSyncType,
+ walletPassword: walletPassword,
+ backgroundCachePassword: backgroundCachePassword);
+}
+
+bool isBackgroundSyncing() => monero.Wallet_isBackgroundSyncing(wptr!);
+
+void startBackgroundSync() {
+ monero.Wallet_startBackgroundSync(wptr!);
+}
+
+void stopBackgroundSync(String walletPassword) {
+ monero.Wallet_stopBackgroundSync(wptr!, walletPassword);
+}
+
+void stopSync() {
+ monero.Wallet_init(wptr!, daemonAddress: "");
+}
void setRefreshFromBlockHeight({required int height}) =>
- monero.Wallet_setRefreshFromBlockHeight(wptr!,
- refresh_from_block_height: height);
+ monero.Wallet_setRefreshFromBlockHeight(wptr!, refresh_from_block_height: height);
void setRecoveringFromSeed({required bool isRecovery}) =>
monero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery);
final storeMutex = Mutex();
-
int lastStorePointer = 0;
int lastStoreHeight = 0;
void storeSync({bool force = false}) async {
@@ -169,7 +209,7 @@ void storeSync({bool force = false}) async {
});
if (lastStorePointer == wptr!.address &&
lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) &&
- !synchronized &&
+ !synchronized &&
!force) {
return;
}
@@ -195,6 +235,10 @@ void closeCurrentWallet() {
monero.Wallet_stop(wptr!);
}
+void stopWallet() {
+ monero.Wallet_stop(wptr!);
+}
+
String getSecretViewKey() => monero.Wallet_secretViewKey(wptr!);
String getPublicViewKey() => monero.Wallet_publicViewKey(wptr!);
@@ -229,8 +273,7 @@ class SyncListener {
_cachedBlockchainHeight = 0;
_lastKnownBlockHeight = 0;
_initialSyncHeight = 0;
- _updateSyncInfoTimer ??=
- Timer.periodic(Duration(milliseconds: 1200), (_) async {
+ _updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: 1200), (_) async {
if (isNewTransactionExist()) {
onNewTransaction();
}
@@ -269,8 +312,8 @@ class SyncListener {
void stop() => _updateSyncInfoTimer?.cancel();
}
-SyncListener setListeners(void Function(int, int, double) onNewBlock,
- void Function() onNewTransaction) {
+SyncListener setListeners(
+ void Function(int, int, double) onNewBlock, void Function() onNewTransaction) {
final listener = SyncListener(onNewBlock, onNewTransaction);
// setListenerNative();
return listener;
@@ -332,8 +375,7 @@ String getSubaddressLabel(int accountIndex, int addressIndex) {
accountIndex: accountIndex, addressIndex: addressIndex);
}
-Future setTrustedDaemon(bool trusted) async =>
- monero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
+Future setTrustedDaemon(bool trusted) async => monero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
Future trustedDaemon() async => monero.Wallet_trustedDaemon(wptr!);
@@ -342,5 +384,6 @@ String signMessage(String message, {String address = ""}) {
}
bool verifyMessage(String message, String address, String signature) {
- return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
+ return monero.Wallet_verifySignedMessage(wptr!,
+ message: message, address: address, signature: signature);
}
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index fd596a3029..e46e18b9f0 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -39,6 +39,7 @@ import 'package:hive/hive.dart';
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
import 'package:mobx/mobx.dart';
import 'package:monero/monero.dart' as monero;
+import 'package:cw_monero/api/transaction_history.dart' as transaction_history;
part 'monero_wallet.g.dart';
@@ -137,6 +138,7 @@ abstract class MoneroWalletBase
Timer? _autoSaveTimer;
List unspentCoins;
String _password;
+ bool isBackgroundSyncing = false;
Future init() async {
await walletAddresses.init();
@@ -157,10 +159,12 @@ abstract class MoneroWalletBase
}
}
- _autoSaveTimer = Timer.periodic(
- Duration(seconds: _autoSaveInterval), (_) async => await save());
+ _autoSaveTimer?.cancel();
+ _autoSaveTimer =
+ Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
+
// update transaction details after restore
- walletAddresses.subaddressList.update(accountIndex: walletAddresses.account?.id??0);
+ walletAddresses.subaddressList.update(accountIndex: walletAddresses.account?.id ?? 0);
}
@override
@@ -172,6 +176,7 @@ abstract class MoneroWalletBase
_onAccountChangeReaction?.reaction.dispose();
_onTxHistoryChangeReaction?.reaction.dispose();
_autoSaveTimer?.cancel();
+ monero_wallet.stopWallet();
}
@override
@@ -196,27 +201,21 @@ abstract class MoneroWalletBase
}
@override
- Future startSync() async {
- try {
- _assertInitialHeight();
- } catch (_) {
- // our restore height wasn't correct, so lets see if using the backup works:
- try {
- await resetCache(name); // Resetting the cache removes the TX Keys and Polyseed
- _assertInitialHeight();
- } catch (e) {
- // we still couldn't get a valid height from the backup?!:
- // try to use the date instead:
- try {
- _setHeightFromDate();
- } catch (_) {
- // we still couldn't get a valid sync height :/
- }
- }
- }
-
+ Future startSync({bool isBackgroundSync = false}) async {
try {
syncStatus = AttemptingSyncStatus();
+ if (isBackgroundSync) {
+ monero_wallet.setupBackgroundSync(
+ backgroundSyncType: 2,
+ walletPassword: password,
+ backgroundCachePassword: "testing-cache-password",
+ );
+ monero_wallet.startBackgroundSync();
+ isBackgroundSyncing = true;
+ } else {
+ monero_wallet.stopBackgroundSync(password);
+ isBackgroundSyncing = false;
+ }
monero_wallet.startRefresh();
_setListeners();
_listener?.start();
@@ -258,19 +257,45 @@ abstract class MoneroWalletBase
}
bool needExportOutputs(int amount) {
+ if (int.tryParse(monero.Wallet_secretSpendKey(wptr!)) != 0) {
+ return false;
+ }
// viewOnlyBalance - balance that we can spend
// TODO(mrcyjanek): remove hasUnknownKeyImages when we cleanup coin control
- return (monero.Wallet_viewOnlyBalance(wptr!,
- accountIndex: walletAddresses.account!.id) < amount) ||
- monero.Wallet_hasUnknownKeyImages(wptr!);
+ return (monero.Wallet_viewOnlyBalance(wptr!, accountIndex: walletAddresses.account!.id) <
+ amount) ||
+ monero.Wallet_hasUnknownKeyImages(wptr!);
}
@override
- Future stopSync() async {
+ Future stopSync({bool isBackgroundSync = false}) async {
syncStatus = NotConnectedSyncStatus();
_listener?.stop();
- // TODO: find a better way to stop syncing than setting an invalid address:
- monero_wallet.setupNode(address: "");
+ if (isBackgroundSync) {
+ isBackgroundSyncing = false;
+ monero_wallet.stopWallet();
+ monero_wallet.stopBackgroundSync(password);
+ return;
+ }
+ monero_wallet.stopSync();
+ _autoSaveTimer?.cancel();
+ monero_wallet.closeCurrentWallet();
+ }
+
+ @override
+ Future reopenWallet() async {
+ printV("closing wallet");
+ final currentWalletDirPath = await pathForWalletDir(name: name, type: type);
+ final wmaddr = wmPtr.address;
+ final waddr = openedWalletsByPath["$currentWalletDirPath/$name"]!.address;
+ await Isolate.run(() {
+ monero.WalletManager_closeWallet(
+ Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
+ });
+ wptr = monero.WalletManager_openWallet(wmPtr, path: currentWalletDirPath, password: password);
+ openedWalletsByPath["$currentWalletDirPath/$name"] = wptr!;
+ transaction_history.txhistory = null;
+
}
@override
@@ -279,8 +304,8 @@ abstract class MoneroWalletBase
final inputs = [];
final outputs = _credentials.outputs;
final hasMultiDestination = outputs.length > 1;
- final unlockedBalance = monero_wallet.getUnlockedBalance(
- accountIndex: walletAddresses.account!.id);
+ final unlockedBalance =
+ monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
PendingTransactionDescription pendingTransactionDescription;
@@ -310,8 +335,7 @@ abstract class MoneroWalletBase
throw MoneroTransactionCreationException('You do not have enough XMR to send this amount.');
}
- if (inputs.isEmpty) MoneroTransactionCreationException(
- 'No inputs selected');
+ if (inputs.isEmpty) MoneroTransactionCreationException('No inputs selected');
final moneroOutputs = outputs.map((output) {
final outputAddress = output.isParsedAddress ? output.extractedAddress : output.address;
@@ -327,10 +351,8 @@ abstract class MoneroWalletBase
preferredInputs: inputs);
} else {
final output = outputs.first;
- final address =
- output.isParsedAddress ? output.extractedAddress : output.address;
- final amount =
- output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
+ final address = output.isParsedAddress ? output.extractedAddress : output.address;
+ final amount = output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
// if ((formattedAmount != null && unlockedBalance < formattedAmount) ||
// (formattedAmount == null && unlockedBalance <= 0)) {
@@ -340,15 +362,13 @@ abstract class MoneroWalletBase
// 'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
// }
- if (inputs.isEmpty) MoneroTransactionCreationException(
- 'No inputs selected');
- pendingTransactionDescription =
- await transaction_history.createTransaction(
- address: address!,
- amount: amount,
- priorityRaw: _credentials.priority.serialize(),
- accountIndex: walletAddresses.account!.id,
- preferredInputs: inputs);
+ if (inputs.isEmpty) MoneroTransactionCreationException('No inputs selected');
+ pendingTransactionDescription = await transaction_history.createTransaction(
+ address: address!,
+ amount: amount,
+ priorityRaw: _credentials.priority.serialize(),
+ accountIndex: walletAddresses.account!.id,
+ preferredInputs: inputs);
}
// final status = monero.PendingTransaction_status(pendingTransactionDescription);
@@ -382,7 +402,7 @@ abstract class MoneroWalletBase
Future save() async {
await walletAddresses.updateUsedSubaddress();
- if (isEnabledAutoGenerateSubaddress) {
+ if (isEnabledAutoGenerateSubaddress && !isBackgroundSyncing) {
walletAddresses.updateUnusedSubaddress(
accountIndex: walletAddresses.account?.id ?? 0,
defaultLabel: walletAddresses.account?.label ?? '');
@@ -500,7 +520,8 @@ abstract class MoneroWalletBase
for (var i = 0; i < coinCount; i++) {
final coin = getCoin(i);
final coinSpent = monero.CoinsInfo_spent(coin);
- if (coinSpent == false && monero.CoinsInfo_subaddrAccount(coin) == walletAddresses.account!.id) {
+ if (coinSpent == false &&
+ monero.CoinsInfo_subaddrAccount(coin) == walletAddresses.account!.id) {
final unspent = MoneroUnspent(
monero.CoinsInfo_address(coin),
monero.CoinsInfo_hash(coin),
@@ -602,8 +623,7 @@ abstract class MoneroWalletBase
Future