mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-04-27 14:04:46 +00:00
Merge branch 'main' into ui-enhancements
This commit is contained in:
commit
ce0d7da97a
101 changed files with 1452 additions and 653 deletions
.github/workflows
assets/images
cakewallet_android_icon
mipmap-anydpi-v26
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
monerocom_android_icon
mipmap-anydpi-v26
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
cw_core/lib
cw_monero/lib
integration_test
components
funds_related_tests.dartrobots
auth_page_robot.dartpin_code_widget_robot.dartrestore_from_seed_or_key_robot.dartsend_page_robot.dartwallet_seed_page_robot.dart
test_suites
lib
core
entities
default_settings_migration.dartparse_address_from_domain.dartparsed_address.dartpreferences_key.dartwellknown_record.dart
router.dartroutes.dartsrc
screens
exchange
new_wallet
new_wallet_page.dartwallet_group_description_page.dartwallet_group_display_page.dartwallet_group_existing_seed_description_page.dart
restore
send
settings
wallet_unlock
widgets
store
themes/extensions
view_model/settings
linux
model_generator.shpubspec_base.yamlres/values
strings_ar.arbstrings_bg.arbstrings_cs.arbstrings_de.arbstrings_en.arbstrings_es.arbstrings_fr.arbstrings_ha.arbstrings_hi.arbstrings_hr.arbstrings_hy.arbstrings_id.arbstrings_it.arbstrings_ja.arbstrings_ko.arbstrings_my.arbstrings_nl.arbstrings_pl.arbstrings_pt.arbstrings_ru.arbstrings_th.arbstrings_tl.arbstrings_tr.arbstrings_uk.arbstrings_ur.arbstrings_vi.arbstrings_yo.arbstrings_zh.arb
scripts
84
.github/workflows/cache_dependencies.yml
vendored
84
.github/workflows/cache_dependencies.yml
vendored
|
@ -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
|
413
.github/workflows/pr_test_build_android.yml
vendored
413
.github/workflows/pr_test_build_android.yml
vendored
|
@ -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"
|
377
.github/workflows/pr_test_build_linux.yml
vendored
377
.github/workflows/pr_test_build_linux.yml
vendored
|
@ -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
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_adaptive_back"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_adaptive_fore"/>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_adaptive_mono"/>
|
||||
</adaptive-icon>
|
Binary file not shown.
After ![]() (image error) Size: 2.3 KiB |
Binary file not shown.
After ![]() (image error) Size: 1.5 KiB |
Binary file not shown.
After ![]() (image error) Size: 3.2 KiB |
Binary file not shown.
After ![]() (image error) Size: 5.1 KiB |
Binary file not shown.
After ![]() (image error) Size: 7.5 KiB |
|
@ -2,4 +2,5 @@
|
|||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_adaptive_back"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_adaptive_fore"/>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_adaptive_mono"/>
|
||||
</adaptive-icon>
|
Binary file not shown.
After ![]() (image error) Size: 2.3 KiB |
Binary file not shown.
After ![]() (image error) Size: 1.5 KiB |
Binary file not shown.
After ![]() (image error) Size: 3 KiB |
Binary file not shown.
After ![]() (image error) Size: 4.8 KiB |
Binary file not shown.
After ![]() (image error) Size: 6.8 KiB |
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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<bool> 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<String, dynamic>;
|
||||
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<String, String>? 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<String, String>? _splitAuthenticateHeader(String? header) {
|
||||
if (header == null || !header.startsWith('Digest ')) {
|
||||
return null;
|
||||
}
|
||||
String token = header.substring(7); // Remove 'Digest '.
|
||||
final Map<String, String> 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<int> values = List<int>.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<Map<String, dynamic>> call(
|
||||
String method, Map<String, dynamic> params) async {
|
||||
final http.Client client = http.Client();
|
||||
final DigestAuth digestAuth = DigestAuth(username, password);
|
||||
|
||||
// Initial request to get the `WWW-Authenticate` header.
|
||||
final initialResponse = await client.post(
|
||||
Uri.parse(rpcUrl),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: jsonEncode({
|
||||
'jsonrpc': '2.0',
|
||||
'id': '0',
|
||||
'method': method,
|
||||
'params': params,
|
||||
}),
|
||||
);
|
||||
|
||||
if (initialResponse.statusCode != 401 ||
|
||||
!initialResponse.headers.containsKey('www-authenticate')) {
|
||||
throw Exception('Unexpected response: ${initialResponse.body}');
|
||||
}
|
||||
|
||||
// Extract Digest details from `WWW-Authenticate` header.
|
||||
final String authInfo = initialResponse.headers['www-authenticate']!;
|
||||
digestAuth.initFromAuthorizationHeader(authInfo);
|
||||
|
||||
// Create Authorization header for the second request.
|
||||
String uri = Uri.parse(rpcUrl).path;
|
||||
String authHeader = digestAuth.getAuthString('POST', uri);
|
||||
|
||||
// Make the authenticated request.
|
||||
final authenticatedResponse = await client.post(
|
||||
Uri.parse(rpcUrl),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': authHeader,
|
||||
},
|
||||
body: jsonEncode({
|
||||
'jsonrpc': '2.0',
|
||||
'id': '0',
|
||||
'method': method,
|
||||
'params': params,
|
||||
}),
|
||||
);
|
||||
|
||||
if (authenticatedResponse.statusCode != 200) {
|
||||
throw Exception('RPC call failed: ${authenticatedResponse.body}');
|
||||
}
|
||||
|
||||
final Map<String, dynamic> result = jsonDecode(authenticatedResponse.body) as Map<String, dynamic>;
|
||||
if (result['error'] != null) {
|
||||
throw Exception('RPC Error: ${result['error']}');
|
||||
}
|
||||
|
||||
return result['result'] as Map<String, dynamic>;
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:monero/monero.dart' as monero;
|
||||
import 'package:mutex/mutex.dart';
|
||||
|
||||
bool debugMonero = false;
|
||||
|
||||
int getSyncingHeight() {
|
||||
// final height = monero.MONERO_cw_WalletListener_height(getWlptr());
|
||||
final h2 = monero.Wallet_blockChainHeight(wptr!);
|
||||
|
@ -132,7 +134,7 @@ Future<bool> setupNodeSync(
|
|||
}
|
||||
}
|
||||
|
||||
if (kDebugMode) {
|
||||
if (kDebugMode && debugMonero) {
|
||||
monero.Wallet_init3(
|
||||
wptr!, argv0: '',
|
||||
defaultLogBaseName: 'moneroc',
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
import 'package:cw_core/parseBoolFromString.dart';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cw_core/format_amount.dart';
|
||||
import 'package:cw_monero/api/transaction_history.dart';
|
||||
|
||||
class MoneroTransactionInfo extends TransactionInfo {
|
||||
MoneroTransactionInfo(this.txHash, this.height, this.direction, this.date,
|
||||
|
@ -11,29 +9,6 @@ class MoneroTransactionInfo extends TransactionInfo {
|
|||
this.confirmations) :
|
||||
id = "${txHash}_${amount}_${accountIndex}_${addressIndex}";
|
||||
|
||||
MoneroTransactionInfo.fromMap(Map<String, Object?> map)
|
||||
: id = "${map['hash']}_${map['amount']}_${map['accountIndex']}_${map['addressIndex']}",
|
||||
txHash = map['hash'] as String,
|
||||
height = (map['height'] ?? 0) as int,
|
||||
direction = map['direction'] != null
|
||||
? parseTransactionDirectionFromNumber(map['direction'] as String)
|
||||
: TransactionDirection.incoming,
|
||||
date = DateTime.fromMillisecondsSinceEpoch(
|
||||
(int.tryParse(map['timestamp'] as String? ?? '') ?? 0) * 1000),
|
||||
isPending = parseBoolFromString(map['isPending'] as String),
|
||||
amount = map['amount'] as int,
|
||||
accountIndex = int.parse(map['accountIndex'] as String),
|
||||
addressIndex = map['addressIndex'] as int,
|
||||
confirmations = map['confirmations'] as int,
|
||||
key = getTxKey((map['hash'] ?? '') as String),
|
||||
fee = map['fee'] as int? ?? 0 {
|
||||
additionalInfo = <String, dynamic>{
|
||||
'key': key,
|
||||
'accountIndex': accountIndex,
|
||||
'addressIndex': addressIndex
|
||||
};
|
||||
}
|
||||
|
||||
final String id;
|
||||
final String txHash;
|
||||
final int height;
|
||||
|
|
|
@ -265,6 +265,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
bool needExportOutputs(int amount) {
|
||||
if (int.tryParse(monero.Wallet_secretSpendKey(wptr!)) != 0) {
|
||||
return false;
|
||||
}
|
||||
// viewOnlyBalance - balance that we can spend
|
||||
// TODO(mrcyjanek): remove hasUnknownKeyImages when we cleanup coin control
|
||||
return (monero.Wallet_viewOnlyBalance(wptr!,
|
||||
|
|
|
@ -32,6 +32,11 @@ class CommonTestCases {
|
|||
expect(textWidget, hasWidget ? findsOneWidget : findsNothing);
|
||||
}
|
||||
|
||||
void hasTextAtLestOnce(String text, {bool hasWidget = true}) {
|
||||
final textWidget = find.text(text);
|
||||
expect(textWidget, hasWidget ? findsAny : findsNothing);
|
||||
}
|
||||
|
||||
void hasType<T>() {
|
||||
final typeWidget = find.byType(T);
|
||||
expect(typeWidget, findsOneWidget);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cake_wallet/entities/seed_type.dart';
|
||||
import 'package:cake_wallet/reactions/bip39_wallet_utils.dart';
|
||||
import 'package:cake_wallet/wallet_types.g.dart';
|
||||
|
@ -85,6 +87,7 @@ class CommonTestFlows {
|
|||
await _confirmPreSeedInfo();
|
||||
|
||||
await _confirmWalletDetails();
|
||||
await _commonTestCases.defaultSleepTime();
|
||||
}
|
||||
|
||||
//* ========== Handles flow from welcome to restoring wallet from seeds ===============
|
||||
|
@ -168,8 +171,8 @@ class CommonTestFlows {
|
|||
await _walletListPageRobot.navigateToRestoreWalletOptionsPage();
|
||||
await _commonTestCases.defaultSleepTime();
|
||||
|
||||
await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
|
||||
await _commonTestCases.defaultSleepTime();
|
||||
if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
|
||||
if (!Platform.isLinux) await _commonTestCases.defaultSleepTime();
|
||||
|
||||
await _selectWalletTypeForWallet(walletType);
|
||||
await _commonTestCases.defaultSleepTime();
|
||||
|
@ -180,6 +183,7 @@ class CommonTestFlows {
|
|||
|
||||
//* ========== Handles setting up pin code for wallet on first install ===============
|
||||
Future<void> setupPinCodeForWallet(List<int> pin) async {
|
||||
if (Platform.isLinux) return;
|
||||
// ----------- SetupPinCode Page -------------
|
||||
// Confirm initial defaults - Widgets to be displayed etc
|
||||
await _setupPinCodeRobot.isSetupPinCodePage();
|
||||
|
@ -212,7 +216,7 @@ class CommonTestFlows {
|
|||
|
||||
await _welcomePageRobot.navigateToRestoreWalletPage();
|
||||
|
||||
await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
|
||||
if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
|
||||
|
||||
await _selectWalletTypeForWallet(walletTypeToRestore);
|
||||
}
|
||||
|
@ -234,6 +238,12 @@ class CommonTestFlows {
|
|||
|
||||
await _newWalletPageRobot.generateWalletName();
|
||||
|
||||
if (Platform.isLinux) {
|
||||
// manual pin input
|
||||
await _restoreFromSeedOrKeysPageRobot.enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
|
||||
await _restoreFromSeedOrKeysPageRobot.enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
|
||||
}
|
||||
|
||||
await _newWalletPageRobot.onNextButtonPressed();
|
||||
}
|
||||
|
||||
|
@ -252,11 +262,15 @@ class CommonTestFlows {
|
|||
|
||||
_walletSeedPageRobot.confirmWalletSeedReminderDisplays();
|
||||
|
||||
await _walletSeedPageRobot.onCopySeedsButtonPressed();
|
||||
// await _walletSeedPageRobot.onCopySeedsButtonPressed();
|
||||
|
||||
await _walletSeedPageRobot.onNextButtonPressed();
|
||||
|
||||
await _walletSeedPageRobot.onConfirmButtonOnSeedAlertDialogPressed();
|
||||
await _walletSeedPageRobot.onSeedPageVerifyButtonPressed();
|
||||
// Turns out the popup about "Copied to clipboard" prevents
|
||||
//the button from being pressed on the first try, by just
|
||||
//tapping it again we fix it.
|
||||
// await _walletSeedPageRobot.onSeedPageVerifyButtonPressed();
|
||||
|
||||
await _walletSeedPageRobot.onOpenWalletButtonPressed();
|
||||
}
|
||||
|
||||
//* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Seeds Action
|
||||
|
@ -277,6 +291,12 @@ class CommonTestFlows {
|
|||
.enterBlockHeightForWalletRestore(secrets.moneroTestWalletBlockHeight);
|
||||
}
|
||||
|
||||
if (Platform.isLinux) {
|
||||
// manual pin input
|
||||
await _restoreFromSeedOrKeysPageRobot.enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
|
||||
await _restoreFromSeedOrKeysPageRobot.enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
|
||||
}
|
||||
|
||||
await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,11 @@ void main() {
|
|||
await authPageRobot.enterPinCode(CommonTestConstants.pin);
|
||||
}
|
||||
|
||||
final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
|
||||
if (onAuthPageDesktop) {
|
||||
await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
|
||||
}
|
||||
|
||||
// ----------- Exchange Confirm Page -------------
|
||||
await exchangeConfirmPageRobot.isExchangeConfirmPage();
|
||||
|
||||
|
|
|
@ -20,6 +20,11 @@ class AuthPageRobot extends PinCodeWidgetRobot {
|
|||
return hasPin;
|
||||
}
|
||||
|
||||
bool onAuthPageDesktop() {
|
||||
final hasWalletPasswordInput = find.byKey(ValueKey('enter_wallet_password'));
|
||||
return hasWalletPasswordInput.tryEvaluate();
|
||||
}
|
||||
|
||||
Future<void> isAuthPage() async {
|
||||
await commonTestCases.isSpecificPage<AuthPage>();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,20 @@ class PinCodeWidgetRobot {
|
|||
commonTestCases.hasValueKey('pin_code_button_0_key');
|
||||
}
|
||||
|
||||
Future<void> enterPassword(String password, {int pumpDuration = 100}) async {
|
||||
await commonTestCases.enterText(
|
||||
password,
|
||||
'enter_wallet_password',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await commonTestCases.tapItemByKey(
|
||||
'unlock',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await commonTestCases.defaultSleepTime();
|
||||
}
|
||||
|
||||
Future<void> enterPinCode(List<int> pinCode, {int pumpDuration = 100}) async {
|
||||
for (int pin in pinCode) {
|
||||
await commonTestCases.tapItemByKey(
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import 'package:cake_wallet/entities/seed_type.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/seed_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/validable_annotated_editable_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../components/common_test_cases.dart';
|
||||
|
@ -65,12 +67,28 @@ class RestoreFromSeedOrKeysPageRobot {
|
|||
|
||||
Future<void> enterSeedPhraseForWalletRestore(String text) async {
|
||||
ValidatableAnnotatedEditableTextState seedTextState =
|
||||
await tester.state(find.byType(ValidatableAnnotatedEditableText));
|
||||
await tester.state(find.byType(ValidatableAnnotatedEditableText));
|
||||
|
||||
seedTextState.widget.controller.text = text;
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> enterPasswordForWalletRestore(String text) async {
|
||||
await commonTestCases.enterText(
|
||||
text,
|
||||
'password',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> enterPasswordRepeatForWalletRestore(String text) async {
|
||||
await commonTestCases.enterText(
|
||||
text,
|
||||
'repeat_wallet_password',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> enterBlockHeightForWalletRestore(String blockHeight) async {
|
||||
await commonTestCases.enterText(
|
||||
blockHeight,
|
||||
|
|
|
@ -183,32 +183,15 @@ class SendPageRobot {
|
|||
}
|
||||
|
||||
Future<void> _handleAuthPage() async {
|
||||
tester.printToConsole('Inside _handleAuth');
|
||||
await tester.pump();
|
||||
tester.printToConsole('starting auth checks');
|
||||
|
||||
final authPage = authPageRobot.onAuthPage();
|
||||
|
||||
tester.printToConsole('hasAuth:$authPage');
|
||||
|
||||
if (authPage) {
|
||||
await tester.pump();
|
||||
tester.printToConsole('Starting inner _handleAuth loop checks');
|
||||
|
||||
try {
|
||||
await authPageRobot.enterPinCode(CommonTestConstants.pin, pumpDuration: 500);
|
||||
tester.printToConsole('Auth done');
|
||||
|
||||
await tester.pump();
|
||||
|
||||
tester.printToConsole('Auth pump done');
|
||||
} catch (e) {
|
||||
tester.printToConsole('Auth failed, retrying');
|
||||
await tester.pump();
|
||||
_handleAuthPage();
|
||||
}
|
||||
final onAuthPage = authPageRobot.onAuthPage();
|
||||
if (onAuthPage) {
|
||||
await authPageRobot.enterPinCode(CommonTestConstants.pin);
|
||||
}
|
||||
|
||||
final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
|
||||
if (onAuthPageDesktop) {
|
||||
await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
|
||||
}
|
||||
await tester.pump();
|
||||
}
|
||||
|
||||
Future<void> handleSendResult() async {
|
||||
|
@ -221,7 +204,7 @@ class SendPageRobot {
|
|||
|
||||
tester.printToConsole('Has an Error in the handle: $hasError');
|
||||
|
||||
int maxRetries = 20;
|
||||
int maxRetries = 3;
|
||||
int retries = 0;
|
||||
|
||||
while (hasError && retries < maxRetries) {
|
||||
|
|
|
@ -14,8 +14,13 @@ class WalletSeedPageRobot {
|
|||
await commonTestCases.isSpecificPage<WalletSeedPage>();
|
||||
}
|
||||
|
||||
Future<void> onNextButtonPressed() async {
|
||||
await commonTestCases.tapItemByKey('wallet_seed_page_next_button_key');
|
||||
Future<void> onSeedPageVerifyButtonPressed() async {
|
||||
await commonTestCases.tapItemByKey('wallet_seed_page_verify_seed_button_key');
|
||||
await commonTestCases.defaultSleepTime();
|
||||
}
|
||||
|
||||
Future<void> onOpenWalletButtonPressed() async {
|
||||
await commonTestCases.tapItemByKey('wallet_seed_page_open_wallet_button_key');
|
||||
await commonTestCases.defaultSleepTime();
|
||||
}
|
||||
|
||||
|
@ -38,11 +43,14 @@ class WalletSeedPageRobot {
|
|||
final walletSeeds = walletSeedViewModel.seed;
|
||||
|
||||
commonTestCases.hasText(walletName);
|
||||
commonTestCases.hasText(walletSeeds);
|
||||
final seedList = walletSeeds.trim().split(" ");
|
||||
for (final seedWord in seedList) {
|
||||
commonTestCases.hasTextAtLestOnce(seedWord);
|
||||
}
|
||||
}
|
||||
|
||||
void confirmWalletSeedReminderDisplays() {
|
||||
commonTestCases.hasText(S.current.seed_reminder);
|
||||
commonTestCases.hasText(S.current.cake_seeds_save_disclaimer);
|
||||
}
|
||||
|
||||
Future<void> onSaveSeedsButtonPressed() async {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cake_wallet/wallet_types.g.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../components/common_test_cases.dart';
|
||||
import '../components/common_test_constants.dart';
|
||||
import '../components/common_test_flows.dart';
|
||||
import '../robots/auth_page_robot.dart';
|
||||
|
@ -95,6 +99,10 @@ Future<void> _confirmSeedsFlowForWalletType(
|
|||
await authPageRobot.enterPinCode(CommonTestConstants.pin);
|
||||
}
|
||||
|
||||
final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
|
||||
if (onAuthPageDesktop) {
|
||||
await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
|
||||
}
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await walletKeysAndSeedPageRobot.isWalletKeysAndSeedPage();
|
||||
|
|
|
@ -56,6 +56,10 @@ void main() {
|
|||
await authPageRobot.enterPinCode(CommonTestConstants.pin);
|
||||
}
|
||||
|
||||
final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
|
||||
if (onAuthPageDesktop) {
|
||||
await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
|
||||
}
|
||||
await exchangeConfirmPageRobot.onSavedTradeIdButtonPressed();
|
||||
await exchangeTradePageRobot.onGotItButtonPressed();
|
||||
});
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cake_wallet/wallet_types.g.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
export DESKTOP_FORCE_MOBILE="Y"
|
||||
|
||||
declare -a targets
|
||||
declare -a passed_tests
|
||||
|
@ -12,6 +13,10 @@ done < <(find integration_test/test_suites -name "*.dart" -type f -print0)
|
|||
# Run each test and collect results
|
||||
for target in "${targets[@]}"
|
||||
do
|
||||
if [[ "x$REMOVE_DATA_DIRECTORY" == "xY" ]];
|
||||
then
|
||||
rm -rf ~/.local/share/com.example.cake_wallet ~/Documents/cake_wallet
|
||||
fi
|
||||
echo "Running test: $target"
|
||||
if flutter drive \
|
||||
--driver=test_driver/integration_test.dart \
|
||||
|
|
|
@ -293,6 +293,7 @@ class BackupService {
|
|||
final lookupsUnstoppableDomains = data[PreferencesKey.lookupsUnstoppableDomains] as bool?;
|
||||
final lookupsOpenAlias = data[PreferencesKey.lookupsOpenAlias] as bool?;
|
||||
final lookupsENS = data[PreferencesKey.lookupsENS] as bool?;
|
||||
final lookupsWellKnown = data[PreferencesKey.lookupsWellKnown] as bool?;
|
||||
final syncAll = data[PreferencesKey.syncAllKey] as bool?;
|
||||
final syncMode = data[PreferencesKey.syncModeKey] as int?;
|
||||
final autoGenerateSubaddressStatus =
|
||||
|
@ -403,6 +404,9 @@ class BackupService {
|
|||
|
||||
if (lookupsENS != null) await _sharedPreferences.setBool(PreferencesKey.lookupsENS, lookupsENS);
|
||||
|
||||
if (lookupsWellKnown != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, lookupsWellKnown);
|
||||
|
||||
if (syncAll != null) await _sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
|
||||
|
||||
if (syncMode != null) await _sharedPreferences.setInt(PreferencesKey.syncModeKey, syncMode);
|
||||
|
@ -542,6 +546,8 @@ class BackupService {
|
|||
_sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains),
|
||||
PreferencesKey.lookupsOpenAlias: _sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias),
|
||||
PreferencesKey.lookupsENS: _sharedPreferences.getBool(PreferencesKey.lookupsENS),
|
||||
PreferencesKey.lookupsWellKnown:
|
||||
_sharedPreferences.getBool(PreferencesKey.lookupsWellKnown),
|
||||
PreferencesKey.syncModeKey: _sharedPreferences.getInt(PreferencesKey.syncModeKey),
|
||||
PreferencesKey.syncAllKey: _sharedPreferences.getBool(PreferencesKey.syncAllKey),
|
||||
PreferencesKey.autoGenerateSubaddressStatusKey:
|
||||
|
|
|
@ -334,20 +334,20 @@ Future<void> defaultSettingsMigration(
|
|||
);
|
||||
break;
|
||||
case 46:
|
||||
_fixNodesUseSSLFlag(nodes);
|
||||
updateWalletTypeNodesWithNewNode(
|
||||
await _fixNodesUseSSLFlag(nodes);
|
||||
await updateWalletTypeNodesWithNewNode(
|
||||
newNodeUri: 'litecoin.stackwallet.com:20063',
|
||||
nodes: nodes,
|
||||
type: WalletType.litecoin,
|
||||
useSSL: true,
|
||||
);
|
||||
updateWalletTypeNodesWithNewNode(
|
||||
await updateWalletTypeNodesWithNewNode(
|
||||
newNodeUri: 'electrum-ltc.bysh.me:50002',
|
||||
nodes: nodes,
|
||||
type: WalletType.litecoin,
|
||||
useSSL: true,
|
||||
);
|
||||
_changeDefaultNode(
|
||||
await _changeDefaultNode(
|
||||
nodes: nodes,
|
||||
sharedPreferences: sharedPreferences,
|
||||
type: WalletType.solana,
|
||||
|
@ -360,13 +360,13 @@ Future<void> defaultSettingsMigration(
|
|||
'solana-rpc.publicnode.com:443',
|
||||
],
|
||||
);
|
||||
_updateNode(
|
||||
await _updateNode(
|
||||
nodes: nodes,
|
||||
currentUri: "ethereum.publicnode.com",
|
||||
newUri: "ethereum-rpc.publicnode.com",
|
||||
useSSL: true,
|
||||
);
|
||||
_updateNode(
|
||||
await _updateNode(
|
||||
nodes: nodes,
|
||||
currentUri: "polygon-bor.publicnode.com",
|
||||
newUri: "polygon-bor-rpc.publicnode.com",
|
||||
|
@ -387,12 +387,12 @@ Future<void> defaultSettingsMigration(
|
|||
await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version);
|
||||
}
|
||||
|
||||
void _updateNode({
|
||||
Future<void> _updateNode({
|
||||
required Box<Node> nodes,
|
||||
required String currentUri,
|
||||
String? newUri,
|
||||
bool? useSSL,
|
||||
}) {
|
||||
}) async {
|
||||
for (Node node in nodes.values) {
|
||||
if (node.uriRaw == currentUri) {
|
||||
if (newUri != null) {
|
||||
|
@ -401,6 +401,7 @@ void _updateNode({
|
|||
if (useSSL != null) {
|
||||
node.useSSL = useSSL;
|
||||
}
|
||||
await node.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -481,7 +482,7 @@ void _deselectExchangeProvider(SharedPreferences sharedPreferences, String provi
|
|||
);
|
||||
}
|
||||
|
||||
void _fixNodesUseSSLFlag(Box<Node> nodes) {
|
||||
Future<void> _fixNodesUseSSLFlag(Box<Node> nodes) async {
|
||||
for (Node node in nodes.values) {
|
||||
switch (node.uriRaw) {
|
||||
case cakeWalletLitecoinElectrumUri:
|
||||
|
@ -490,6 +491,7 @@ void _fixNodesUseSSLFlag(Box<Node> nodes) {
|
|||
case newCakeWalletMoneroUri:
|
||||
node.useSSL = true;
|
||||
node.trusted = true;
|
||||
await node.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:cake_wallet/entities/openalias_record.dart';
|
|||
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||
import 'package:cake_wallet/entities/unstoppable_domain_address.dart';
|
||||
import 'package:cake_wallet/entities/emoji_string_extension.dart';
|
||||
import 'package:cake_wallet/entities/wellknown_record.dart';
|
||||
import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
|
||||
import 'package:cake_wallet/mastodon/mastodon_api.dart';
|
||||
import 'package:cake_wallet/nostr/nostr_api.dart';
|
||||
|
@ -208,6 +209,17 @@ class AddressResolver {
|
|||
}
|
||||
}
|
||||
|
||||
// .well-known scheme:
|
||||
if (text.contains('.') && text.contains('@')) {
|
||||
if (settingsStore.lookupsWellKnown) {
|
||||
final record =
|
||||
await WellKnownRecord.fetchAddressAndName(formattedName: text, currency: currency);
|
||||
if (record != null) {
|
||||
return ParsedAddress.fetchWellKnownAddress(address: record.address, name: text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!text.startsWith('@') && text.contains('@') && !text.contains('.')) {
|
||||
final bool isFioRegistered = await FioAddressProvider.checkAvail(text);
|
||||
if (isFioRegistered) {
|
||||
|
|
|
@ -12,7 +12,8 @@ enum ParseFrom {
|
|||
contact,
|
||||
mastodon,
|
||||
nostr,
|
||||
thorChain
|
||||
thorChain,
|
||||
wellKnown
|
||||
}
|
||||
|
||||
class ParsedAddress {
|
||||
|
@ -142,6 +143,14 @@ class ParsedAddress {
|
|||
);
|
||||
}
|
||||
|
||||
factory ParsedAddress.fetchWellKnownAddress({required String address, required String name}) {
|
||||
return ParsedAddress(
|
||||
addresses: [address],
|
||||
name: name,
|
||||
parseFrom: ParseFrom.wellKnown,
|
||||
);
|
||||
}
|
||||
|
||||
final List<String> addresses;
|
||||
final String name;
|
||||
final String description;
|
||||
|
|
|
@ -76,6 +76,7 @@ class PreferencesKey {
|
|||
static const lookupsUnstoppableDomains = 'looks_up_unstoppable_domain';
|
||||
static const lookupsOpenAlias = 'looks_up_open_alias';
|
||||
static const lookupsENS = 'looks_up_ens';
|
||||
static const lookupsWellKnown = 'looks_up_well_known';
|
||||
static const showCameraConsent = 'show_camera_consent';
|
||||
|
||||
static String moneroWalletUpdateV1Key(String name) =>
|
||||
|
|
92
lib/entities/wellknown_record.dart
Normal file
92
lib/entities/wellknown_record.dart
Normal file
|
@ -0,0 +1,92 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class WellKnownRecord {
|
||||
WellKnownRecord({
|
||||
required this.address,
|
||||
required this.name,
|
||||
});
|
||||
|
||||
final String name;
|
||||
final String address;
|
||||
|
||||
static Future<String?> checkWellKnownUsername(String username, CryptoCurrency currency) async {
|
||||
String jsonLocation = "";
|
||||
switch (currency) {
|
||||
case CryptoCurrency.nano:
|
||||
jsonLocation = "nano-currency";
|
||||
break;
|
||||
// TODO: add other currencies
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
// split the string by the @ symbol:
|
||||
try {
|
||||
final List<String> splitStrs = username.split("@");
|
||||
String name = splitStrs.first.toLowerCase();
|
||||
final String domain = splitStrs.last;
|
||||
|
||||
if (splitStrs.length == 3) {
|
||||
// for username like @alice@domain.org instead of alice@domain.org
|
||||
name = splitStrs[1];
|
||||
}
|
||||
|
||||
if (name.isEmpty) {
|
||||
name = "_";
|
||||
}
|
||||
|
||||
// lookup domain/.well-known/nano-currency.json and check if it has a nano address:
|
||||
final http.Response response = await http.get(
|
||||
Uri.parse("https://$domain/.well-known/$jsonLocation.json?names=$name"),
|
||||
headers: <String, String>{"Accept": "application/json"},
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
return null;
|
||||
}
|
||||
final Map<String, dynamic> decoded = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
// Access the first element in the names array and retrieve its address
|
||||
final List<dynamic> names = decoded["names"] as List<dynamic>;
|
||||
for (final dynamic item in names) {
|
||||
if (item["name"].toLowerCase() == name) {
|
||||
return item["address"] as String;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
printV("error checking well-known username: $e");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static String formatDomainName(String name) {
|
||||
String formattedName = name;
|
||||
|
||||
if (name.contains("@")) {
|
||||
formattedName = name.replaceAll("@", ".");
|
||||
}
|
||||
|
||||
return formattedName;
|
||||
}
|
||||
|
||||
static Future<WellKnownRecord?> fetchAddressAndName({
|
||||
required String formattedName,
|
||||
required CryptoCurrency currency,
|
||||
}) async {
|
||||
String name = formattedName;
|
||||
|
||||
printV("formattedName: $formattedName");
|
||||
|
||||
final address = await checkWellKnownUsername(formattedName, currency);
|
||||
|
||||
if (address == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return WellKnownRecord(address: address, name: name);
|
||||
}
|
||||
}
|
|
@ -50,6 +50,7 @@ import 'package:cake_wallet/src/screens/new_wallet/advanced_privacy_settings_pag
|
|||
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
|
||||
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
|
||||
import 'package:cake_wallet/src/screens/new_wallet/wallet_group_description_page.dart';
|
||||
import 'package:cake_wallet/src/screens/new_wallet/wallet_group_existing_seed_description_page.dart';
|
||||
import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
|
||||
import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart';
|
||||
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
|
||||
|
@ -587,6 +588,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<PreSeedPage>(param1: settings.arguments as int));
|
||||
|
||||
case Routes.walletGroupExistingSeedDescriptionPage:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => WalletGroupExistingSeedDescriptionPage(
|
||||
seedPhraseWordsLength: settings.arguments as int));
|
||||
|
||||
case Routes.transactionSuccessPage:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<TransactionSuccessPage>(param1: settings.arguments as String));
|
||||
|
|
|
@ -116,5 +116,6 @@ class Routes {
|
|||
static const urqrAnimatedPage = '/urqr/animated_page';
|
||||
static const walletGroupsDisplayPage = '/wallet_groups_display_page';
|
||||
static const walletGroupDescription = '/wallet_group_description';
|
||||
static const walletGroupExistingSeedDescriptionPage = '/wallet_group_existing_seed_description_page';
|
||||
static const walletSeedVerificationPage = '/wallet_seed_verification_page';
|
||||
}
|
||||
|
|
|
@ -231,6 +231,8 @@ class ExchangePage extends BasePage {
|
|||
key: ValueKey('exchange_page_exchange_button_key'),
|
||||
text: S.of(context).exchange,
|
||||
onPressed: () {
|
||||
FocusScope.of(context).unfocus();
|
||||
|
||||
if (_formKey.currentState != null &&
|
||||
_formKey.currentState!.validate()) {
|
||||
if ((exchangeViewModel.depositCurrency == CryptoCurrency.xmr) &&
|
||||
|
|
|
@ -101,8 +101,14 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
|||
void initState() {
|
||||
_stateReaction ??= reaction((_) => _walletNewVM.state, (ExecutionState state) async {
|
||||
if (state is ExecutedSuccessfullyState) {
|
||||
Navigator.of(navigatorKey.currentContext ?? context)
|
||||
.pushNamed(Routes.preSeedPage, arguments: _walletNewVM.seedPhraseWordsLength);
|
||||
if (widget.isChildWallet) {
|
||||
Navigator.of(navigatorKey.currentContext ?? context)
|
||||
.pushNamed(Routes.walletGroupExistingSeedDescriptionPage,
|
||||
arguments: _walletNewVM.seedPhraseWordsLength);
|
||||
} else {
|
||||
Navigator.of(navigatorKey.currentContext ?? context)
|
||||
.pushNamed(Routes.preSeedPage, arguments: _walletNewVM.seedPhraseWordsLength);
|
||||
}
|
||||
}
|
||||
|
||||
if (state is FailureState) {
|
||||
|
@ -221,6 +227,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
|||
),
|
||||
if (_walletNewVM.hasWalletPassword) ...[
|
||||
TextFormField(
|
||||
key: ValueKey('password'),
|
||||
onChanged: (value) => _walletNewVM.walletPassword = value,
|
||||
controller: _passwordController,
|
||||
textAlign: TextAlign.center,
|
||||
|
@ -257,6 +264,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
|||
),
|
||||
),
|
||||
TextFormField(
|
||||
key: ValueKey('repeat_wallet_password'),
|
||||
onChanged: (value) => _walletNewVM.repeatedWalletPassword = value,
|
||||
controller: _repeatedPasswordController,
|
||||
textAlign: TextAlign.center,
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/themes/theme_base.dart';
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/themes/extensions/theme_type_images.dart';
|
||||
|
||||
class WalletGroupDescriptionPage extends BasePage {
|
||||
WalletGroupDescriptionPage({required this.selectedWalletType});
|
||||
|
@ -25,10 +26,7 @@ class WalletGroupDescriptionPage extends BasePage {
|
|||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
_getThemedWalletGroupImage(currentTheme.type),
|
||||
height: 200,
|
||||
),
|
||||
Image.asset(currentTheme.type.walletGroupImage, height: 200),
|
||||
SizedBox(height: 32),
|
||||
Expanded(
|
||||
child: Text.rich(
|
||||
|
@ -91,19 +89,4 @@ class WalletGroupDescriptionPage extends BasePage {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _getThemedWalletGroupImage(ThemeType theme) {
|
||||
final lightImage = 'assets/images/wallet_group_light.png';
|
||||
final darkImage = 'assets/images/wallet_group_dark.png';
|
||||
final brightImage = 'assets/images/wallet_group_bright.png';
|
||||
|
||||
switch (theme) {
|
||||
case ThemeType.bright:
|
||||
return brightImage;
|
||||
case ThemeType.light:
|
||||
return lightImage;
|
||||
default:
|
||||
return darkImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,13 @@ import 'package:cake_wallet/routes.dart';
|
|||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/new_wallet/widgets/grouped_wallet_expansion_tile.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/theme_type_images.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_groups_display_view_model.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import '../../../themes/extensions/cake_text_theme.dart';
|
||||
|
||||
class WalletGroupsDisplayPage extends BasePage {
|
||||
WalletGroupsDisplayPage(this.walletGroupsDisplayViewModel);
|
||||
|
@ -165,10 +166,7 @@ class WalletGroupEmptyStateWidget extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
_getThemedWalletGroupImage(currentTheme.type),
|
||||
scale: 1.8,
|
||||
),
|
||||
Image.asset(currentTheme.type.walletGroupImage, scale: 1.8),
|
||||
SizedBox(height: 32),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
|
@ -194,19 +192,4 @@ class WalletGroupEmptyStateWidget extends StatelessWidget {
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
String _getThemedWalletGroupImage(ThemeType theme) {
|
||||
final lightImage = 'assets/images/wallet_group_light.png';
|
||||
final darkImage = 'assets/images/wallet_group_dark.png';
|
||||
final brightImage = 'assets/images/wallet_group_bright.png';
|
||||
|
||||
switch (theme) {
|
||||
case ThemeType.bright:
|
||||
return brightImage;
|
||||
case ThemeType.light:
|
||||
return lightImage;
|
||||
default:
|
||||
return darkImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/theme_type_images.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WalletGroupExistingSeedDescriptionPage extends BasePage {
|
||||
WalletGroupExistingSeedDescriptionPage({required this.seedPhraseWordsLength});
|
||||
|
||||
final int seedPhraseWordsLength;
|
||||
|
||||
@override
|
||||
String get title => S.current.wallet_group;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
final textStyle = TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
|
||||
);
|
||||
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(currentTheme.type.walletGroupImage, height: 200),
|
||||
SizedBox(height: 32),
|
||||
Expanded(
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: S.current.wallet_group_description_existing_seed + '\n\n',
|
||||
style: textStyle),
|
||||
TextSpan(
|
||||
text: S.current.wallet_group_description_open_wallet + '\n\n',
|
||||
style: textStyle),
|
||||
TextSpan(
|
||||
text: S.current.wallet_group_description_view_seed + '\n', style: textStyle),
|
||||
TextSpan(
|
||||
text: S.current.seed_display_path,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: PrimaryButton(
|
||||
key: ValueKey(
|
||||
'wallet_group_existing_seed_description_page_verify_seed_button_key'),
|
||||
onPressed: () => Navigator.pushNamed(context, Routes.preSeedPage,
|
||||
arguments: seedPhraseWordsLength),
|
||||
text: S.current.verify_seed,
|
||||
color: Theme.of(context).cardColor,
|
||||
textColor: currentTheme.type == ThemeType.dark
|
||||
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
|
||||
: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Builder(
|
||||
builder: (context) => PrimaryButton(
|
||||
key: ValueKey(
|
||||
'wallet_group_existing_seed_description_page_open_wallet_button_key'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
||||
},
|
||||
text: S.current.open_wallet,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -148,12 +148,14 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
|||
),
|
||||
if (widget.displayWalletPassword)
|
||||
...[Container(
|
||||
key: ValueKey('password'),
|
||||
padding: EdgeInsets.only(top: 20.0),
|
||||
child: BaseTextFormField(
|
||||
controller: passwordTextEditingController,
|
||||
hintText: S.of(context).password,
|
||||
obscureText: true)),
|
||||
Container(
|
||||
key: ValueKey('repeat_wallet_password'),
|
||||
padding: EdgeInsets.only(top: 20.0),
|
||||
child: BaseTextFormField(
|
||||
controller: repeatedPasswordTextEditingController,
|
||||
|
|
|
@ -223,12 +223,14 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
|||
),
|
||||
if (widget.displayWalletPassword)
|
||||
...[BaseTextFormField(
|
||||
key: ValueKey('password'),
|
||||
controller: passwordTextEditingController,
|
||||
hintText: S
|
||||
.of(context)
|
||||
.password,
|
||||
obscureText: true),
|
||||
BaseTextFormField(
|
||||
key: ValueKey('repeat_wallet_password'),
|
||||
controller: repeatedPasswordTextEditingController,
|
||||
hintText: S
|
||||
.of(context)
|
||||
|
|
|
@ -525,6 +525,10 @@ class SendPage extends BasePage {
|
|||
if (state is TransactionCommitted) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
final successMessage = S.of(context).send_success(
|
||||
sendViewModel.selectedCryptoCurrency.toString());
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@ Future<String> extractAddressFromParsed(
|
|||
content = S.of(context).extracted_address_content('${parsedAddress.name} (OpenAlias)');
|
||||
address = parsedAddress.addresses.first;
|
||||
break;
|
||||
case ParseFrom.wellKnown:
|
||||
title = S.of(context).address_detected;
|
||||
content = S.of(context).extracted_address_content('${parsedAddress.name} (Well-Known)');
|
||||
address = parsedAddress.addresses.first;
|
||||
break;
|
||||
case ParseFrom.fio:
|
||||
title = S.of(context).address_detected;
|
||||
content = S.of(context).extracted_address_content('${parsedAddress.name} (FIO)');
|
||||
|
|
|
@ -45,6 +45,10 @@ class DomainLookupsPage extends BasePage {
|
|||
title: 'Ethereum Name Service',
|
||||
value: _privacySettingsViewModel.looksUpENS,
|
||||
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsENS(value)),
|
||||
SettingsSwitcherCell(
|
||||
title: '.well-known',
|
||||
value: _privacySettingsViewModel.looksUpWellKnown,
|
||||
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsWellKnown(value)),
|
||||
|
||||
//if (!isHaven) it does not work correctly
|
||||
],
|
||||
|
|
|
@ -170,6 +170,7 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
|
|||
SizedBox(height: 24),
|
||||
Form(
|
||||
child: TextFormField(
|
||||
key: ValueKey('enter_wallet_password'),
|
||||
onChanged: (value) => null,
|
||||
controller: _passwordController,
|
||||
textAlign: TextAlign.center,
|
||||
|
@ -205,6 +206,7 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
|
|||
),
|
||||
),
|
||||
Padding(
|
||||
key: ValueKey('unlock'),
|
||||
padding: EdgeInsets.only(bottom: 24),
|
||||
child: Observer(
|
||||
builder: (_) => LoadingPrimaryButton(
|
||||
|
|
|
@ -91,7 +91,10 @@ class LoadingPrimaryButton extends StatelessWidget {
|
|||
width: double.infinity,
|
||||
height: 52.0,
|
||||
child: TextButton(
|
||||
onPressed: (isLoading || isDisabled) ? null : onPressed,
|
||||
onPressed: (isLoading || isDisabled) ? null : () {
|
||||
FocusScope.of(context).unfocus();
|
||||
onPressed.call();
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor:
|
||||
MaterialStateProperty.all(isDisabled ? color.withOpacity(0.5) : color),
|
||||
|
|
|
@ -115,6 +115,7 @@ abstract class SettingsStoreBase with Store {
|
|||
required this.lookupsUnstoppableDomains,
|
||||
required this.lookupsOpenAlias,
|
||||
required this.lookupsENS,
|
||||
required this.lookupsWellKnown,
|
||||
required this.customBitcoinFeeRate,
|
||||
required this.silentPaymentsCardDisplay,
|
||||
required this.silentPaymentsAlwaysScan,
|
||||
|
@ -459,6 +460,11 @@ abstract class SettingsStoreBase with Store {
|
|||
reaction((_) => lookupsENS,
|
||||
(bool looksUpENS) => _sharedPreferences.setBool(PreferencesKey.lookupsENS, looksUpENS));
|
||||
|
||||
reaction(
|
||||
(_) => lookupsWellKnown,
|
||||
(bool looksUpWellKnown) =>
|
||||
_sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown));
|
||||
|
||||
// secure storage keys:
|
||||
reaction(
|
||||
(_) => allowBiometricalAuthentication,
|
||||
|
@ -772,6 +778,8 @@ abstract class SettingsStoreBase with Store {
|
|||
@observable
|
||||
bool lookupsENS;
|
||||
|
||||
@observable
|
||||
bool lookupsWellKnown;
|
||||
@observable
|
||||
SyncMode currentSyncMode;
|
||||
|
||||
|
@ -967,6 +975,7 @@ abstract class SettingsStoreBase with Store {
|
|||
sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains) ?? true;
|
||||
final lookupsOpenAlias = sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias) ?? true;
|
||||
final lookupsENS = sharedPreferences.getBool(PreferencesKey.lookupsENS) ?? true;
|
||||
final lookupsWellKnown = sharedPreferences.getBool(PreferencesKey.lookupsWellKnown) ?? true;
|
||||
final customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1;
|
||||
final silentPaymentsCardDisplay =
|
||||
sharedPreferences.getBool(PreferencesKey.silentPaymentsCardDisplay) ?? true;
|
||||
|
@ -1245,6 +1254,7 @@ abstract class SettingsStoreBase with Store {
|
|||
lookupsUnstoppableDomains: lookupsUnstoppableDomains,
|
||||
lookupsOpenAlias: lookupsOpenAlias,
|
||||
lookupsENS: lookupsENS,
|
||||
lookupsWellKnown: lookupsWellKnown,
|
||||
customBitcoinFeeRate: customBitcoinFeeRate,
|
||||
silentPaymentsCardDisplay: silentPaymentsCardDisplay,
|
||||
silentPaymentsAlwaysScan: silentPaymentsAlwaysScan,
|
||||
|
@ -1414,6 +1424,7 @@ abstract class SettingsStoreBase with Store {
|
|||
sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains) ?? true;
|
||||
lookupsOpenAlias = sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias) ?? true;
|
||||
lookupsENS = sharedPreferences.getBool(PreferencesKey.lookupsENS) ?? true;
|
||||
lookupsWellKnown = sharedPreferences.getBool(PreferencesKey.lookupsWellKnown) ?? true;
|
||||
customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1;
|
||||
silentPaymentsCardDisplay =
|
||||
sharedPreferences.getBool(PreferencesKey.silentPaymentsCardDisplay) ?? true;
|
||||
|
|
14
lib/themes/extensions/theme_type_images.dart
Normal file
14
lib/themes/extensions/theme_type_images.dart
Normal file
|
@ -0,0 +1,14 @@
|
|||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
|
||||
extension ThemeTypeImages on ThemeType {
|
||||
String get walletGroupImage {
|
||||
switch (this) {
|
||||
case ThemeType.bright:
|
||||
return 'assets/images/wallet_group_bright.png';
|
||||
case ThemeType.light:
|
||||
return 'assets/images/wallet_group_light.png';
|
||||
default:
|
||||
return 'assets/images/wallet_group_dark.png';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -94,6 +94,9 @@ abstract class PrivacySettingsViewModelBase with Store {
|
|||
@computed
|
||||
bool get looksUpENS => _settingsStore.lookupsENS;
|
||||
|
||||
@computed
|
||||
bool get looksUpWellKnown => _settingsStore.lookupsWellKnown;
|
||||
|
||||
bool get canUseEtherscan => _wallet.type == WalletType.ethereum;
|
||||
|
||||
bool get canUsePolygonScan => _wallet.type == WalletType.polygon;
|
||||
|
@ -130,6 +133,9 @@ abstract class PrivacySettingsViewModelBase with Store {
|
|||
@action
|
||||
void setLookupsENS(bool value) => _settingsStore.lookupsENS = value;
|
||||
|
||||
@action
|
||||
void setLookupsWellKnown(bool value) => _settingsStore.lookupsWellKnown = value;
|
||||
|
||||
@action
|
||||
void setLookupsYatService(bool value) => _settingsStore.lookupsYatService = value;
|
||||
|
||||
|
|
|
@ -46,8 +46,11 @@ static void my_application_activate(GApplication* application) {
|
|||
} else {
|
||||
gtk_window_set_title(window, "Cake Wallet");
|
||||
}
|
||||
|
||||
gtk_window_set_default_size(window, 1280, 720);
|
||||
if (getenv("DESKTOP_FORCE_MOBILE")) {
|
||||
gtk_window_set_default_size(window, 720, 1280);
|
||||
} else {
|
||||
gtk_window_set_default_size(window, 1280, 720);
|
||||
}
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||
|
|
|
@ -1,18 +1,24 @@
|
|||
#!/bin/bash
|
||||
set -x -e
|
||||
|
||||
cd cw_core; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_evm; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_monero; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_bitcoin; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_haven; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_nano; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_bitcoin_cash; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_solana; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_tron; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_wownero; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_polygon; flutter pub get; cd ..
|
||||
cd cw_ethereum; flutter pub get; cd ..
|
||||
cd cw_mweb && flutter pub get && cd ..
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
for cwcoin in cw_{core,evm,monero,bitcoin,haven,nano,bitcoin_cash,solana,tron,wownero}
|
||||
do
|
||||
if [[ "x$1" == "xasync" ]];
|
||||
then
|
||||
bash -c "cd $cwcoin; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .." &
|
||||
else
|
||||
bash -c "cd $cwcoin; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .."
|
||||
fi
|
||||
done
|
||||
for cwcoin in cw_{polygon,ethereum,mwebd};
|
||||
do
|
||||
if [[ "x$1" == "xasync" ]];
|
||||
then
|
||||
bash -c "cd $cwcoin; flutter pub get; cd .." &
|
||||
else
|
||||
bash -c "cd $cwcoin; flutter pub get; cd .."
|
||||
fi
|
||||
done
|
||||
|
||||
flutter pub get
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
|
|
|
@ -107,7 +107,10 @@ dependencies:
|
|||
polyseed: ^0.0.6
|
||||
nostr_tools: ^1.0.9
|
||||
solana: ^0.31.0+1
|
||||
ledger_flutter_plus: ^1.4.1
|
||||
ledger_flutter_plus:
|
||||
git:
|
||||
url: https://github.com/vespr-wallet/ledger-flutter-plus
|
||||
ref: c2e341d8038f1108690ad6f80f7b4b7156aacc76
|
||||
hashlib: ^1.19.2
|
||||
|
||||
dev_dependencies:
|
||||
|
@ -146,6 +149,10 @@ dependency_overrides:
|
|||
url: https://github.com/cake-tech/bitcoin_base
|
||||
ref: cake-update-v9
|
||||
ffi: 2.1.0
|
||||
ledger_flutter_plus:
|
||||
git:
|
||||
url: https://github.com/vespr-wallet/ledger-flutter-plus
|
||||
ref: c2e341d8038f1108690ad6f80f7b4b7156aacc76
|
||||
|
||||
flutter_icons:
|
||||
image_path: "assets/images/app_logo.png"
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "ﺕﻼﻣﺎﻌﻤﻟﺍ ﻞﺠﺳ ﻲﻓ ﺔﻠﻣﺎﻌﻤﻟﺍ ﺲﻜﻌﻨﺗ ﻰﺘﺣ ﻥﺍﻮﺛ ﻊﻀﺒﻟ ﺭﺎﻈﺘﻧﻻﺍ ﻰﺟﺮﻳ",
|
||||
"wallet": "محفظة",
|
||||
"wallet_group": "مجموعة محفظة",
|
||||
"wallet_group_description_existing_seed": "لقد اخترت استخدام بذرة موجودة لهذه المحفظة. يمكنك التحقق من البذرة مرة أخرى إذا كنت بحاجة إلى تأكيدها أو كتابتها.",
|
||||
"wallet_group_description_four": "لإنشاء محفظة مع بذرة جديدة تماما.",
|
||||
"wallet_group_description_one": "في محفظة الكيك ، يمكنك إنشاء ملف",
|
||||
"wallet_group_description_open_wallet": "خلاف ذلك ، يمكنك الاستمرار في فتح المحفظة",
|
||||
"wallet_group_description_three": "لرؤية المحافظ المتاحة و/أو شاشة مجموعات المحفظة. أو اختر",
|
||||
"wallet_group_description_two": "عن طريق اختيار محفظة موجودة لتبادل البذور مع. يمكن أن تحتوي كل مجموعة محفظة على محفظة واحدة من كل نوع من العملة. \n\n يمكنك تحديدها",
|
||||
"wallet_group_description_view_seed": "يمكنك دائمًا عرض هذه البذرة مرة أخرى تحت",
|
||||
"wallet_group_empty_state_text_one": "يبدو أنه ليس لديك أي مجموعات محفظة متوافقة !\n\n انقر",
|
||||
"wallet_group_empty_state_text_two": "أدناه لجعل واحدة جديدة.",
|
||||
"wallet_keys": "سييد المحفظة / المفاتيح",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "Моля, изчакайте няколко секунди, докато транзакцията се отрази в историята на транзакциите",
|
||||
"wallet": "Портфейл",
|
||||
"wallet_group": "Група на портфейла",
|
||||
"wallet_group_description_existing_seed": "Вие сте избрали да използвате съществуващо семе за този портфейл. Можете да проверите отново семето, ако трябва да го потвърдите или запишете.",
|
||||
"wallet_group_description_four": "За да създадете портфейл с изцяло ново семе.",
|
||||
"wallet_group_description_one": "В портфейла за торта можете да създадете a",
|
||||
"wallet_group_description_open_wallet": "В противен случай можете да продължите да отваряте портфейла",
|
||||
"wallet_group_description_three": "За да видите наличния екран за портфейли и/или групи за портфейли. Или изберете",
|
||||
"wallet_group_description_two": "Чрез избора на съществуващ портфейл, с който да споделите семе. Всяка група за портфейл може да съдържа по един портфейл от всеки тип валута. \n\n Можете да изберете",
|
||||
"wallet_group_description_view_seed": "Винаги можете да видите това семе отново под",
|
||||
"wallet_group_empty_state_text_one": "Изглежда, че нямате съвместими групи портфейли !\n\n tap",
|
||||
"wallet_group_empty_state_text_two": "по -долу, за да се направи нов.",
|
||||
"wallet_keys": "Seed/keys на портфейла",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "Počkejte několik sekund, než se transakce projeví v historii transakcí",
|
||||
"wallet": "Peněženka",
|
||||
"wallet_group": "Skupina peněženky",
|
||||
"wallet_group_description_existing_seed": "Rozhodli jste se použít existující semeno pro tuto peněženku. Semeno můžete znovu ověřit, pokud potřebujete potvrdit nebo zapisovat.",
|
||||
"wallet_group_description_four": "Vytvoření peněženky s zcela novým semenem.",
|
||||
"wallet_group_description_one": "V peněžence dortu můžete vytvořit a",
|
||||
"wallet_group_description_open_wallet": "Jinak můžete pokračovat v otevírání peněženky",
|
||||
"wallet_group_description_three": "Chcete -li zobrazit dostupnou obrazovku Skupina skupin peněženek a/nebo skupin peněženek. Nebo zvolit",
|
||||
"wallet_group_description_two": "Výběrem existující peněženky pro sdílení semeno. Každá skupina peněženek může obsahovat jednu peněženku každého typu měny. \n\n Můžete si vybrat",
|
||||
"wallet_group_description_view_seed": "Toto semeno si můžete vždy znovu prohlédnout",
|
||||
"wallet_group_empty_state_text_one": "Vypadá to, že nemáte žádné kompatibilní skupiny peněženky !\n\n",
|
||||
"wallet_group_empty_state_text_two": "Níže vytvořit nový.",
|
||||
"wallet_keys": "Seed/klíče peněženky",
|
||||
|
|
|
@ -929,10 +929,13 @@
|
|||
"waiting_payment_confirmation": "Warte auf Zahlungsbestätigung",
|
||||
"wallet": "Geldbörse",
|
||||
"wallet_group": "Walletgruppe",
|
||||
"wallet_group_description_existing_seed": "Sie haben für diese Brieftasche einen vorhandenen Samen verwendet. Sie können den Samen erneut überprüfen, wenn Sie ihn bestätigen oder aufschreiben müssen.",
|
||||
"wallet_group_description_four": "eine Wallet mit einem völlig neuen Seed schaffen.",
|
||||
"wallet_group_description_one": "In CakeWallet können Sie eine erstellen",
|
||||
"wallet_group_description_open_wallet": "Andernfalls können Sie die Brieftasche weiter öffnen",
|
||||
"wallet_group_description_three": "Sehen Sie den Bildschirm zur verfügbaren Wallet und/oder Walletgruppen. Oder wählen",
|
||||
"wallet_group_description_two": "Durch die Auswahl einer vorhandenen Wallet, mit der ein Seed geteilt werden kann. Jede Walletgruppe kann eine einzelne Wallet jedes Währungstyps enthalten. \n\n Sie können auswählen",
|
||||
"wallet_group_description_view_seed": "Sie können diesen Samen immer wieder untersuchen",
|
||||
"wallet_group_empty_state_text_one": "Sieht so aus, als hätten Sie keine kompatiblen Walletgruppen !\n\n TAP",
|
||||
"wallet_group_empty_state_text_two": "unten, um einen neuen zu machen.",
|
||||
"wallet_keys": "Wallet-Seed/-Schlüssel",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "Kindly wait for a few seconds for transaction to reflect in transactions history",
|
||||
"wallet": "Wallet",
|
||||
"wallet_group": "Wallet Group",
|
||||
"wallet_group_description_existing_seed": "You’ve chosen to use an existing seed for this wallet. You may verify the seed again if you need to confirm or write it down.",
|
||||
"wallet_group_description_four": "to create a wallet with an entirely new seed.",
|
||||
"wallet_group_description_one": "In Cake Wallet, you can create a",
|
||||
"wallet_group_description_open_wallet": "Otherwise, you can continue to open the wallet",
|
||||
"wallet_group_description_three": "to see the available wallets and/or wallet groups screen. Or choose",
|
||||
"wallet_group_description_two": "by selecting an existing wallet to share a seed with. Each wallet group can contain a single wallet of each currency type.\n\nYou can select",
|
||||
"wallet_group_description_view_seed": "You can always view this seed again under",
|
||||
"wallet_group_empty_state_text_one": "Looks like you don't have any compatible wallet groups!\n\nTap",
|
||||
"wallet_group_empty_state_text_two": "below to make a new one.",
|
||||
"wallet_keys": "Wallet seed/keys",
|
||||
|
|
|
@ -927,10 +927,13 @@
|
|||
"waitFewSecondForTxUpdate": "Espera unos segundos para que la transacción se refleje en el historial de transacciones.",
|
||||
"wallet": "Billetera",
|
||||
"wallet_group": "Grupo de billetera",
|
||||
"wallet_group_description_existing_seed": "Ha elegido usar una semilla existente para esta billetera. Puede verificar la semilla nuevamente si necesita confirmarla o escribirla.",
|
||||
"wallet_group_description_four": "Para crear una billetera con una semilla completamente nueva.",
|
||||
"wallet_group_description_one": "En la billetera de pastel, puedes crear un",
|
||||
"wallet_group_description_open_wallet": "De lo contrario, puede continuar abriendo la billetera",
|
||||
"wallet_group_description_three": "Para ver las billeteras disponibles y/o la pantalla de grupos de billeteras. O elegir",
|
||||
"wallet_group_description_two": "Seleccionando una billetera existente para compartir una semilla con. Cada grupo de billetera puede contener una sola billetera de cada tipo de moneda. \n\n puedes seleccionar",
|
||||
"wallet_group_description_view_seed": "Siempre puedes ver esta semilla nuevamente debajo",
|
||||
"wallet_group_empty_state_text_one": "Parece que no tienes ningún grupo de billetera compatible !\n\n toque",
|
||||
"wallet_group_empty_state_text_two": "a continuación para hacer uno nuevo.",
|
||||
"wallet_keys": "Billetera semilla/claves",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "Veuillez attendre quelques secondes pour que la transaction soit reflétée dans l'historique des transactions.",
|
||||
"wallet": "Portefeuille",
|
||||
"wallet_group": "Groupe de portefeuille",
|
||||
"wallet_group_description_existing_seed": "Vous avez choisi d'utiliser une graine existante pour ce portefeuille. Vous pouvez vérifier à nouveau la graine si vous avez besoin de le confirmer ou de le noter.",
|
||||
"wallet_group_description_four": "Pour créer un portefeuille avec une graine entièrement nouvelle.",
|
||||
"wallet_group_description_one": "Dans Cake Wallet, vous pouvez créer un",
|
||||
"wallet_group_description_open_wallet": "Sinon, vous pouvez continuer à ouvrir le portefeuille",
|
||||
"wallet_group_description_three": "Pour voir les portefeuilles et / ou les groupes de portefeuilles disponibles. Ou choisir",
|
||||
"wallet_group_description_two": "En sélectionnant un portefeuille existant pour partager une graine avec. Chaque groupe de portefeuille peut contenir un seul portefeuille de chaque type de devise. \n\n Vous pouvez sélectionner",
|
||||
"wallet_group_description_view_seed": "Vous pouvez toujours revoir cette graine sous",
|
||||
"wallet_group_empty_state_text_one": "On dirait que vous n'avez pas de groupes de portefeuilles compatibles !\n\n Tap",
|
||||
"wallet_group_empty_state_text_two": "Ci-dessous pour en faire un nouveau.",
|
||||
"wallet_keys": "Phrase secrète (seed)/Clefs du portefeuille (wallet)",
|
||||
|
|
|
@ -928,10 +928,13 @@
|
|||
"waitFewSecondForTxUpdate": "Da fatan za a jira ƴan daƙiƙa don ciniki don yin tunani a tarihin ma'amala",
|
||||
"wallet": "Zabira",
|
||||
"wallet_group": "Wallet kungiyar",
|
||||
"wallet_group_description_existing_seed": "Kun zaɓi yin amfani da iri ɗaya na data kasance don wannan Wallet.you na iya tabbatar da zuriyar kuma idan kuna buƙatar tabbatarwa ko rubuta shi.",
|
||||
"wallet_group_description_four": "Don ƙirƙirar walat tare da sabon iri.",
|
||||
"wallet_group_description_one": "A cikin walat walat, zaka iya ƙirƙirar",
|
||||
"wallet_group_description_open_wallet": "In ba haka ba, zaku iya ci gaba da buɗe walat ɗin",
|
||||
"wallet_group_description_three": "Don ganin wallets da / ko allon walat din. Ko zabi",
|
||||
"wallet_group_description_two": "ta hanyar zabar walat mai gudana don raba iri tare da. Kowane rukunin walat na iya ƙunsar watsarin kowane nau'in kuɗi. \n\n Zaka iya zaɓar",
|
||||
"wallet_group_description_view_seed": "Koyaushe zaka iya duba wannan zuriya",
|
||||
"wallet_group_empty_state_text_one": "Kamar dai ba ku da wata ƙungiya matattara !\n\n Taɓa",
|
||||
"wallet_group_empty_state_text_two": "da ke ƙasa don yin sabo.",
|
||||
"wallet_keys": "Iri/maɓalli na walat",
|
||||
|
|
|
@ -928,10 +928,13 @@
|
|||
"waitFewSecondForTxUpdate": "लेन-देन इतिहास में लेन-देन प्रतिबिंबित होने के लिए कृपया कुछ सेकंड प्रतीक्षा करें",
|
||||
"wallet": "बटुआ",
|
||||
"wallet_group": "बटुए समूह",
|
||||
"wallet_group_description_existing_seed": "आपने इस वॉलेट के लिए एक मौजूदा बीज का उपयोग करने के लिए चुना है। यदि आपको इसकी पुष्टि करने या लिखने की आवश्यकता है, तो आप फिर से बीज को सत्यापित कर सकते हैं।",
|
||||
"wallet_group_description_four": "एक पूरी तरह से नए बीज के साथ एक बटुआ बनाने के लिए।",
|
||||
"wallet_group_description_one": "केक बटुए में, आप एक बना सकते हैं",
|
||||
"wallet_group_description_open_wallet": "अन्यथा, आप बटुए खोलना जारी रख सकते हैं",
|
||||
"wallet_group_description_three": "उपलब्ध वॉलेट और/या वॉलेट समूह स्क्रीन देखने के लिए। या चुनें",
|
||||
"wallet_group_description_two": "एक बीज साझा करने के लिए एक मौजूदा बटुए का चयन करके। प्रत्येक वॉलेट समूह में प्रत्येक मुद्रा प्रकार का एक एकल वॉलेट हो सकता है।\n\nआप चयन कर सकते हैं",
|
||||
"wallet_group_description_view_seed": "आप हमेशा इस बीज को फिर से देख सकते हैं",
|
||||
"wallet_group_empty_state_text_one": "लगता है कि आपके पास कोई संगत बटुआ समूह नहीं है!\n\nनल",
|
||||
"wallet_group_empty_state_text_two": "नीचे एक नया बनाने के लिए।",
|
||||
"wallet_keys": "बटुआ बीज / चाबियाँ",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "Pričekajte nekoliko sekundi da se transakcija prikaže u povijesti transakcija",
|
||||
"wallet": "Novčanik",
|
||||
"wallet_group": "Skupina novčanika",
|
||||
"wallet_group_description_existing_seed": "Odlučili ste koristiti postojeće sjeme za ovaj novčanik. Možete ponovno provjeriti sjeme ako ga trebate potvrditi ili zapisati.",
|
||||
"wallet_group_description_four": "Da biste stvorili novčanik s potpuno novim sjemenom.",
|
||||
"wallet_group_description_one": "U novčaniku kolača možete stvoriti a",
|
||||
"wallet_group_description_open_wallet": "Inače možete nastaviti otvarati novčanik",
|
||||
"wallet_group_description_three": "Da biste vidjeli zaslon dostupnih novčanika i/ili grupa novčanika. Ili odaberite",
|
||||
"wallet_group_description_two": "Odabirom postojećeg novčanika s kojim ćete dijeliti sjeme. Svaka grupa novčanika može sadržavati jedan novčanik svake vrste valute. \n\n",
|
||||
"wallet_group_description_view_seed": "Uvijek možete ponovo pogledati ovo sjeme ispod",
|
||||
"wallet_group_empty_state_text_one": "Izgleda da nemate nikakve kompatibilne grupe novčanika !\n\n",
|
||||
"wallet_group_empty_state_text_two": "Ispod da napravite novi.",
|
||||
"wallet_keys": "Pristupni izraz/ključ novčanika",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "Խնդրում ենք սպասել մի քանի վայրկյան, որպեսզի գործարքը արտացոլվի գործարքների պատմության մեջ",
|
||||
"wallet": "Դրամապանակ",
|
||||
"wallet_group": "Դրամապանակների խումբ",
|
||||
"wallet_group_description_existing_seed": "Դուք ընտրել եք օգտագործել այս դրամապանակի համար գոյություն ունեցող սերմը: Կարող եք կրկին հաստատել սերմը, եթե անհրաժեշտ է հաստատել կամ գրել այն:",
|
||||
"wallet_group_description_four": "Ամբողջովին նոր սերմով դրամապանակ ստեղծելու համար:",
|
||||
"wallet_group_description_one": "Տորթի դրամապանակում կարող եք ստեղծել ա",
|
||||
"wallet_group_description_open_wallet": "Հակառակ դեպքում, դուք կարող եք շարունակել բացել դրամապանակը",
|
||||
"wallet_group_description_three": "Տեսնել առկա դրամապանակներն ու (կամ) դրամապանակների խմբերի էկրանը: Կամ ընտրել",
|
||||
"wallet_group_description_two": "ընտրելով գոյություն ունեցող դրամապանակ `սերմը կիսելու համար: Դրամապանակների յուրաքանչյուր խումբ կարող է պարունակել յուրաքանչյուր արժույթի տեսակի մեկ դրամապանակ:\n\nԿարող եք ընտրել",
|
||||
"wallet_group_description_view_seed": "Միշտ կարող եք կրկին դիտել այս սերմը ներքեւում",
|
||||
"wallet_group_empty_state_text_one": "Կարծես թե որեւէ համատեղելի դրամապանակի խմբեր չունեք:\n\nԹակել",
|
||||
"wallet_group_empty_state_text_two": "ներքեւում `նորը կազմելու համար:",
|
||||
"wallet_keys": "Դրամապանակի սերմ/բանալիներ",
|
||||
|
|
|
@ -929,10 +929,13 @@
|
|||
"waitFewSecondForTxUpdate": "Mohon tunggu beberapa detik hingga transaksi terlihat di riwayat transaksi",
|
||||
"wallet": "Dompet",
|
||||
"wallet_group": "Kelompok dompet",
|
||||
"wallet_group_description_existing_seed": "Anda telah memilih untuk menggunakan benih yang ada untuk dompet ini. Anda dapat memverifikasi benih lagi jika Anda perlu mengonfirmasi atau menuliskannya.",
|
||||
"wallet_group_description_four": "Untuk membuat dompet dengan benih yang sama sekali baru.",
|
||||
"wallet_group_description_one": "Di dompet kue, Anda dapat membuat file",
|
||||
"wallet_group_description_open_wallet": "Jika tidak, Anda dapat terus membuka dompet",
|
||||
"wallet_group_description_three": "Untuk melihat layar dompet dan/atau grup dompet yang tersedia. Atau pilih",
|
||||
"wallet_group_description_two": "dengan memilih dompet yang ada untuk berbagi benih dengan. Setiap grup dompet dapat berisi satu dompet dari setiap jenis mata uang. \n\n Anda dapat memilih",
|
||||
"wallet_group_description_view_seed": "Anda selalu dapat melihat benih ini lagi di bawah",
|
||||
"wallet_group_empty_state_text_one": "Sepertinya Anda tidak memiliki grup dompet yang kompatibel !\n\n tap",
|
||||
"wallet_group_empty_state_text_two": "di bawah ini untuk membuat yang baru.",
|
||||
"wallet_keys": "Seed/kunci dompet",
|
||||
|
|
|
@ -929,10 +929,13 @@
|
|||
"waiting_payment_confirmation": "In attesa di conferma del pagamento",
|
||||
"wallet": "Portafoglio",
|
||||
"wallet_group": "Gruppo di portafoglio",
|
||||
"wallet_group_description_existing_seed": "Hai scelto di utilizzare un seme esistente per questo portafoglio. Puoi verificare di nuovo il seme se devi confermarlo o scriverlo.",
|
||||
"wallet_group_description_four": "Per creare un portafoglio con un seme completamente nuovo.",
|
||||
"wallet_group_description_one": "Nel portafoglio di torte, puoi creare un",
|
||||
"wallet_group_description_open_wallet": "Altrimenti, puoi continuare ad aprire il portafoglio",
|
||||
"wallet_group_description_three": "Per vedere la schermata di portafogli e/o gruppi di portafogli disponibili. O scegli",
|
||||
"wallet_group_description_two": "Selezionando un portafoglio esistente con cui condividere un seme. Ogni gruppo di portafoglio può contenere un singolo portafoglio di ciascun tipo di valuta. \n\n È possibile selezionare",
|
||||
"wallet_group_description_view_seed": "Puoi sempre visualizzare di nuovo questo seme sotto",
|
||||
"wallet_group_empty_state_text_one": "Sembra che tu non abbia alcun gruppo di portafoglio compatibile !\n\n TAP",
|
||||
"wallet_group_empty_state_text_two": "Di seguito per crearne uno nuovo.",
|
||||
"wallet_keys": "Seme Portafoglio /chiavi",
|
||||
|
|
|
@ -927,10 +927,13 @@
|
|||
"waitFewSecondForTxUpdate": "取引履歴に取引が反映されるまで数秒お待ちください。",
|
||||
"wallet": "財布",
|
||||
"wallet_group": "ウォレットグループ",
|
||||
"wallet_group_description_existing_seed": "この財布に既存の種子を使用することを選択しました。確認または書き留める必要がある場合は、シードをもう一度確認できます。",
|
||||
"wallet_group_description_four": "まったく新しい種子の財布を作成します。",
|
||||
"wallet_group_description_one": "ケーキウォレットでは、aを作成できます",
|
||||
"wallet_group_description_open_wallet": "それ以外の場合は、ウォレットを開き続けることができます",
|
||||
"wallet_group_description_three": "利用可能なウォレットおよび/またはウォレットグループの画面を表示します。または選択します",
|
||||
"wallet_group_description_two": "既存のウォレットを選択して種子を共有します。各ウォレットグループには、各通貨タイプの単一のウォレットを含めることができます。\n\n選択できます",
|
||||
"wallet_group_description_view_seed": "いつでもこの種を再び見ることができます",
|
||||
"wallet_group_empty_state_text_one": "互換性のあるウォレットグループがないようです!\n\nタップ",
|
||||
"wallet_group_empty_state_text_two": "以下に新しいものを作るために。",
|
||||
"wallet_keys": "ウォレットシード/キー",
|
||||
|
|
|
@ -512,7 +512,6 @@
|
|||
"please_fill_totp": "다른 기기에 있는 8자리 코드를 입력하세요.",
|
||||
"please_make_selection": "아래에서 선택하십시오 지갑 만들기 또는 복구.",
|
||||
"please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.",
|
||||
"Please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.",
|
||||
"please_select": "선택 해주세요:",
|
||||
"please_select_backup_file": "백업 파일을 선택하고 백업 암호를 입력하십시오.",
|
||||
"please_try_to_connect_to_another_node": "다른 노드에 연결을 시도하십시오",
|
||||
|
@ -927,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "거래 내역에 거래가 반영될 때까지 몇 초 정도 기다려 주세요.",
|
||||
"wallet": "지갑",
|
||||
"wallet_group": "지갑 그룹",
|
||||
"wallet_group_description_existing_seed": "이 지갑에 기존 씨앗을 사용하기로 선택했습니다. 확인하거나 작성 해야하는 경우 씨앗을 다시 확인할 수 있습니다.",
|
||||
"wallet_group_description_four": "완전히 새로운 씨앗으로 지갑을 만듭니다.",
|
||||
"wallet_group_description_one": "케이크 지갑에서는 a를 만들 수 있습니다",
|
||||
"wallet_group_description_open_wallet": "그렇지 않으면 지갑을 계속 열 수 있습니다",
|
||||
"wallet_group_description_three": "사용 가능한 지갑 및/또는 지갑 그룹 스크린을 볼 수 있습니다. 또는 선택하십시오",
|
||||
"wallet_group_description_two": "씨앗을 공유 할 기존 지갑을 선택함으로써. 각 지갑 그룹은 각 통화 유형의 단일 지갑을 포함 할 수 있습니다. \n\n",
|
||||
"wallet_group_description_view_seed": "이 씨앗을 언제든지 다시 볼 수 있습니다",
|
||||
"wallet_group_empty_state_text_one": "호환 지갑 그룹이없는 것 같습니다 !\n\n TAP",
|
||||
"wallet_group_empty_state_text_two": "아래에서 새로운 것을 만들기 위해.",
|
||||
"wallet_keys": "지갑 시드 / 키",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "ငွေပေးငွေယူ မှတ်တမ်းတွင် ရောင်ပြန်ဟပ်ရန် စက္ကန့်အနည်းငယ်စောင့်ပါ။",
|
||||
"wallet": "ပိုက်ဆံအိတ်",
|
||||
"wallet_group": "ပိုက်ဆံအိတ်အုပ်စု",
|
||||
"wallet_group_description_existing_seed": "ဒီပိုက်ဆံအိတ်အတွက်ရှိပြီးသားမျိုးစေ့ကိုသုံးဖို့သင်ရွေးချယ်ခဲ့တယ်။ သင်ကအတည်ပြုရန်သို့မဟုတ်ရေးရန်လိုအပ်လျှင်မျိုးစေ့ကိုထပ်မံအတည်ပြုနိုင်သည်။",
|
||||
"wallet_group_description_four": "လုံးဝအသစ်သောမျိုးစေ့နှင့်အတူပိုက်ဆံအိတ်ဖန်တီးရန်။",
|
||||
"wallet_group_description_one": "ကိတ်မုန့်၌, သင်တစ် ဦး ဖန်တီးနိုင်ပါတယ်",
|
||||
"wallet_group_description_open_wallet": "ဒီလိုမှမဟုတ်ရင်သင်ပိုက်ဆံအိတ်ကိုဆက်ဖွင့်နိုင်တယ်",
|
||||
"wallet_group_description_three": "ရရှိနိုင်သည့်ပိုက်ဆံအိတ်နှင့် / သို့မဟုတ်ပိုက်ဆံအိတ်အုပ်စုများမြင်ကွင်းကိုကြည့်ရှုရန်။ သို့မဟုတ်ရွေးချယ်ပါ",
|
||||
"wallet_group_description_two": "နှင့်အတူမျိုးစေ့ဝေမျှဖို့ရှိပြီးသားပိုက်ဆံအိတ်တစ်ခုရွေးချယ်ခြင်းအားဖြင့်။ ပိုက်ဆံအိတ်အုပ်စုတစ်ခုစီတွင်ငွေကြေးအမျိုးအစားတစ်ခုစီ၏တစ်ခုတည်းသောပိုက်ဆံအိတ်တစ်ခုပါ 0 င်နိုင်သည်။ \n\n သင်ရွေးချယ်နိုင်သည်",
|
||||
"wallet_group_description_view_seed": "သင်သည်ဤမျိုးစေ့ကိုနောက်တဖန်ရှုမြင်နိုင်သည်",
|
||||
"wallet_group_empty_state_text_one": "သင့်တွင်သဟဇာတဖြစ်သောပိုက်ဆံအိတ်အုပ်စုများမရှိပါ။ !\n\n ကိုအသာပုတ်ပါ",
|
||||
"wallet_group_empty_state_text_two": "အသစ်တစ်ခုကိုတစ်ခုလုပ်ဖို့အောက်တွင်ဖော်ပြထားသော။",
|
||||
"wallet_keys": "ပိုက်ဆံအိတ် အစေ့/သော့များ",
|
||||
|
|
|
@ -927,10 +927,13 @@
|
|||
"waiting_payment_confirmation": "In afwachting van betalingsbevestiging",
|
||||
"wallet": "Portemonnee",
|
||||
"wallet_group": "Portemonnee",
|
||||
"wallet_group_description_existing_seed": "U hebt ervoor gekozen om een bestaand zaadje voor deze portemonnee te gebruiken. U kunt het zaad opnieuw verifiëren als u het moet bevestigen of opschrijven.",
|
||||
"wallet_group_description_four": "om een portemonnee te maken met een geheel nieuw zaadje.",
|
||||
"wallet_group_description_one": "In cakeballet kun je een",
|
||||
"wallet_group_description_open_wallet": "Anders kunt u de portemonnee blijven openen",
|
||||
"wallet_group_description_three": "Om de beschikbare portefeuilles en/of portefeuillegroepen te zien. Of kies",
|
||||
"wallet_group_description_two": "Door een bestaande portemonnee te selecteren om een zaadje mee te delen. Elke portemonnee -groep kan een enkele portemonnee van elk valutietype bevatten. \n\n U kunt selecteren",
|
||||
"wallet_group_description_view_seed": "Je kunt dit zaad altijd opnieuw bekijken",
|
||||
"wallet_group_empty_state_text_one": "Het lijkt erop dat je geen compatibele portemonnee -groepen hebt !\n\n TAP",
|
||||
"wallet_group_empty_state_text_two": "hieronder om een nieuwe te maken.",
|
||||
"wallet_keys": "Portemonnee zaad/sleutels",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "Poczekaj kilka sekund, aż transakcja zostanie odzwierciedlona w historii transakcji",
|
||||
"wallet": "Portfel",
|
||||
"wallet_group": "Grupa portfela",
|
||||
"wallet_group_description_existing_seed": "Zdecydowałeś się użyć istniejącego ziarna do tego portfela. Możesz ponownie zweryfikować ziarno, jeśli chcesz je potwierdzić lub zapisać.",
|
||||
"wallet_group_description_four": "Aby stworzyć portfel z zupełnie nowym ziarnem.",
|
||||
"wallet_group_description_one": "W portfelu ciasta możesz stworzyć",
|
||||
"wallet_group_description_open_wallet": "W przeciwnym razie możesz nadal otwierać portfel",
|
||||
"wallet_group_description_three": "Aby zobaczyć dostępny ekran portfeli i/lub grup portfeli. Lub wybierz",
|
||||
"wallet_group_description_two": "Wybierając istniejący portfel do podzielenia nasion. Każda grupa portfela może zawierać pojedynczy portfel każdego typu waluty. \n\n możesz wybrać",
|
||||
"wallet_group_description_view_seed": "Zawsze możesz ponownie zobaczyć to ziarno pod",
|
||||
"wallet_group_empty_state_text_one": "Wygląda na to, że nie masz żadnych kompatybilnych grup portfeli !\n\n Tap",
|
||||
"wallet_group_empty_state_text_two": "poniżej, aby zrobić nowy.",
|
||||
"wallet_keys": "Klucze portfela",
|
||||
|
|
|
@ -929,10 +929,13 @@
|
|||
"waiting_payment_confirmation": "Aguardando confirmação de pagamento",
|
||||
"wallet": "Carteira",
|
||||
"wallet_group": "Grupo de carteira",
|
||||
"wallet_group_description_existing_seed": "Você optou por usar uma semente existente para esta carteira. Você pode verificar a semente novamente se precisar confirmar ou anotá -la.",
|
||||
"wallet_group_description_four": "Para criar uma carteira com uma semente totalmente nova.",
|
||||
"wallet_group_description_one": "Na carteira de bolo, você pode criar um",
|
||||
"wallet_group_description_open_wallet": "Caso contrário, você pode continuar a abrir a carteira",
|
||||
"wallet_group_description_three": "Para ver as carteiras disponíveis e/ou os grupos de carteiras. Ou escolha",
|
||||
"wallet_group_description_two": "Selecionando uma carteira existente para compartilhar uma semente. Cada grupo de carteira pode conter uma única carteira de cada tipo de moeda. \n\n você pode selecionar",
|
||||
"wallet_group_description_view_seed": "Você sempre pode ver esta semente novamente em",
|
||||
"wallet_group_empty_state_text_one": "Parece que você não tem nenhum grupo de carteira compatível !\n\n Toque",
|
||||
"wallet_group_empty_state_text_two": "abaixo para fazer um novo.",
|
||||
"wallet_keys": "Semente/chaves da carteira",
|
||||
|
|
|
@ -927,10 +927,13 @@
|
|||
"waitFewSecondForTxUpdate": "Пожалуйста, подождите несколько секунд, чтобы транзакция отразилась в истории транзакций.",
|
||||
"wallet": "Кошелек",
|
||||
"wallet_group": "Группа кошелька",
|
||||
"wallet_group_description_existing_seed": "Вы решили использовать существующее семя для этого кошелька. Вы можете снова проверить семя, если вам нужно подтвердить или записать его.",
|
||||
"wallet_group_description_four": "создать кошелек с совершенно новым семенем.",
|
||||
"wallet_group_description_one": "В кошельке для торта вы можете создать",
|
||||
"wallet_group_description_open_wallet": "В противном случае вы можете продолжать открывать кошелек",
|
||||
"wallet_group_description_three": "Чтобы увидеть доступные кошельки и/или экраны групп кошельков. Или выберите",
|
||||
"wallet_group_description_two": "выбирая существующий кошелек, чтобы поделиться семенами. Каждая группа кошелька может содержать один кошелек каждого типа валюты. \n\n Вы можете выбрать",
|
||||
"wallet_group_description_view_seed": "Вы всегда можете просматривать это семя снова под",
|
||||
"wallet_group_empty_state_text_one": "Похоже, у вас нет никаких совместимых групп кошелька !\n\n tap",
|
||||
"wallet_group_empty_state_text_two": "ниже, чтобы сделать новый.",
|
||||
"wallet_keys": "Мнемоническая фраза/ключи кошелька",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "กรุณารอสักครู่เพื่อให้ธุรกรรมปรากฏในประวัติการทำธุรกรรม",
|
||||
"wallet": "กระเป๋าสตางค์",
|
||||
"wallet_group": "กลุ่มกระเป๋าเงิน",
|
||||
"wallet_group_description_existing_seed": "คุณเลือกที่จะใช้เมล็ดพันธุ์ที่มีอยู่สำหรับกระเป๋าเงินนี้คุณอาจตรวจสอบเมล็ดได้อีกครั้งหากคุณต้องการยืนยันหรือเขียนลงไป",
|
||||
"wallet_group_description_four": "เพื่อสร้างกระเป๋าเงินที่มีเมล็ดพันธุ์ใหม่ทั้งหมด",
|
||||
"wallet_group_description_one": "ในกระเป๋าเงินเค้กคุณสามารถสร้างไฟล์",
|
||||
"wallet_group_description_open_wallet": "มิฉะนั้นคุณสามารถเปิดกระเป๋าเงินต่อไปได้",
|
||||
"wallet_group_description_three": "หากต้องการดูกระเป๋าเงินและ/หรือกลุ่มกระเป๋าเงินที่มีอยู่ หรือเลือก",
|
||||
"wallet_group_description_two": "โดยการเลือกกระเป๋าเงินที่มีอยู่เพื่อแบ่งปันเมล็ดด้วย แต่ละกลุ่มกระเป๋าเงินสามารถมีกระเป๋าเงินเดียวของแต่ละประเภทสกุลเงิน \n\n คุณสามารถเลือกได้",
|
||||
"wallet_group_description_view_seed": "คุณสามารถดูเมล็ดพันธุ์นี้ได้อีกครั้งภายใต้",
|
||||
"wallet_group_empty_state_text_one": "ดูเหมือนว่าคุณจะไม่มีกลุ่มกระเป๋าเงินที่เข้ากันได้ !\n\n แตะ",
|
||||
"wallet_group_empty_state_text_two": "ด้านล่างเพื่อสร้างใหม่",
|
||||
"wallet_keys": "ซีดของกระเป๋า/คีย์",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "Mangyaring maghintay ng ilang segundo para makita ang transaksyon sa history ng mga transaksyon",
|
||||
"wallet": "Wallet",
|
||||
"wallet_group": "Group ng Wallet",
|
||||
"wallet_group_description_existing_seed": "Pinili mong gumamit ng isang umiiral na binhi para sa pitaka na ito. Maaari mong mapatunayan muli ang binhi kung kailangan mong kumpirmahin o isulat ito.",
|
||||
"wallet_group_description_four": "Upang lumikha ng isang pitaka na may ganap na bagong binhi.",
|
||||
"wallet_group_description_one": "Sa cake wallet, maaari kang lumikha ng isang",
|
||||
"wallet_group_description_open_wallet": "Kung hindi man, maaari mong magpatuloy upang buksan ang pitaka",
|
||||
"wallet_group_description_three": "Upang makita ang magagamit na mga wallets at/o screen ng mga pangkat ng pitaka. O pumili",
|
||||
"wallet_group_description_two": "Sa pamamagitan ng pagpili ng isang umiiral na pitaka upang magbahagi ng isang binhi. Ang bawat pangkat ng pitaka ay maaaring maglaman ng isang solong pitaka ng bawat uri ng pera.\n\nMaaari kang pumili",
|
||||
"wallet_group_description_view_seed": "Maaari mong palaging tingnan ang binhi na ito sa ilalim",
|
||||
"wallet_group_empty_state_text_one": "Mukhang wala kang anumang mga katugmang pangkat ng pitaka!\n\ntap",
|
||||
"wallet_group_empty_state_text_two": "sa ibaba upang gumawa ng bago.",
|
||||
"wallet_keys": "Wallet seed/keys",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "İşlemin işlem geçmişine yansıması için lütfen birkaç saniye bekleyin",
|
||||
"wallet": "Cüzdan",
|
||||
"wallet_group": "Cüzdan grubu",
|
||||
"wallet_group_description_existing_seed": "Bu cüzdan için mevcut bir tohum kullanmayı seçtiniz. Onaylamanız veya yazmanız gerekiyorsa tohumu tekrar doğrulayabilirsiniz.",
|
||||
"wallet_group_description_four": "Tamamen yeni bir tohumla bir cüzdan oluşturmak için.",
|
||||
"wallet_group_description_one": "Kek cüzdanında bir",
|
||||
"wallet_group_description_open_wallet": "Aksi takdirde cüzdanı açmaya devam edebilirsiniz",
|
||||
"wallet_group_description_three": "Mevcut cüzdan ve/veya cüzdan grupları ekranını görmek için. Veya seç",
|
||||
"wallet_group_description_two": "Bir tohumu paylaşmak için mevcut bir cüzdan seçerek. Her cüzdan grubu, her para türünün tek bir cüzdanı içerebilir. \n\n Seçebilirsiniz",
|
||||
"wallet_group_description_view_seed": "Bu tohumu her zaman tekrar görebilirsiniz",
|
||||
"wallet_group_empty_state_text_one": "Herhangi bir uyumlu cüzdan grubunuz yok gibi görünüyor !\n\n TAP",
|
||||
"wallet_group_empty_state_text_two": "Yeni bir tane yapmak için aşağıda.",
|
||||
"wallet_keys": "Cüzdan tohumu/anahtarları",
|
||||
|
|
|
@ -927,10 +927,13 @@
|
|||
"waitFewSecondForTxUpdate": "Будь ласка, зачекайте кілька секунд, поки транзакція відобразиться в історії транзакцій",
|
||||
"wallet": "Гаманець",
|
||||
"wallet_group": "Група гаманців",
|
||||
"wallet_group_description_existing_seed": "Ви вирішили використовувати існуюче насіння для цього гаманця. Ви можете ще раз перевірити насіння, якщо вам потрібно підтвердити або записати його.",
|
||||
"wallet_group_description_four": "створити гаманець з абсолютно новим насінням.",
|
||||
"wallet_group_description_one": "У гаманці тортів ви можете створити a",
|
||||
"wallet_group_description_open_wallet": "В іншому випадку ви можете продовжувати відкривати гаманець",
|
||||
"wallet_group_description_three": "Щоб побачити наявні гаманці та/або екран групи гаманців. Або вибрати",
|
||||
"wallet_group_description_two": "Вибираючи існуючий гаманець, щоб поділитися насінням. Кожна група гаманця може містити один гаманець кожного типу валюти. \n\n Ви можете вибрати",
|
||||
"wallet_group_description_view_seed": "Ви завжди можете переглянути це насіння ще раз під",
|
||||
"wallet_group_empty_state_text_one": "Схоже, у вас немає сумісних груп гаманця !\n\n Торкніться",
|
||||
"wallet_group_empty_state_text_two": "нижче, щоб зробити новий.",
|
||||
"wallet_keys": "Мнемонічна фраза/ключі гаманця",
|
||||
|
|
|
@ -928,10 +928,13 @@
|
|||
"waitFewSecondForTxUpdate": "۔ﮟﯾﺮﮐ ﺭﺎﻈﺘﻧﺍ ﺎﮐ ﮉﻨﮑﯿﺳ ﺪﻨﭼ ﻡﺮﮐ ﮦﺍﺮﺑ ﮯﯿﻟ ﮯﮐ ﮯﻧﺮﮐ ﯽﺳﺎﮑﻋ ﯽﮐ ﻦﯾﺩ ﻦﯿﻟ ﮟﯿﻣ ﺦﯾﺭﺎﺗ ﯽﮐ ﻦ",
|
||||
"wallet": "پرس",
|
||||
"wallet_group": "پرس گروپ",
|
||||
"wallet_group_description_existing_seed": "آپ نے اس پرس کے لئے موجودہ بیج استعمال کرنے کا انتخاب کیا ہے۔ اگر آپ کو اس کی تصدیق یا لکھنے کی ضرورت ہے تو آپ دوبارہ بیج کی تصدیق کرسکتے ہیں۔",
|
||||
"wallet_group_description_four": "مکمل طور پر نئے بیج کے ساتھ پرس بنانے کے ل.",
|
||||
"wallet_group_description_one": "کیک پرس میں ، آپ بنا سکتے ہیں",
|
||||
"wallet_group_description_open_wallet": "بصورت دیگر ، آپ بٹوے کو کھول سکتے ہیں",
|
||||
"wallet_group_description_three": "دستیاب بٹوے اور/یا پرس گروپوں کی اسکرین کو دیکھنے کے لئے۔ یا منتخب کریں",
|
||||
"wallet_group_description_two": "بیج کے ساتھ بانٹنے کے لئے موجودہ پرس کا انتخاب کرکے۔ ہر بٹوے گروپ میں ہر کرنسی کی قسم کا ایک بٹوے شامل ہوسکتا ہے۔ \n\n آپ منتخب کرسکتے ہیں",
|
||||
"wallet_group_description_view_seed": "آپ ہمیشہ اس بیج کو دوبارہ دیکھ سکتے ہیں",
|
||||
"wallet_group_empty_state_text_one": "ایسا لگتا ہے کہ آپ کے پاس کوئی مطابقت پذیر والیٹ گروپس نہیں ہیں !\n\n نل",
|
||||
"wallet_group_empty_state_text_two": "ایک نیا بنانے کے لئے ذیل میں.",
|
||||
"wallet_keys": "بٹوے کے بیج / چابیاں",
|
||||
|
|
|
@ -925,10 +925,13 @@
|
|||
"waitFewSecondForTxUpdate": "Vui lòng đợi vài giây để giao dịch được phản ánh trong lịch sử giao dịch",
|
||||
"wallet": "Cái ví",
|
||||
"wallet_group": "Nhóm ví",
|
||||
"wallet_group_description_existing_seed": "Bạn đã chọn sử dụng một hạt giống hiện có cho ví này. Bạn có thể xác minh lại hạt giống nếu bạn cần xác nhận hoặc viết nó ra.",
|
||||
"wallet_group_description_four": "Để tạo ra một ví với một hạt giống hoàn toàn mới.",
|
||||
"wallet_group_description_one": "Trong ví bánh, bạn có thể tạo",
|
||||
"wallet_group_description_open_wallet": "Nếu không, bạn có thể tiếp tục mở ví",
|
||||
"wallet_group_description_three": "Để xem ví trên ví và/hoặc màn hình nhóm ví. Hoặc chọn",
|
||||
"wallet_group_description_two": "Bằng cách chọn một ví hiện có để chia sẻ một hạt giống với. Mỗi nhóm ví có thể chứa một ví của mỗi loại tiền tệ. \n\n Bạn có thể chọn",
|
||||
"wallet_group_description_view_seed": "Bạn luôn có thể xem lại hạt giống này dưới",
|
||||
"wallet_group_empty_state_text_one": "Có vẻ như bạn không có bất kỳ nhóm ví tương thích nào !\n\n Tap",
|
||||
"wallet_group_empty_state_text_two": "Dưới đây để làm một cái mới.",
|
||||
"wallet_keys": "Hạt giống/khóa ví",
|
||||
|
|
|
@ -927,10 +927,13 @@
|
|||
"waitFewSecondForTxUpdate": "Fi inurere duro fun awọn iṣeju diẹ fun idunadura lati ṣe afihan ninu itan-akọọlẹ iṣowo",
|
||||
"wallet": "Ohun apamọwọwọ",
|
||||
"wallet_group": "Ẹgbẹ apamọwọ",
|
||||
"wallet_group_description_existing_seed": "O ti yan lati lo irugbin ti o wa tẹlẹ fun ogiriina yii.O le rii daju iru naa lẹẹkansii ti o ba nilo lati jẹrisi tabi kọ silẹ.",
|
||||
"wallet_group_description_four": "Lati ṣẹda apamọwọ kan pẹlu irugbin tuntun tuntun.",
|
||||
"wallet_group_description_one": "Ni apamọwọ akara oyinbo, o le ṣẹda a",
|
||||
"wallet_group_description_open_wallet": "Bibẹẹkọ, o le tẹsiwaju lati ṣii apamọwọ",
|
||||
"wallet_group_description_three": "Lati wo awọn Woleti ti o wa ati / tabi Iboju Wallt. Tabi yan",
|
||||
"wallet_group_description_two": "nipa yiyan apamọwọ ti o wa tẹlẹ lati pin irugbin kan pẹlu. Ẹgbẹ apamọwọ kọọkan le ni apamọwọ kan ti iru owo kọọkan. \n\n O le yan",
|
||||
"wallet_group_description_view_seed": "O le nigbagbogbo wo irugbin yii lẹẹkansi labẹ",
|
||||
"wallet_group_empty_state_text_one": "O dabi pe o ko ni eyikeyi awọn ẹgbẹ ti o ni ibamu!\n\ntẹ ni kia kia",
|
||||
"wallet_group_empty_state_text_two": "ni isalẹ lati ṣe ọkan titun.",
|
||||
"wallet_keys": "Hóró/kọ́kọ́rọ́ àpamọ́wọ́",
|
||||
|
|
|
@ -926,10 +926,13 @@
|
|||
"waitFewSecondForTxUpdate": "请等待几秒钟,交易才会反映在交易历史记录中",
|
||||
"wallet": "钱包",
|
||||
"wallet_group": "钱包组",
|
||||
"wallet_group_description_existing_seed": "您已经选择在此钱包中使用现有种子。如果需要确认或写下来,您可能会再次验证种子。",
|
||||
"wallet_group_description_four": "创建一个带有全新种子的钱包。",
|
||||
"wallet_group_description_one": "在蛋糕钱包中,您可以创建一个",
|
||||
"wallet_group_description_open_wallet": "否则,您可以继续打开钱包",
|
||||
"wallet_group_description_three": "查看可用的钱包和/或钱包组屏幕。或选择",
|
||||
"wallet_group_description_two": "通过选择现有的钱包与种子共享。每个钱包组都可以包含每种货币类型的单个钱包。\n\n您可以选择",
|
||||
"wallet_group_description_view_seed": "您可以随时再次在下面查看此种子",
|
||||
"wallet_group_empty_state_text_one": "看起来您没有任何兼容的钱包组!\n\n tap",
|
||||
"wallet_group_empty_state_text_two": "下面是一个新的。",
|
||||
"wallet_keys": "钱包种子/密钥",
|
||||
|
|
1
scripts/android/.gitignore
vendored
Normal file
1
scripts/android/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
mwebd
|
|
@ -23,7 +23,7 @@ MONERO_COM_SCHEME="monero.com"
|
|||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="4.22.1"
|
||||
CAKEWALLET_BUILD_NUMBER=241
|
||||
CAKEWALLET_BUILD_NUMBER=242
|
||||
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
|
||||
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
|
||||
CAKEWALLET_SCHEME="cakewallet"
|
||||
|
|
|
@ -8,50 +8,20 @@ cd "$(dirname "$0")"
|
|||
|
||||
NPROC="-j$(nproc)"
|
||||
|
||||
if [[ "x$(uname)" == "xDarwin" ]];
|
||||
then
|
||||
USE_DOCKER="ON"
|
||||
NPROC="-j1"
|
||||
fi
|
||||
|
||||
../prepare_moneroc.sh
|
||||
|
||||
if [[ ! "x$RUNNER_OS" == "x" ]];
|
||||
then
|
||||
REMOVE_CACHES=ON
|
||||
fi
|
||||
|
||||
# NOTE: -j1 is intentional. Otherwise you will run into weird behaviour on macos
|
||||
if [[ ! "x$USE_DOCKER" == "x" ]];
|
||||
then
|
||||
for COIN in monero wownero;
|
||||
do
|
||||
pushd ../monero_c
|
||||
docker run --platform linux/amd64 -v$HOME/.cache/ccache:/root/.ccache -v$PWD:$PWD -w $PWD --rm -it git.mrcyjanek.net/mrcyjanek/debian:buster bash -c "git config --global --add safe.directory '*'; apt update; apt install -y ccache gcc g++ libtinfo5 gperf; ./build_single.sh ${COIN} x86_64-linux-android $NPROC"
|
||||
# docker run --platform linux/amd64 -v$PWD:$PWD -w $PWD --rm -it git.mrcyjanek.net/mrcyjanek/debian:buster bash -c "git config --global --add safe.directory '*'; apt update; apt install -y ccache gcc g++ libtinfo5 gperf; ./build_single.sh ${COIN} i686-linux-android $NPROC"
|
||||
docker run --platform linux/amd64 -v$HOME/.cache/ccache:/root/.ccache -v$PWD:$PWD -w $PWD --rm -it git.mrcyjanek.net/mrcyjanek/debian:buster bash -c "git config --global --add safe.directory '*'; apt update; apt install -y ccache gcc g++ libtinfo5 gperf; ./build_single.sh ${COIN} armv7a-linux-androideabi $NPROC"
|
||||
docker run --platform linux/amd64 -v$HOME/.cache/ccache:/root/.ccache -v$PWD:$PWD -w $PWD --rm -it git.mrcyjanek.net/mrcyjanek/debian:buster bash -c "git config --global --add safe.directory '*'; apt update; apt install -y ccache gcc g++ libtinfo5 gperf; ./build_single.sh ${COIN} aarch64-linux-android $NPROC"
|
||||
popd
|
||||
done
|
||||
else
|
||||
for COIN in monero wownero;
|
||||
do
|
||||
pushd ../monero_c
|
||||
env -i ./build_single.sh ${COIN} x86_64-linux-android $NPROC
|
||||
[[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/x86_64-linux-android
|
||||
# ./build_single.sh ${COIN} i686-linux-android $NPROC
|
||||
# [[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/i686-linux-android
|
||||
env -i ./build_single.sh ${COIN} armv7a-linux-androideabi $NPROC
|
||||
[[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/armv7a-linux-androideabi
|
||||
env -i ./build_single.sh ${COIN} aarch64-linux-android $NPROC
|
||||
[[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/aarch64-linux-android
|
||||
|
||||
popd
|
||||
unxz -f ../monero_c/release/${COIN}/x86_64-linux-android_libwallet2_api_c.so.xz
|
||||
|
||||
unxz -f ../monero_c/release/${COIN}/armv7a-linux-androideabi_libwallet2_api_c.so.xz
|
||||
|
||||
unxz -f ../monero_c/release/${COIN}/aarch64-linux-android_libwallet2_api_c.so.xz
|
||||
[[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/{built,sources}
|
||||
done
|
||||
fi
|
||||
for COIN in monero wownero;
|
||||
do
|
||||
pushd ../monero_c
|
||||
for target in {x86_64,aarch64}-linux-android armv7a-linux-androideabi
|
||||
do
|
||||
if [[ -f "release/${COIN}/${target}_libwallet2_api_c.so" ]];
|
||||
then
|
||||
echo "file exist, not building monero_c for ${COIN}/$target.";
|
||||
else
|
||||
env -i ./build_single.sh ${COIN} $target $NPROC
|
||||
unxz -f ../monero_c/release/${COIN}/${target}_libwallet2_api_c.so.xz
|
||||
fi
|
||||
done
|
||||
popd
|
||||
done
|
|
@ -16,7 +16,4 @@ cd mwebd
|
|||
git reset --hard 555349415f76a42ec5c76152b64c4ab9aabc448f
|
||||
gomobile bind -target=android -androidapi 21 .
|
||||
mkdir -p ../../../cw_mweb/android/libs/
|
||||
mv ./mwebd.aar $_
|
||||
# cleanup:
|
||||
cd ..
|
||||
rm -rf mwebd
|
||||
cp ./mwebd.aar $_
|
|
@ -19,7 +19,7 @@ MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
|||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="4.22.1"
|
||||
CAKEWALLET_BUILD_NUMBER=288
|
||||
CAKEWALLET_BUILD_NUMBER=289
|
||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||
|
||||
HAVEN_NAME="Haven"
|
||||
|
|
148
scripts/linux/Dockerfile.linux
Normal file
148
scripts/linux/Dockerfile.linux
Normal file
|
@ -0,0 +1,148 @@
|
|||
# Usage:
|
||||
# docker build . -f Dockerfile.linux -t ghcr.io/cake-tech/cake_wallet:main-linux
|
||||
# docker push ghcr.io/cake-tech/cake_wallet:main-linux
|
||||
|
||||
FROM --platform=linux/amd64 docker.io/debian:12
|
||||
|
||||
LABEL org.opencontainers.image.source=https://github.com/cake-tech/cake_wallet
|
||||
|
||||
ENV GOLANG_VERSION=1.23.4
|
||||
# comes from https://developer.android.com/studio/#command-tools
|
||||
ENV ANDROID_SDK_TOOLS_VERSION=11076708
|
||||
# https://developer.android.com/studio/releases/build-tools
|
||||
ENV ANDROID_PLATFORM_VERSION=34
|
||||
ENV ANDROID_BUILD_TOOLS_VERSION=34.0.0
|
||||
|
||||
ENV FLUTTER_VERSION=3.24.0
|
||||
|
||||
# If we ever need to migrate the home directory...
|
||||
RUN sed -i 's|^root:[^:]*:[^:]*:[^:]*:[^:]*:/root:|root:x:0:0:root:/root:|' /etc/passwd
|
||||
# mkdir -p /root && rm -rf /root && cp -a /root /root
|
||||
ENV HOME=/root
|
||||
# Heavily inspired by cirrusci images
|
||||
# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/tools/Dockerfile
|
||||
# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/34/Dockerfile
|
||||
# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/34-ndk/Dockerfile
|
||||
# https://github.com/cirruslabs/docker-images-flutter/blob/master/sdk/Dockerfile
|
||||
|
||||
ENV ANDROID_HOME=/opt/android-sdk-linux \
|
||||
LANG=en_US.UTF-8 \
|
||||
LC_ALL=en_US.UTF-8 \
|
||||
LANGUAGE=en_US:en
|
||||
|
||||
ENV ANDROID_SDK_ROOT=$ANDROID_HOME \
|
||||
PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/emulator
|
||||
|
||||
RUN set -o xtrace \
|
||||
&& cd /opt \
|
||||
&& apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get install -y jq \
|
||||
&& apt-get install -y default-jdk \
|
||||
&& apt-get install -y sudo wget zip unzip git openssh-client curl bc software-properties-common build-essential ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov libsqlite3-dev --no-install-recommends \
|
||||
# for x86 emulators
|
||||
&& apt-get install -y libxtst6 libnss3-dev libnspr4 libxss1 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \
|
||||
&& apt-get install -y -qq xxd \
|
||||
&& apt-get install -y lftp \
|
||||
&& apt-get install -qq -y sqlite3 libsqlite3-dev \
|
||||
# linux desktop dependencies
|
||||
&& apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev \
|
||||
# monero_c dependencies
|
||||
&& apt-get install -y ccache build-essential autoconf libtool gperf llvm \
|
||||
# extra stuff for KVM
|
||||
&& apt-get install -y udev qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils \
|
||||
# for linux tests
|
||||
&& apt-get install -y xvfb network-manager ffmpeg x11-utils \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' \
|
||||
&& locale-gen \
|
||||
&& update-locale LANG=en_US.UTF-8
|
||||
|
||||
# install nodejs for actions
|
||||
RUN apt-get update && \
|
||||
apt-get install -y curl && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_23.x | bash - && \
|
||||
apt-get install -y nodejs && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN wget https://go.dev/dl/go${GOLANG_VERSION}.linux-amd64.tar.gz &&\
|
||||
rm -rf /usr/local/go &&\
|
||||
tar -C /usr/local -xzf go${GOLANG_VERSION}.linux-amd64.tar.gz
|
||||
|
||||
ENV PATH=${PATH}:/usr/local/go/bin:${HOME}/go/bin
|
||||
ENV GOROOT=/usr/local/go
|
||||
ENV GOPATH=${HOME}/go
|
||||
RUN go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
RUN gomobile init
|
||||
|
||||
RUN wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip -O android-sdk-tools.zip \
|
||||
&& mkdir -p ${ANDROID_HOME}/cmdline-tools/ \
|
||||
&& unzip -q android-sdk-tools.zip -d ${ANDROID_HOME}/cmdline-tools/ \
|
||||
&& mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \
|
||||
&& chown -R root:root $ANDROID_HOME \
|
||||
&& rm android-sdk-tools.zip \
|
||||
&& echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \
|
||||
&& yes | sdkmanager --licenses \
|
||||
&& wget -O /usr/bin/android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/master/community-cookbooks/android-sdk/files/default/android-wait-for-emulator \
|
||||
&& chmod +x /usr/bin/android-wait-for-emulator \
|
||||
&& sdkmanager platform-tools \
|
||||
&& mkdir -p ${HOME}/.android \
|
||||
&& touch ${HOME}/.android/repositories.cfg \
|
||||
&& git config --global user.email "czarek@cakewallet.com" \
|
||||
&& git config --global user.name "CakeWallet CI"
|
||||
|
||||
# emulator is not available on linux/arm64 (https://issuetracker.google.com/issues/227219818)
|
||||
RUN if [ $(uname -m) == "x86_64" ]; then sdkmanager emulator ; fi
|
||||
|
||||
# Extra dependencies to not download them for cake wallet build
|
||||
RUN yes | sdkmanager \
|
||||
"platforms;android-$ANDROID_PLATFORM_VERSION" \
|
||||
"build-tools;$ANDROID_BUILD_TOOLS_VERSION" \
|
||||
"platforms;android-33" \
|
||||
"build-tools;33.0.2" \
|
||||
"build-tools;33.0.1" \
|
||||
"build-tools;33.0.0" \
|
||||
"build-tools;35.0.0"
|
||||
|
||||
ENV ANDROID_NDK_VERSION=27.2.12479018
|
||||
|
||||
# Extra ndk dependency for sp_scanner
|
||||
RUN yes | sdkmanager "ndk;$ANDROID_NDK_VERSION" \
|
||||
"ndk;27.0.12077973"
|
||||
|
||||
# https://github.com/ReactiveCircus/android-emulator-runner dependencies for tests
|
||||
RUN yes | sdkmanager "system-images;android-29;default;x86" \
|
||||
"system-images;android-29;default;x86_64" \
|
||||
"system-images;android-31;default;x86_64" \
|
||||
"platforms;android-29"
|
||||
|
||||
# fake the KVM status so android emulator doesn't complain (that much)
|
||||
RUN (addgroup kvm || true) && \
|
||||
adduser root kvm && \
|
||||
mkdir -p /etc/udev/rules.d/ && \
|
||||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | tee /etc/udev/rules.d/99-kvm4all.rules
|
||||
|
||||
ENV PATH=${HOME}/.cargo/bin:${PATH}
|
||||
|
||||
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y && \
|
||||
cargo install cargo-ndk && \
|
||||
for target in aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android x86_64-unknown-linux-gnu; \
|
||||
do \
|
||||
rustup target add --toolchain stable $target; \
|
||||
done
|
||||
|
||||
|
||||
ENV HOME=${HOME}
|
||||
ENV FLUTTER_HOME=${HOME}/sdks/flutter/${FLUTTER_VERSION}
|
||||
ENV FLUTTER_ROOT=$FLUTTER_HOME
|
||||
|
||||
ENV PATH=${PATH}:${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin
|
||||
|
||||
RUN git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git ${FLUTTER_HOME}
|
||||
|
||||
RUN yes | flutter doctor --android-licenses \
|
||||
&& flutter doctor \
|
||||
&& chown -R root:root ${FLUTTER_HOME}
|
||||
|
||||
RUN flutter precache
|
|
@ -15,7 +15,7 @@ fi
|
|||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="1.12.1"
|
||||
CAKEWALLET_BUILD_NUMBER=42
|
||||
CAKEWALLET_BUILD_NUMBER=43
|
||||
|
||||
if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
|
||||
echo "Wrong app type."
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
. ./config.sh
|
||||
|
||||
|
||||
set -x -e
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
@ -15,7 +11,15 @@ NPROC="-j$(nproc)"
|
|||
for COIN in monero wownero;
|
||||
do
|
||||
pushd ../monero_c
|
||||
./build_single.sh ${COIN} $(gcc -dumpmachine) $NPROC
|
||||
for target in x86_64-linux-gnu
|
||||
do
|
||||
if [[ -f "release/${COIN}/${target}_libwallet2_api_c.so" ]];
|
||||
then
|
||||
echo "file exist, not building monero_c for ${COIN}/$target.";
|
||||
else
|
||||
./build_single.sh ${COIN} $target $NPROC
|
||||
unxz -f ../monero_c/release/${COIN}/${target}_libwallet2_api_c.so.xz
|
||||
fi
|
||||
done
|
||||
popd
|
||||
unxz -f ../monero_c/release/${COIN}/$(gcc -dumpmachine)_libwallet2_api_c.so.xz
|
||||
done
|
||||
done
|
|
@ -22,7 +22,7 @@ MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
|||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="1.15.1"
|
||||
CAKEWALLET_BUILD_NUMBER=100
|
||||
CAKEWALLET_BUILD_NUMBER=101
|
||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||
|
||||
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
|
||||
|
|
|
@ -4,9 +4,9 @@ set -x -e
|
|||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
if [[ ! -d "monero_c" ]];
|
||||
if [[ ! -d "monero_c/.git" ]];
|
||||
then
|
||||
git clone https://github.com/mrcyjanek/monero_c --branch master
|
||||
git clone https://github.com/mrcyjanek/monero_c --branch master monero_c
|
||||
cd monero_c
|
||||
git checkout af5277f96073917185864d3596e82b67bee54e78
|
||||
git reset --hard
|
||||
|
|
1
scripts/windows/.gitignore
vendored
Normal file
1
scripts/windows/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
actions-runner
|
68
scripts/windows/Dockerfile.windows
Normal file
68
scripts/windows/Dockerfile.windows
Normal file
|
@ -0,0 +1,68 @@
|
|||
# Usage:
|
||||
# docker build . -f Dockerfile.windows -t ghcr.io/cake-tech/cake_wallet:main-windows
|
||||
# docker push ghcr.io/cake-tech/cake_wallet:main-windows
|
||||
|
||||
FROM mcr.microsoft.com/windows/servercore:ltsc2022
|
||||
|
||||
ENV FLUTTER_VERSION=3.24.0
|
||||
ENV GIT_VERSION=2.47.1
|
||||
ENV VS_INSTALLED_DIR="C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools"
|
||||
ENV PATH="C:\Users\ContainerAdministrator\.cargo\bin;C:\ProgramData\chocolatey\bin;C:\flutter\flutter\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\ContainerAdministrator\AppData\Local\Microsoft\WindowsApps"
|
||||
ENV RUNNER_VERSION=2.321.0
|
||||
ENV RUNNER_URL=https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-win-x64-${RUNNER_VERSION}.zip
|
||||
ENV RUNNER_WORKDIR=_work
|
||||
|
||||
RUN powershell -Command \
|
||||
curl.exe -L https://aka.ms/vs/17/release/vc_redist.x64.exe -o vc_redist.x64.exe ; \
|
||||
Start-Process -Wait -FilePath .\vc_redist.x64.exe -ArgumentList '/quiet', '/install' ; \
|
||||
Remove-Item -Force vc_redist.x64.exe
|
||||
|
||||
RUN powershell -Command \
|
||||
$GIT_VERSION = [Environment]::GetEnvironmentVariable('GIT_VERSION'); \
|
||||
curl.exe -L https://github.com/git-for-windows/git/releases/download/v$($GIT_VERSION).windows.1/Git-$($GIT_VERSION)-64-bit.exe -o git_installer.exe ; \
|
||||
Start-Process -Wait -FilePath .\git_installer.exe -ArgumentList '/SILENT', '/NOICONS' ; \
|
||||
Remove-Item -Force git_installer.exe
|
||||
|
||||
RUN powershell -NoProfile -ExecutionPolicy Bypass -Command \
|
||||
Set-ExecutionPolicy RemoteSigned -Scope Process; \
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; \
|
||||
Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicP -OutFile install.ps1; \
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File install.ps1; \
|
||||
Remove-Item -Force install.ps1
|
||||
|
||||
RUN choco install -y visualstudio2022community
|
||||
RUN choco install -y visualstudio2022-workload-nativedesktop
|
||||
RUN choco install -y nodejs
|
||||
RUN choco install -y go
|
||||
RUN choco install -y 7zip
|
||||
|
||||
RUN powershell -Command \
|
||||
curl.exe -L https://win.rustup.rs -o rustup-init.exe; \
|
||||
Start-Process -Wait -FilePath .\rustup-init.exe -ArgumentList "-y"; \
|
||||
Remove-Item -Force .\rustup-init.exe
|
||||
|
||||
RUN powershell -Command \
|
||||
curl.exe -L https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -o C:\Windows\System32\nuget.exe
|
||||
|
||||
RUN powershell -Command \
|
||||
$FLUTTER_VERSION = [Environment]::GetEnvironmentVariable('FLUTTER_VERSION'); \
|
||||
curl.exe -L https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_$($FLUTTER_VERSION)-stable.zip -o flutter.zip ; \
|
||||
7z x flutter.zip -oC:\flutter -bsp1 -bse1 ; \
|
||||
Remove-Item -Force flutter.zip
|
||||
|
||||
RUN flutter precache
|
||||
|
||||
WORKDIR C:\\actions-runner
|
||||
|
||||
RUN powershell -Command \
|
||||
curl.exe -L $env:RUNNER_URL -o 'actions-runner.zip'; \
|
||||
7z x actions-runner.zip -oC:\actions-runner -bsp1 -bse1 ; \
|
||||
Remove-Item -Path 'actions-runner.zip'
|
||||
|
||||
COPY actions-runner/.credentials /actions-runner/.credentials
|
||||
COPY actions-runner/.credentials_rsaparams /actions-runner/.credentials_rsaparams
|
||||
COPY actions-runner/.runner /actions-runner/.runner
|
||||
|
||||
COPY ci_entrypoint.ps1 /actions-runner/ci_entrypoint.ps1
|
||||
|
||||
ENTRYPOINT ["powershell", "-File", "ci_entrypoint.ps1"]
|
5
scripts/windows/ci_entrypoint.ps1
Normal file
5
scripts/windows/ci_entrypoint.ps1
Normal file
|
@ -0,0 +1,5 @@
|
|||
$runnerDir = "C:\actions-runner"
|
||||
$runCmd = "$runnerDir\run.cmd"
|
||||
|
||||
Write-Host "Starting the runner..."
|
||||
& $runCmd
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue