diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
deleted file mode 100644
index cb2afa396..000000000
--- 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 cdd0e40b4..c5f875128 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
+ - name: Fix github actions messing up $HOME...
+ run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
+ - uses: actions/checkout@v4
+ - name: configure git
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
- 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: Generate KeyStore
+ run: |
+ 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
+
+ - name: Execute Build and Setup Commands
+ run: |
+ 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
+
+ - 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: |
+ ./model_generator.sh async
+
+ - name: Generate key properties
+ run: |
+ dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
+
+ - name: Generate localization
+ run: |
+ dart run tool/generate_localization.dart
- name: Rename app
run: |
- echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+ 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
- # Step 3: Download previous build number
- - name: Download previous build number
- id: download-build-number
- run: |
- # Download the artifact if it exists
- if [[ ! -f build_number.txt ]]; then
- echo "1" > build_number.txt
- fi
-
- # Step 4: Read and Increment Build Number
- - name: Increment Build Number
- id: increment-build-number
- run: |
- # Read current build number from file
- BUILD_NUMBER=$(cat build_number.txt)
- BUILD_NUMBER=$((BUILD_NUMBER + 1))
- echo "New build number: $BUILD_NUMBER"
-
- # Save the incremented build number
- echo "$BUILD_NUMBER" > build_number.txt
-
- # Export the build number to use in later steps
- echo "BUILD_NUMBER=$BUILD_NUMBER" >> $GITHUB_ENV
-
- # Step 5: Update pubspec.yaml with new build number
- - name: Update build number
- run: |
- cd /opt/android/cake_wallet
- sed -i "s/^version: .*/version: 1.0.$BUILD_NUMBER/" pubspec.yaml
+ 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
+ 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: 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
-
- - 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 891327d1e..345c95c4f 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
+ - name: Fix github actions messing up $HOME...
+ run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
+ - uses: actions/checkout@v4
+ - name: configure git
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
- 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
-
- - name: Rename app
+ # 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: |
- echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+ 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
- - name: Build
+ 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: Execute Build and Setup Commands
+ run: |
+ pushd scripts/linux
+ source ./app_env.sh cakewallet
+ ./app_config.sh
+ popd
+
+ - 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
-# 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 }}
+ - 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 &
+
+ # 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 00d924171..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
@@ -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 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-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-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-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-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/monerocom_android_icon/mipmap-anydpi-v26/ic_launcher.xml b/assets/images/monerocom_android_icon/mipmap-anydpi-v26/ic_launcher.xml
index 00d924171..c8bd4b26c 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 000000000..af8126ea9
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 000000000..0778b841f
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 000000000..318914c59
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 000000000..b1165abe8
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 000000000..ea11a01d3
Binary files /dev/null and b/assets/images/monerocom_android_icon/mipmap-xxxhdpi/ic_launcher_adaptive_mono.png differ
diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt
index 3a6706a26..09092a8df 100644
--- a/assets/text/Monerocom_Release_Notes.txt
+++ b/assets/text/Monerocom_Release_Notes.txt
@@ -1,3 +1,2 @@
-Support Monero Ledger
-Bug fixes
-New designs and better user experience
\ No newline at end of file
+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 f7d5e4d2c..8abed72a2 100644
--- a/assets/text/Release_Notes.txt
+++ b/assets/text/Release_Notes.txt
@@ -1,5 +1,4 @@
-Support Monero Ledger
-Prepare for Haven removal
-Improve Ethereum and Polygon sending process
-Bug fixes
-New designs and better user experience
\ No newline at end of file
+Bitcoin and Litecoin enhancements
+Solana and Nano fixes/improvements
+UI enhancements
+Bug fixes
\ No newline at end of file
diff --git a/build-guide-linux.md b/build-guide-linux.md
index 99c2ed0c8..df5f0f601 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 6ace961af..8cfd02c4c 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_core/lib/node.dart b/cw_core/lib/node.dart
index 7d0c2411f..7b3294043 100644
--- a/cw_core/lib/node.dart
+++ b/cw_core/lib/node.dart
@@ -1,13 +1,18 @@
import 'dart:io';
+import 'dart:math';
import 'package:cw_core/keyable.dart';
+import 'package:cw_core/utils/print_verbose.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:hive/hive.dart';
import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:http/io_client.dart' as ioc;
+import 'dart:math' as math;
+import 'package:convert/convert.dart';
+import 'package:crypto/crypto.dart' as crypto;
-// import 'package:tor/tor.dart';
+import 'package:crypto/crypto.dart';
part 'node.g.dart';
@@ -170,34 +175,43 @@ class Node extends HiveObject with Keyable {
}
Future requestMoneroNode() async {
- if (uri.toString().contains(".onion") || useSocksProxy) {
+ if (useSocksProxy) {
return await requestNodeWithProxy();
}
+
+
final path = '/json_rpc';
final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
- final realm = 'monero-rpc';
final body = {'jsonrpc': '2.0', 'id': '0', 'method': 'get_info'};
+
try {
final authenticatingClient = HttpClient();
-
authenticatingClient.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
- authenticatingClient.addCredentials(
- rpcUri,
- realm,
- HttpClientDigestCredentials(login ?? '', password ?? ''),
- );
final http.Client client = ioc.IOClient(authenticatingClient);
+ final jsonBody = json.encode(body);
+
final response = await client.post(
rpcUri,
headers: {'Content-Type': 'application/json'},
- body: json.encode(body),
+ body: jsonBody,
);
- client.close();
+ // Check if we received a 401 Unauthorized response
+ if (response.statusCode == 401) {
+ final daemonRpc = DaemonRpc(
+ rpcUri.toString(),
+ username: login??'',
+ password: password??'',
+ );
+ final response = await daemonRpc.call('get_info', {});
+ return !(response['offline'] as bool);
+ }
+
+ printV("node check response: ${response.body}");
if ((response.body.contains("400 Bad Request") // Some other generic error
||
@@ -225,7 +239,8 @@ class Node extends HiveObject with Keyable {
final resBody = json.decode(response.body) as Map;
return !(resBody['result']['offline'] as bool);
- } catch (_) {
+ } catch (e) {
+ printV("error: $e");
return false;
}
}
@@ -316,3 +331,150 @@ class Node extends HiveObject with Keyable {
}
}
}
+
+/// https://github.com/ManyMath/digest_auth/
+/// HTTP Digest authentication.
+///
+/// Adapted from https://github.com/dart-lang/http/issues/605#issue-963962341.
+///
+/// Created because http_auth was not working for Monero daemon RPC responses.
+class DigestAuth {
+ final String username;
+ final String password;
+ String? realm;
+ String? nonce;
+ String? uri;
+ String? qop = "auth";
+ int _nonceCount = 0;
+
+ DigestAuth(this.username, this.password);
+
+ /// Initialize Digest parameters from the `WWW-Authenticate` header.
+ void initFromAuthorizationHeader(String authInfo) {
+ final Map? values = _splitAuthenticateHeader(authInfo);
+ if (values != null) {
+ realm = values['realm'];
+ // Check if the nonce has changed.
+ if (nonce != values['nonce']) {
+ nonce = values['nonce'];
+ _nonceCount = 0; // Reset nonce count when nonce changes.
+ }
+ }
+ }
+
+ /// Generate the Digest Authorization header.
+ String getAuthString(String method, String uri) {
+ this.uri = uri;
+ _nonceCount++;
+ String cnonce = _computeCnonce();
+ String nc = _formatNonceCount(_nonceCount);
+
+ String ha1 = md5Hash("$username:$realm:$password");
+ String ha2 = md5Hash("$method:$uri");
+ String response = md5Hash("$ha1:$nonce:$nc:$cnonce:$qop:$ha2");
+
+ return 'Digest username="$username", realm="$realm", nonce="$nonce", uri="$uri", qop=$qop, nc=$nc, cnonce="$cnonce", response="$response"';
+ }
+
+ /// Helper to parse the `WWW-Authenticate` header.
+ Map? _splitAuthenticateHeader(String? header) {
+ if (header == null || !header.startsWith('Digest ')) {
+ return null;
+ }
+ String token = header.substring(7); // Remove 'Digest '.
+ final Map result = {};
+
+ final components = token.split(',').map((token) => token.trim());
+ for (final component in components) {
+ final kv = component.split('=');
+ final key = kv[0];
+ final value = kv.sublist(1).join('=').replaceAll('"', '');
+ result[key] = value;
+ }
+ return result;
+ }
+
+ /// Helper to compute a random cnonce.
+ String _computeCnonce() {
+ final math.Random rnd = math.Random();
+ final List values = List.generate(16, (i) => rnd.nextInt(256));
+ return hex.encode(values);
+ }
+
+ /// Helper to format the nonce count.
+ String _formatNonceCount(int count) =>
+ count.toRadixString(16).padLeft(8, '0');
+
+ /// Compute the MD5 hash of a string.
+ String md5Hash(String input) {
+ return md5.convert(utf8.encode(input)).toString();
+ }
+}
+
+class DaemonRpc {
+ final String rpcUrl;
+ final String username;
+ final String password;
+
+ DaemonRpc(this.rpcUrl, {required this.username, required this.password});
+
+ /// Perform a JSON-RPC call with Digest Authentication.
+ Future