Merge branch 'main' into electrum-sp-refactors

This commit is contained in:
Omar Hatem 2024-12-20 17:05:57 +02:00 committed by GitHub
commit dded5a78f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 547 additions and 490 deletions

View file

@ -4,7 +4,7 @@ contact_links:
url: https://github.com/cake-tech/cake_wallet/discussions/new?category=feature-requests
about: Suggest an idea for Cake Wallet
- name: Not sure where to start?
url: https://guides.cakewallet.com
url: https://docs.cakewallet.com
about: Start by reading checking out the guides!
- name: Need help?
url: https://cakewallet.com/#contact

View file

@ -1,298 +1,298 @@
#name: Automated Integration Tests
#
#on:
# pull_request:
# branches: [main, CW-659-Transaction-History-Automated-Tests]
# workflow_dispatch:
# inputs:
# branch:
# description: "Branch name to build"
# required: true
# default: "main"
#
#jobs:
# Automated_integration_test:
# runs-on: ubuntu-20.04
# strategy:
# fail-fast: false
# matrix:
# api-level: [29]
# # arch: [x86, x86_64]
# 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: 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 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 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: Generate key properties
# run: |
# cd /opt/android/cake_wallet
# flutter packages pub 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
# flutter packages pub run tool/generate_localization.dart
#
# - name: Build generated code
# run: |
# cd /opt/android/cake_wallet
# ./model_generator.sh
#
# - 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
# echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
# echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
# echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
# echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
# echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
# echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
# echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
# 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 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
# echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
# echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
# echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
# echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart
# echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
# echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
# echo "const ankrApiKey = '${{ secrets.ANKR_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 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
# echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
# 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 ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
# echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
# echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
# echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
# echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
# echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
# echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
# echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
# 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.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
# 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: Rename app
# run: |
# echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
#
# - name: Build
# run: |
# cd /opt/android/cake_wallet
# flutter build apk --release --split-per-abi
#
# # - name: Rename apk file
# # run: |
# # cd /opt/android/cake_wallet/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/
#
# # - 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/app/outputs/flutter-apk/test-apk/${{env.BRANCH_NAME}}.apk
# # channel: ${{ secrets.SLACK_APK_CHANNEL }}
# # title: "${{ env.BRANCH_NAME }}.apk"
# # filename: ${{ env.BRANCH_NAME }}.apk
# # initial_comment: ${{ github.event.head_commit.message }}
#
# - name: 🦾 Enable KVM
# run: |
# echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
# sudo udevadm control --reload-rules
# sudo udevadm trigger --name-match=kvm
#
# - name: 🦾 Cache gradle
# uses: gradle/actions/setup-gradle@v3
#
# - name: 🦾 Cache AVD
# uses: actions/cache@v4
# id: avd-cache
# with:
# path: |
# ~/.android/avd/*
# ~/.android/adb*
# key: avd-${{ matrix.api-level }}
#
# - name: 🦾 Create AVD and generate snapshot for caching
# if: steps.avd-cache.outputs.cache-hit != 'true'
# uses: reactivecircus/android-emulator-runner@v2
# with:
# api-level: ${{ matrix.api-level }}
# force-avd-creation: false
# # arch: ${{ matrix.arch }}
# emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
# working-directory: /opt/android/cake_wallet
# disable-animations: false
# script: echo "Generated AVD snapshot for caching."
#
# - name: 🚀 Integration tests on Android Emulator
# uses: reactivecircus/android-emulator-runner@v2
# with:
# api-level: ${{ matrix.api-level }}
# force-avd-creation: false
# emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
# disable-animations: true
# working-directory: /opt/android/cake_wallet
# script: |
# chmod a+rx integration_test_runner.sh
# ./integration_test_runner.sh
name: Automated Integration Tests
on:
# pull_request:
# branches: [main, CW-659-Transaction-History-Automated-Tests]
workflow_dispatch:
inputs:
branch:
description: "Branch name to build"
required: true
default: "main"
jobs:
Automated_integration_test:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
api-level: [29]
# arch: [x86, x86_64]
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: 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 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 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: Generate key properties
run: |
cd /opt/android/cake_wallet
flutter packages pub 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
flutter packages pub run tool/generate_localization.dart
- name: Build generated code
run: |
cd /opt/android/cake_wallet
./model_generator.sh
- 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
echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
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 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
echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart
echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
echo "const ankrApiKey = '${{ secrets.ANKR_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 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
echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
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 ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
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.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
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: Rename app
run: |
echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
- name: Build
run: |
cd /opt/android/cake_wallet
flutter build apk --release --split-per-abi
# - name: Rename apk file
# run: |
# cd /opt/android/cake_wallet/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/
# - 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/app/outputs/flutter-apk/test-apk/${{env.BRANCH_NAME}}.apk
# channel: ${{ secrets.SLACK_APK_CHANNEL }}
# title: "${{ env.BRANCH_NAME }}.apk"
# filename: ${{ env.BRANCH_NAME }}.apk
# initial_comment: ${{ github.event.head_commit.message }}
- name: 🦾 Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: 🦾 Cache gradle
uses: gradle/actions/setup-gradle@v3
- name: 🦾 Cache AVD
uses: actions/cache@v4
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ matrix.api-level }}
- name: 🦾 Create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
force-avd-creation: false
# arch: ${{ matrix.arch }}
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
working-directory: /opt/android/cake_wallet
disable-animations: false
script: echo "Generated AVD snapshot for caching."
- name: 🚀 Integration tests on Android Emulator
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
working-directory: /opt/android/cake_wallet
script: |
chmod a+rx integration_test_runner.sh
./integration_test_runner.sh

BIN
assets/images/discord.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
assets/images/discourse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View file

@ -1,10 +1,10 @@
-
uri: rpc.ankr.com
is_default: true
useSSL: true
-
uri: api.mainnet-beta.solana.com:443
useSSL: true
-
uri: solana-rpc.publicnode.com:443
useSSL: true
useSSL: true
is_default: true

View file

@ -1,2 +1,3 @@
UI/UX enhancements
Bug fixes and app improvements
Support Monero Ledger
Bug fixes
New designs and better user experience

View file

@ -1,2 +1,5 @@
UI/UX enhancements
Bug fixes and app improvements
Support Monero Ledger
Prepare for Haven removal
Improve Ethereum and Polygon sending process
Bug fixes
New designs and better user experience

View file

@ -4,9 +4,8 @@
useSSL: true
-
uri: api.trongrid.io
is_default: false
is_default: true
useSSL: true
-
uri: trx.nownodes.io
is_default: true
useSSL: true

View file

@ -843,6 +843,7 @@ abstract class ElectrumWalletBase
)..addListener((transaction) async {
transactionHistory.addOne(transaction);
await updateBalance();
await updateAllUnspents();
});
}
@ -923,6 +924,7 @@ abstract class ElectrumWalletBase
.removeWhere((utxo) => estimatedTx.utxos.any((e) => e.utxo.txHash == utxo.hash));
await updateBalance();
await updateAllUnspents();
});
} catch (e, s) {
print([e, s]);
@ -1591,6 +1593,7 @@ abstract class ElectrumWalletBase
});
transactionHistory.addOne(transaction);
await updateBalance();
await updateAllUnspents();
});
} catch (e) {
throw e;

View file

@ -781,6 +781,13 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
if (!mwebEnabled) return false;
if (!tx.isPending) return false;
final isMwebTx = (tx.inputAddresses?.any((addr) => addr.contains("mweb")) ?? false) ||
(tx.outputAddresses?.any((addr) => addr.contains("mweb")) ?? false);
if (!isMwebTx) {
return false;
}
final outputId = <String>[], target = <String>{};
final isHash = RegExp(r'^[a-f0-9]{64}$').hasMatch;
final spendingOutputIds = tx.inputAddresses?.where(isHash) ?? [];

View file

@ -27,7 +27,7 @@ class TransactionCommitFailed implements Exception {
@override
String toString() {
return errorMessage??"unknown error";
return errorMessage ?? "unknown error";
}
}
@ -44,3 +44,11 @@ class TransactionCommitFailedBIP68Final implements Exception {}
class TransactionCommitFailedLessThanMin implements Exception {}
class TransactionInputNotSupported implements Exception {}
class SignNativeTokenTransactionRentException implements Exception {}
class CreateAssociatedTokenAccountException implements Exception {}
class SignSPLTokenTransactionRentException implements Exception {}
class NoAssociatedTokenAccountException implements Exception {}

View file

@ -716,10 +716,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
url: "https://pub.dev"
source: hosted
version: "14.2.5"
version: "14.2.4"
watcher:
dependency: "direct overridden"
description:

View file

@ -829,10 +829,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
url: "https://pub.dev"
source: hosted
version: "14.2.5"
version: "14.2.4"
watcher:
dependency: "direct overridden"
description:

View file

@ -874,10 +874,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
url: "https://pub.dev"
source: hosted
version: "14.2.5"
version: "14.2.4"
watcher:
dependency: "direct overridden"
description:

View file

@ -22,11 +22,11 @@ class PolygonClient extends EVMChainClient {
from: from,
to: to,
value: amount,
data: data,
// data: data,
maxGas: maxGas,
gasPrice: gasPrice,
maxFeePerGas: maxFeePerGas,
maxPriorityFeePerGas: maxPriorityFeePerGas,
// gasPrice: gasPrice,
// maxFeePerGas: maxFeePerGas,
// maxPriorityFeePerGas: maxPriorityFeePerGas,
);
}

View file

@ -1,4 +1,5 @@
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/exceptions.dart';
class SolanaTransactionCreationException implements Exception {
final String exceptionMessage;
@ -20,18 +21,19 @@ class SolanaTransactionWrongBalanceException implements Exception {
String toString() => exceptionMessage;
}
class SolanaSignNativeTokenTransactionRentException implements Exception {}
class SolanaCreateAssociatedTokenAccountException implements Exception {
final String exceptionMessage;
class SolanaSignNativeTokenTransactionRentException
extends SignNativeTokenTransactionRentException {}
class SolanaCreateAssociatedTokenAccountException extends CreateAssociatedTokenAccountException {
SolanaCreateAssociatedTokenAccountException(this.exceptionMessage);
final String exceptionMessage;
}
class SolanaSignSPLTokenTransactionRentException implements Exception {}
class SolanaSignSPLTokenTransactionRentException extends SignSPLTokenTransactionRentException {}
class SolanaNoAssociatedTokenAccountException implements Exception {
const SolanaNoAssociatedTokenAccountException(this.account, this.mint);
class SolanaNoAssociatedTokenAccountException extends NoAssociatedTokenAccountException {
SolanaNoAssociatedTokenAccountException(this.account, this.mint);
final String account;
final String mint;

View file

@ -757,10 +757,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
url: "https://pub.dev"
source: hosted
version: "14.2.5"
version: "14.2.4"
watcher:
dependency: "direct overridden"
description:

View file

@ -1,13 +1,11 @@
import 'dart:convert';
import 'dart:io' show Directory, File, Platform;
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/haven_seed_store.dart';
import 'package:cake_wallet/haven/haven.dart';
import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cw_core/root_dir.dart';
@ -42,8 +40,8 @@ const polygonDefaultNodeUri = 'polygon-bor.publicnode.com';
const cakeWalletBitcoinCashDefaultNodeUri = 'bitcoincash.stackwallet.com:50002';
const nanoDefaultNodeUri = 'nano.nownodes.io';
const nanoDefaultPowNodeUri = 'rpc.nano.to';
const solanaDefaultNodeUri = 'rpc.ankr.com';
const tronDefaultNodeUri = 'trx.nownodes.io';
const solanaDefaultNodeUri = 'solana-rpc.publicnode.com:443';
const tronDefaultNodeUri = 'api.trongrid.io';
const newCakeWalletBitcoinUri = 'btc-electrum.cakewallet.com:50002';
const wowneroDefaultNodeUri = 'node3.monerodevs.org:34568';
const moneroWorldNodeUri = '.moneroworld.com';
@ -311,6 +309,27 @@ Future<void> defaultSettingsMigration(
type: WalletType.ethereum,
useSSL: true,
);
_changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.tron,
newDefaultUri: tronDefaultNodeUri,
currentNodePreferenceKey: PreferencesKey.currentTronNodeIdKey,
useSSL: true,
oldUri: [
'tron-rpc.publicnode.com:443',
'trx.nownodes.io',
],
);
_changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.solana,
newDefaultUri: solanaDefaultNodeUri,
currentNodePreferenceKey: PreferencesKey.currentSolanaNodeIdKey,
useSSL: true,
oldUri: ['rpc.ankr.com'],
);
default:
break;
}
@ -332,6 +351,7 @@ Future<void> _backupHavenSeeds(Box<HavenSeedStore> havenSeedStore) async {
}
return;
}
/// generic function for changing any wallet default node
/// instead of making a new function for each change
Future<void> _changeDefaultNode({

View file

@ -134,6 +134,7 @@ class AddressResolver {
Future<ParsedAddress> resolve(BuildContext context, String text, CryptoCurrency currency) async {
final ticker = currency.title;
try {
// twitter handle example: @username
if (text.startsWith('@') && !text.substring(1).contains('@')) {
if (settingsStore.lookupsTwitter) {
final formattedName = text.substring(1);
@ -165,6 +166,7 @@ class AddressResolver {
}
}
// Mastodon example: @username@hostname.xxx
if (text.startsWith('@') && text.contains('@', 1) && text.contains('.', 1)) {
if (settingsStore.lookupsMastodon) {
final subText = text.substring(1);

View file

@ -92,6 +92,7 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
late StreamSubscription<LedgerDevice>? _bleRefresh = null;
bool longWait = false;
Timer? _longWaitTimer;
@override
void initState() {
@ -108,7 +109,7 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
Timer.periodic(Duration(seconds: 1), (_) => _refreshUsbDevices());
}
Future.delayed(Duration(seconds: 10), () {
_longWaitTimer = Timer(Duration(seconds: 10), () {
if (widget.ledgerVM.bleIsEnabled && bleDevices.isEmpty)
setState(() => longWait = true);
});
@ -121,6 +122,7 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
_bleStateTimer?.cancel();
_usbRefreshTimer?.cancel();
_bleRefresh?.cancel();
_longWaitTimer?.cancel();
widget.ledgerVM.stopScanning();
super.dispose();
@ -206,7 +208,8 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
offstage: !longWait,
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20, bottom: 20),
child: Text(S.of(context).if_you_dont_see_your_device,
child: Text(
S.of(context).if_you_dont_see_your_device,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
@ -235,7 +238,6 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
),
),
),
if (bleDevices.length > 0) ...[
Padding(
padding: EdgeInsets.only(left: 20, right: 20, bottom: 20),
@ -277,7 +279,9 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
color: Theme.of(context)
.extension<CakeTextTheme>()!
.titleColor,
),
),
),
@ -299,8 +303,12 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
if (widget.allowChangeWallet) ...[
PrimaryButton(
text: S.of(context).wallets,
color: Theme.of(context).extension<WalletListTheme>()!.createNewWalletButtonBackgroundColor,
textColor: Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor,
color: Theme.of(context)
.extension<WalletListTheme>()!
.createNewWalletButtonBackgroundColor,
textColor: Theme.of(context)
.extension<WalletListTheme>()!
.restoreWalletButtonTextColor,
onPressed: _onChangeWallet,
)
],

View file

@ -481,7 +481,7 @@ class CryptoBalanceWidget extends StatelessWidget {
behavior: HitTestBehavior.opaque,
onTap: () => launchUrl(
Uri.parse(
"https://guides.cakewallet.com/docs/cryptos/litecoin/#mweb"),
"https://docs.cakewallet.com/cryptos/litecoin/#mweb"),
mode: LaunchMode.externalApplication,
),
child: Text(

View file

@ -71,7 +71,7 @@ class SeedVerificationStepView extends StatelessWidget {
return GestureDetector(
onTap: () async {
final isCorrectWord = walletSeedViewModel.isChosenWordCorrect(option);
final isSecondWrongEntry = walletSeedViewModel.wrongEntries == 2;
final isSecondWrongEntry = walletSeedViewModel.wrongEntries >= 2;
if (!isCorrectWord) {
await showBar<void>(
context,

View file

@ -25,7 +25,7 @@ class WelcomePage extends BasePage {
@override
Widget trailing(BuildContext context) {
final Uri _url = Uri.parse('https://guides.cakewallet.com/docs/basic-features/basic-features/');
final Uri _url = Uri.parse('https://docs.cakewallet.com/get-started/setup/create-first-wallet/');
return IconButton(
icon: Icon(Icons.info_outline),
onPressed: () async {

View file

@ -221,7 +221,7 @@ class ExceptionHandler {
// just ignoring until we find a solution to this issue or migrate from flutter secure storage
"core/auth_service.dart:63",
"core/key_service.dart:14",
"core/wallet_loading_service.dart:132",
"core/wallet_loading_service.dart:133",
];
static Future<void> _addDeviceInfo(File file) async {

View file

@ -99,47 +99,54 @@ abstract class LedgerViewModelBase with Store {
}
Future<void> connectLedger(sdk.LedgerDevice device, WalletType type) async {
_isConnecting = true;
_connectingWalletType = type;
if (isConnected) {
try {
await _connectionChangeListener?.cancel();
_connectionChangeListener = null;
await _connection!.disconnect().catchError((_) {});
} catch (_) {}
}
final ledger = device.connectionType == sdk.ConnectionType.ble
? ledgerPlusBLE
: ledgerPlusUSB;
if (_connectionChangeListener == null) {
_connectionChangeListener = ledger.deviceStateChanges.listen((event) {
printV('Ledger Device State Changed: $event');
if (event == sdk.BleConnectionState.disconnected) {
_connection = null;
if (type == WalletType.monero) {
monero!.resetLedgerConnection();
Navigator.of( navigatorKey.currentContext!).pushNamed(
Routes.connectDevices,
arguments: ConnectDevicePageParams(
walletType: WalletType.monero,
allowChangeWallet: true,
isReconnect: true,
onConnectDevice: (context, ledgerVM) async {
Navigator.of(context).pop();
},
),
);
}
}
});
if (_connectionChangeSubscription == null) {
_connectionChangeSubscription = ledger.deviceStateChanges
.listen(_connectionChangeListener);
}
_connection = await ledger.connect(device);
_isConnecting = false;
}
StreamSubscription<sdk.BleConnectionState>? _connectionChangeListener;
StreamSubscription<sdk.BleConnectionState>? _connectionChangeSubscription;
sdk.LedgerConnection? _connection;
bool _isConnecting = true;
WalletType? _connectingWalletType;
void _connectionChangeListener(
sdk.BleConnectionState event, ) {
printV('Ledger Device State Changed: $event');
if (event == sdk.BleConnectionState.disconnected && !_isConnecting) {
_connection = null;
if (_connectingWalletType == WalletType.monero) {
monero!.resetLedgerConnection();
Navigator.of(navigatorKey.currentContext!).pushNamed(
Routes.connectDevices,
arguments: ConnectDevicePageParams(
walletType: WalletType.monero,
allowChangeWallet: true,
isReconnect: true,
onConnectDevice: (context, ledgerVM) async {
Navigator.of(context).pop();
},
),
);
}
}
}
bool get isConnected => _connection != null && !(_connection!.isDisconnected);

View file

@ -26,8 +26,6 @@ import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/unspent_coin_type.dart';
import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cake_wallet/view_model/send/send_template_view_model.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_solana/solana_exceptions.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
@ -100,6 +98,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
outputs
.add(Output(wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
unspentCoinsListViewModel.initialSetup();
}
@observable
@ -684,19 +684,19 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
}
}
if (error is SolanaSignNativeTokenTransactionRentException) {
if (error is SignNativeTokenTransactionRentException) {
return S.current.solana_sign_native_transaction_rent_exception;
}
if (error is SolanaCreateAssociatedTokenAccountException) {
if (error is CreateAssociatedTokenAccountException) {
return S.current.solana_create_associated_token_account_exception;
}
if (error is SolanaSignSPLTokenTransactionRentException) {
if (error is SignSPLTokenTransactionRentException) {
return S.current.solana_sign_spl_token_transaction_rent_exception;
}
if (error is SolanaNoAssociatedTokenAccountException) {
if (error is NoAssociatedTokenAccountException) {
return S.current.solana_no_associated_token_account_exception;
}
@ -724,10 +724,11 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return S.current.insufficient_funds_for_tx;
}
return '''${S.current.insufficient_funds_for_tx} \n\n'''
'''${S.current.balance}: ${parsedErrorMessageResult.balanceEth} ETH (${parsedErrorMessageResult.balanceUsd} USD)\n\n'''
'''${S.current.transaction_cost}: ${parsedErrorMessageResult.txCostEth} ETH (${parsedErrorMessageResult.txCostUsd} USD)\n\n'''
'''${S.current.overshot}: ${parsedErrorMessageResult.overshotEth} ETH (${parsedErrorMessageResult.overshotUsd} USD)''';
return
'''${S.current.insufficient_funds_for_tx} \n\n'''
'''${S.current.balance}: ${parsedErrorMessageResult.balanceEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.balanceUsd} ${fiatFromSettings.name})\n\n'''
'''${S.current.transaction_cost}: ${parsedErrorMessageResult.txCostEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.txCostUsd} ${fiatFromSettings.name})\n\n'''
'''${S.current.overshot}: ${parsedErrorMessageResult.overshotEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.overshotUsd} ${fiatFromSettings.name})''';
}
return errorMessage;

View file

@ -11,102 +11,99 @@ class SupportViewModel = SupportViewModelBase with _$SupportViewModel;
abstract class SupportViewModelBase with Store {
SupportViewModelBase()
: items = [
LinkListItem(
title: 'Email',
icon: 'assets/images/support_icon.png',
linkTitle: 'support@cakewallet.com',
link: 'mailto:support@cakewallet.com'),
if (!isMoneroOnly)
LinkListItem(
title: 'Website',
icon: 'assets/images/global.png',
linkTitle: 'cakewallet.com',
link: 'https://cakewallet.com'),
if (!isMoneroOnly)
LinkListItem(
title: 'GitHub',
icon: 'assets/images/github.png',
hasIconColor: true,
linkTitle: S.current.apk_update,
link: 'https://github.com/cake-tech/cake_wallet/releases'),
LinkListItem(
title: 'Discord',
icon: 'assets/images/discord.png',
linkTitle: 'discord.gg/pwmWa6aFpX',
link: 'https://discord.gg/pwmWa6aFpX'),
LinkListItem(
title: 'Telegram',
icon: 'assets/images/Telegram.png',
linkTitle: 't.me/cakewallet',
link: 'https://t.me/cakewalletannouncements'),
LinkListItem(
title: 'Telegram Support Bot',
icon: 'assets/images/Telegram.png',
linkTitle: '@cakewallet_bot',
link: 'https://t.me/cakewallet_bot'),
LinkListItem(
title: 'ChangeNow',
icon: 'assets/images/change_now.png',
linkTitle: 'support@changenow.io',
link: 'mailto:support@changenow.io'),
LinkListItem(
title: 'SideShift',
icon: 'assets/images/sideshift.png',
linkTitle: 'help.sideshift.ai',
link: 'https://help.sideshift.ai/en/'),
LinkListItem(
title: 'SimpleSwap',
icon: 'assets/images/simpleSwap.png',
linkTitle: 'support@simpleswap.io',
link: 'mailto:support@simpleswap.io'),
LinkListItem(
title: 'Exolix',
icon: 'assets/images/exolix.png',
linkTitle: 'support@exolix.com',
link: 'mailto:support@exolix.com'),
LinkListItem(
title: 'Quantex',
icon: 'assets/images/quantex.png',
linkTitle: 'help.myquantex.com',
link: 'mailto:support@exolix.com'),
LinkListItem(
title: 'Trocador',
icon: 'assets/images/trocador.png',
linkTitle: 'mail@trocador.app',
link: 'mailto:mail@trocador.app'),
LinkListItem(
title: 'Onramper',
icon: 'assets/images/onramper_dark.png',
lightIcon: 'assets/images/onramper_light.png',
linkTitle: 'View exchanges',
link: 'https://docs.cakewallet.com/support/buy/#onramper'),
LinkListItem(
title: 'DFX',
icon: 'assets/images/dfx_dark.png',
lightIcon: 'assets/images/dfx_light.png',
linkTitle: 'support@dfx.swiss',
link: 'mailto:support@dfx.swiss'),
if (!isMoneroOnly) ... [
LinkListItem(
title: 'MoonPay',
icon: 'assets/images/moonpay.png',
linkTitle: S.current.submit_request,
link: 'https://support.moonpay.com/hc/en-gb/requests/new'),
LinkListItem(
title: 'Robinhood Connect',
icon: 'assets/images/robinhood_dark.png',
lightIcon: 'assets/images/robinhood_light.png',
linkTitle: S.current.submit_request,
link: 'https://robinhood.com/contact')
]
//LinkListItem(
// title: 'Yat',
// icon: 'assets/images/yat_mini_logo.png',
// hasIconColor: true,
// linkTitle: 'support@y.at',
// link: 'mailto:support@y.at')
];
: items = [
LinkListItem(
title: 'Email',
icon: 'assets/images/support_icon.png',
linkTitle: 'support@cakewallet.com',
link: 'mailto:support@cakewallet.com'),
LinkListItem(
title: 'Website',
icon: 'assets/images/global.png',
linkTitle: 'cakewallet.com',
link: 'https://cakewallet.com'),
LinkListItem(
title: 'Forum',
icon: 'assets/images/discourse.png',
linkTitle: 'forum.cakewallet.com',
link: 'https://forum.cakewallet.com'),
LinkListItem(
title: 'GitHub',
icon: 'assets/images/github.png',
hasIconColor: true,
linkTitle: S.current.apk_update,
link: 'https://github.com/cake-tech/cake_wallet/releases'),
LinkListItem(
title: 'Discord',
icon: 'assets/images/discord.png',
linkTitle: 'discord.gg/pwmWa6aFpX',
link: 'https://discord.gg/pwmWa6aFpX'),
LinkListItem(
title: 'Telegram',
icon: 'assets/images/Telegram.png',
linkTitle: 't.me/cakewallet',
link: 'https://t.me/cakewalletannouncements'),
LinkListItem(
title: 'Telegram Support Bot',
icon: 'assets/images/Telegram.png',
linkTitle: '@cakewallet_bot',
link: 'https://t.me/cakewallet_bot'),
LinkListItem(
title: 'ChangeNow',
icon: 'assets/images/change_now.png',
linkTitle: 'support@changenow.io',
link: 'mailto:support@changenow.io'),
LinkListItem(
title: 'SideShift',
icon: 'assets/images/sideshift.png',
linkTitle: 'help.sideshift.ai',
link: 'https://help.sideshift.ai/en/'),
LinkListItem(
title: 'SimpleSwap',
icon: 'assets/images/simpleSwap.png',
linkTitle: 'support@simpleswap.io',
link: 'mailto:support@simpleswap.io'),
LinkListItem(
title: 'Exolix',
icon: 'assets/images/exolix.png',
linkTitle: 'support@exolix.com',
link: 'mailto:support@exolix.com'),
LinkListItem(
title: 'Quantex',
icon: 'assets/images/quantex.png',
linkTitle: 'help.myquantex.com',
link: 'mailto:support@exolix.com'),
LinkListItem(
title: 'Trocador',
icon: 'assets/images/trocador.png',
linkTitle: 'mail@trocador.app',
link: 'mailto:mail@trocador.app'),
LinkListItem(
title: 'Onramper',
icon: 'assets/images/onramper_dark.png',
lightIcon: 'assets/images/onramper_light.png',
linkTitle: 'View exchanges',
link: 'https://docs.cakewallet.com/support/buy/#onramper'),
LinkListItem(
title: 'DFX',
icon: 'assets/images/dfx_dark.png',
lightIcon: 'assets/images/dfx_light.png',
linkTitle: 'support@dfx.swiss',
link: 'mailto:support@dfx.swiss'),
if (!isMoneroOnly) ...[
LinkListItem(
title: 'MoonPay',
icon: 'assets/images/moonpay.png',
linkTitle: S.current.submit_request,
link: 'https://support.moonpay.com/hc/en-gb/requests/new'),
LinkListItem(
title: 'Robinhood Connect',
icon: 'assets/images/robinhood_dark.png',
lightIcon: 'assets/images/robinhood_light.png',
linkTitle: S.current.submit_request,
link: 'https://robinhood.com/contact')
]
];
final docsUrl = 'https://docs.cakewallet.com';
@ -114,8 +111,7 @@ abstract class SupportViewModelBase with Store {
var supportUrl =
"https://app.chatwoot.com/widget?website_token=${secrets.chatwootWebsiteToken}&locale=${locale}";
if (authToken.isNotEmpty)
supportUrl += "&cw_conversation=$authToken";
if (authToken.isNotEmpty) supportUrl += "&cw_conversation=$authToken";
return supportUrl;
}

View file

@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.18.2"
MONERO_COM_BUILD_NUMBER=108
MONERO_COM_VERSION="1.19.0"
MONERO_COM_BUILD_NUMBER=109
MONERO_COM_BUNDLE_ID="com.monero.app"
MONERO_COM_PACKAGE="com.monero.app"
MONERO_COM_SCHEME="monero.com"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.21.2"
CAKEWALLET_BUILD_NUMBER=239
CAKEWALLET_VERSION="4.22.0"
CAKEWALLET_BUILD_NUMBER=240
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
CAKEWALLET_SCHEME="cakewallet"

View file

@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.18.2"
MONERO_COM_BUILD_NUMBER=105
MONERO_COM_VERSION="1.19.0"
MONERO_COM_BUILD_NUMBER=106
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.21.2"
CAKEWALLET_BUILD_NUMBER=284
CAKEWALLET_VERSION="4.22.0"
CAKEWALLET_BUILD_NUMBER=287
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven"

View file

@ -14,8 +14,8 @@ if [ -n "$1" ]; then
fi
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.11.2"
CAKEWALLET_BUILD_NUMBER=40
CAKEWALLET_VERSION="1.12.0"
CAKEWALLET_BUILD_NUMBER=41
if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
echo "Wrong app type."

View file

@ -16,13 +16,13 @@ if [ -n "$1" ]; then
fi
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.8.1"
MONERO_COM_BUILD_NUMBER=37
MONERO_COM_VERSION="1.9.0"
MONERO_COM_BUILD_NUMBER=39
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.14.2"
CAKEWALLET_BUILD_NUMBER=98
CAKEWALLET_VERSION="1.15.0"
CAKEWALLET_BUILD_NUMBER=99
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

View file

@ -1,5 +1,5 @@
#define MyAppName "Cake Wallet"
#define MyAppVersion "0.2.1"
#define MyAppVersion "0.3.0"
#define MyAppPublisher "Cake Labs LLC"
#define MyAppURL "https://cakewallet.com/"
#define MyAppExeName "CakeWallet.exe"