diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index e9c53c00f..c0042bf5c 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -23,9 +23,10 @@ jobs:
docker-images: true
- uses: actions/checkout@v2
- - uses: actions/setup-java@v1
+ - uses: actions/setup-java@v2
with:
- java-version: "11.x"
+ distribution: "temurin"
+ java-version: "17"
- name: Configure placeholder git details
run: |
git config --global user.email "CI@cakewallet.com"
@@ -60,7 +61,7 @@ jobs:
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') }}
+ key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
name: Generate Externals
diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build_android.yml
similarity index 85%
rename from .github/workflows/pr_test_build.yml
rename to .github/workflows/pr_test_build_android.yml
index 4c46137ac..c9021fac0 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -13,6 +13,9 @@ on:
jobs:
PR_test_build:
runs-on: ubuntu-20.04
+ strategy:
+ matrix:
+ api-level: [29]
env:
STORE_PASS: test@cake_wallet
KEY_PASS: test@cake_wallet
@@ -39,9 +42,10 @@ jobs:
docker-images: true
- uses: actions/checkout@v2
- - uses: actions/setup-java@v1
+ - uses: actions/setup-java@v2
with:
- java-version: "17.x"
+ distribution: "temurin"
+ java-version: "17"
- name: Configure placeholder git details
run: |
git config --global user.email "CI@cakewallet.com"
@@ -53,7 +57,9 @@ jobs:
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
+ run: |
+ sudo apt update
+ sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
- name: Execute Build and Setup Commands
run: |
@@ -76,7 +82,7 @@ jobs:
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') }}
+ key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
name: Generate Externals
@@ -90,6 +96,25 @@ jobs:
cd /opt/android/cake_wallet
flutter pub get
+
+ - name: Install go and gomobile
+ run: |
+ # install go > 1.23:
+ wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz
+ sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz
+ export PATH=$PATH:/usr/local/go/bin
+ export PATH=$PATH:~/go/bin
+ go install golang.org/x/mobile/cmd/gomobile@latest
+ gomobile init
+
+ - name: Build mwebd
+ run: |
+ # paths are reset after each step, so we need to set them again:
+ export PATH=$PATH:/usr/local/go/bin
+ export PATH=$PATH:~/go/bin
+ cd /opt/android/cake_wallet/scripts/android/
+ ./build_mwebd.sh --dont-install
+
- name: Generate KeyStore
run: |
cd /opt/android/cake_wallet/android/app
@@ -146,6 +171,8 @@ jobs:
echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
@@ -165,6 +192,10 @@ jobs:
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+ echo "const 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
run: |
@@ -193,6 +224,7 @@ jobs:
cd /opt/android/cake_wallet/build/app/outputs/flutter-apk
mkdir test-apk
cp app-arm64-v8a-release.apk test-apk/${{env.BRANCH_NAME}}.apk
+ cp app-x86_64-release.apk test-apk/${{env.BRANCH_NAME}}_x86.apk
- name: Upload Artifact
uses: kittaakos/upload-artifact-as-is@v0
diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml
new file mode 100644
index 000000000..5ea0cb377
--- /dev/null
+++ b/.github/workflows/pr_test_build_linux.yml
@@ -0,0 +1,212 @@
+name: PR Test Build linux
+
+on:
+ pull_request:
+ branches: [main]
+ workflow_dispatch:
+ inputs:
+ branch:
+ description: "Branch name to build"
+ required: true
+ default: "main"
+
+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 }}
+
+ steps:
+ - name: is pr
+ if: github.event_name == 'pull_request'
+ run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
+
+ - name: is not pr
+ if: github.event_name != 'pull_request'
+ run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENVg
+
+ - uses: actions/checkout@v2
+ - uses: actions/setup-java@v1
+ with:
+ java-version: "17.x"
+ - name: Configure placeholder git details
+ run: |
+ git config --global user.email "CI@cakewallet.com"
+ git config --global user.name "Cake Github Actions"
+ - name: Flutter action
+ uses: subosito/flutter-action@v1
+ with:
+ flutter-version: "3.19.6"
+ 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
+ flutter packages pub run tool/generate_localization.dart
+
+ - name: Build generated code
+ run: |
+ cd /opt/android/cake_wallet
+ ./model_generator.sh
+
+ - name: Add secrets
+ run: |
+ cd /opt/android/cake_wallet
+ touch lib/.secrets.g.dart
+ touch cw_evm/lib/.secrets.g.dart
+ touch cw_solana/lib/.secrets.g.dart
+ touch cw_core/lib/.secrets.g.dart
+ touch cw_nano/lib/.secrets.g.dart
+ touch cw_tron/lib/.secrets.g.dart
+ echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
+ echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+ echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
+ echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
+ echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
+ echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
+ echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+ echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
+ echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
+ echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
+ echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
+ echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
+ echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
+ echo "const 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
+ echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
+ echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
+ echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart
+ echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+ echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+ echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
+ echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
+ echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
+ echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
+ echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+ echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
+ echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+ echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
+ echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
+ echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
+ echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
+ echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
+ echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+ echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+ echo "const 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
+ run: |
+ echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+
+ - name: Build
+ run: |
+ cd /opt/android/cake_wallet
+ flutter build linux --release
+
+ - name: Prepare release zip file
+ run: |
+ cd /opt/android/cake_wallet/build/linux/x64/release
+ zip -r ${{env.BRANCH_NAME}}.zip bundle
+
+ - name: Upload Artifact
+ uses: kittaakos/upload-artifact-as-is@v0
+ with:
+ path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
+
+# 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 }}
diff --git a/.gitignore b/.gitignore
index 2e30ed6bc..5eaf3c18e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -161,6 +161,8 @@ macos/Runner/Release.entitlements
macos/Runner/Runner.entitlements
lib/core/secure_storage.dart
+lib/core/secure_storage.dart
+
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
@@ -170,6 +172,9 @@ macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
macos/Runner/Configs/AppInfo.xcconfig
+
+integration_test/playground.dart
+
# Monero.dart (Monero_C)
scripts/monero_c
# iOS generated framework bin
diff --git a/.metadata b/.metadata
index 7d00ca21a..c7b8dc9f8 100644
--- a/.metadata
+++ b/.metadata
@@ -18,6 +18,12 @@ migration:
- platform: windows
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+ - platform: macos
+ create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+ base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+ - platform: linux
+ create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+ base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
# User provided section
diff --git a/PRIVACY.md b/PRIVACY.md
index 76cfcc4d3..a5c8eddfb 100644
--- a/PRIVACY.md
+++ b/PRIVACY.md
@@ -5,7 +5,7 @@ Last modified: January 24, 2024
Introduction
============
- Cake Labs LLC ("Cake Labs", "Company", or "We") respect your privacy and are committed to protecting it through our compliance with this policy.
+ Cake Labs LLC ("Cake Labs", "Company", or "We") respects your privacy and are committed to protecting it through our compliance with this policy.
This policy describes the types of information we may collect from you or that you may provide when you use the App (our "App") and our practices for collecting, using, maintaining, protecting, and disclosing that information.
@@ -13,7 +13,7 @@ Introduction
- On this App.
- In email, text, and other electronic messages between you and this App.
It does not apply to information collected by:
- - Us offline or through any other means, including on any other App operated by Company or any third party (including our affiliates and subsidiaries); or
+ - Us offline or through any other means, including on any other App operated by the Company or any third party (including our affiliates and subsidiaries); or
- Any third party (including our affiliates and subsidiaries), including through any application or content (including advertising) that may link to or be accessible from or on the App.
Please read this policy carefully to understand our policies and practices regarding your information and how we will treat it. If you do not agree with our policies and practices, you have the choice to not use the App. By accessing or using this App, you agree to this privacy policy. This policy may change from time to time. Your continued use of this App after we make changes is deemed to be acceptance of those changes, so please check the policy periodically for updates.
diff --git a/README.md b/README.md
index 7823734fb..078c4437e 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-

+
@@ -18,7 +18,7 @@
# Cake Wallet
-Cake Wallet is an open source, non-custodial, and private multi-currency crypto wallet for Android, iOS, macOS, and Linux.
+[Cake Wallet](https://cakewallet.com) is an open-source, non-custodial, and private multi-currency crypto wallet for Android, iOS, macOS, and Linux.
Cake Wallet includes support for several cryptocurrencies, including:
* Monero (XMR)
@@ -26,7 +26,7 @@ Cake Wallet includes support for several cryptocurrencies, including:
* Ethereum (ETH)
* Litecoin (LTC)
* Bitcoin Cash (BCH)
-* Polygon (MATIC)
+* Polygon (Pol)
* Solana (SOL)
* Nano (XNO)
* Haven (XHV)
@@ -44,7 +44,7 @@ Cake Wallet includes support for several cryptocurrencies, including:
* Create several wallets
* Select your own custom nodes/servers
* Address book
-* Backup to external location or iCloud
+* Backup to an external location or iCloud
* Send to OpenAlias, Unstoppable Domains, Yats, and FIO Crypto Handles
* Set desired network fee level
* Store local transaction notes
@@ -161,7 +161,9 @@ The only parts to be translated, if needed, are the values m and s after the var
4. Add the language to `lib/entities/language_service.dart` under both `supportedLocales` and `localeCountryCode`. Use the name of the language in the local language and in English in parentheses after for `supportedLocales`. Use the [ISO 3166-1 alpha-3 code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) for `localeCountryCode`. You must choose one country, so choose the country with the most native speakers of this language or is otherwise best associated with this language.
-5. Add a relevant flag to `assets/images/flags/XXXX.png`, replacing XXXX with the 3 digit localeCountryCode. The image must be 42x26 pixels with a 3 pixels of transparent margin on all 4 sides. You can resize the flag with [paint.net](https://www.getpaint.net/) to 36x20 pixels, expand the canvas to 42x26 pixels with the flag anchored in the middle, and then manually delete the 3 pixels on each side to make transparent. Or you can use another program like Photoshop.
+5. Add a relevant flag to `assets/images/flags/XXXX.png`, replacing XXXX with the 3 letters localeCountryCode. The image must be 42x26 pixels with 3 pixels of transparent margin on all 4 sides. You can resize the flag with [paint.net](https://www.getpaint.net/) to 36x20 pixels, expand the canvas to 42x26 pixels with the flag anchored in the middle, and then manually delete the 3 pixels on each side to make it transparent. Or you can use another program like Photoshop.
+
+6. Add the new language code to `tool/utils/translation/translation_constants.dart`
## Add a new fiat currency
diff --git a/SECURITY.md b/SECURITY.md
index a1b489b76..e7c6baa02 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -9,4 +9,4 @@ If you need to report a vulnerability, please either:
## Supported Versions
-As we don't maintain prevoius versions of the app, only the latest release for each platform is supported and any updates will bump the version number.
+As we don't maintain previous versions of the app, only the latest release for each platform is supported and any updates will bump the version number.
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 396904041..be68a4f26 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,5 +1,6 @@
include: package:lints/recommended.yaml
+
analyzer:
exclude: [
build/**,
@@ -10,7 +11,18 @@ analyzer:
lib/generated/*.dart,
cw_monero/ios/External/**,
cw_shared_external/**,
- shared_external/**]
+ shared_external/**,
+ lib/bitcoin/cw_bitcoin.dart,
+ lib/bitcoin_cash/cw_bitcoin_cash.dart,
+ lib/ethereum/cw_ethereum.dart,
+ lib/haven/cw_haven.dart,
+ lib/monero/cw_monero.dart,
+ lib/nano/cw_nano.dart,
+ lib/polygon/cw_polygon.dart,
+ lib/solana/cw_solana.dart,
+ lib/tron/cw_tron.dart,
+ lib/wownero/cw_wownero.dart,
+ ]
language:
strict-casts: true
strict-raw-types: true
@@ -72,4 +84,4 @@ linter:
# - unawaited_futures
# - unnecessary_getters_setters
# - unrelated_type_equality_checks
-# - valid_regexps
\ No newline at end of file
+# - valid_regexps
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 60defb1fd..2f5427531 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -91,5 +91,4 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
- implementation 'com.unstoppabledomains:resolution:5.0.0'
}
diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml
index b03c8a925..5b080e3ec 100644
--- a/android/app/src/main/AndroidManifestBase.xml
+++ b/android/app/src/main/AndroidManifestBase.xml
@@ -1,35 +1,31 @@
-
-
-
-
-
+
+
-
-
+
-
-
-
+
+
+
-
-
-
+
+
+
+
+
-
+
+
+
+
-
+
+
result.success(bytes));
break;
- case "getUnstoppableDomainAddress":
- int version = Build.VERSION.SDK_INT;
- if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
- getUnstoppableDomainAddress(call, result);
- } else {
- handler.post(() -> result.success(""));
- }
- break;
case "setIsAppSecure":
isAppSecure = call.argument("isAppSecure");
if (isAppSecure) {
@@ -85,23 +73,6 @@ public class MainActivity extends FlutterFragmentActivity {
}
}
- private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
- DomainResolution resolution = new Resolution();
- Handler handler = new Handler(Looper.getMainLooper());
- String domain = call.argument("domain");
- String ticker = call.argument("ticker");
-
- AsyncTask.execute(() -> {
- try {
- String address = resolution.getAddress(domain, ticker);
- handler.post(() -> result.success(address));
- } catch (Exception e) {
- System.out.println("Expected Address, but got " + e.getMessage());
- handler.post(() -> result.success(""));
- }
- });
- }
-
private void disableBatteryOptimization() {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/android/app/src/main/java/com/cakewallet/haven/MainActivity.java b/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
index d0a465d22..83a790683 100644
--- a/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
+++ b/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
@@ -19,14 +19,10 @@ import android.net.Uri;
import android.os.PowerManager;
import android.provider.Settings;
-import com.unstoppabledomains.resolution.DomainResolution;
-import com.unstoppabledomains.resolution.Resolution;
-
import java.security.SecureRandom;
public class MainActivity extends FlutterFragmentActivity {
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
- final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
@@ -51,14 +47,6 @@ public class MainActivity extends FlutterFragmentActivity {
random.nextBytes(bytes);
handler.post(() -> result.success(bytes));
break;
- case "getUnstoppableDomainAddress":
- int version = Build.VERSION.SDK_INT;
- if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
- getUnstoppableDomainAddress(call, result);
- } else {
- handler.post(() -> result.success(""));
- }
- break;
case "disableBatteryOptimization":
disableBatteryOptimization();
handler.post(() -> result.success(null));
@@ -75,23 +63,6 @@ public class MainActivity extends FlutterFragmentActivity {
}
}
- private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
- DomainResolution resolution = new Resolution();
- Handler handler = new Handler(Looper.getMainLooper());
- String domain = call.argument("domain");
- String ticker = call.argument("ticker");
-
- AsyncTask.execute(() -> {
- try {
- String address = resolution.getAddress(domain, ticker);
- handler.post(() -> result.success(address));
- } catch (Exception e) {
- System.out.println("Expected Address, but got " + e.getMessage());
- handler.post(() -> result.success(""));
- }
- });
- }
-
private void disableBatteryOptimization() {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/android/app/src/main/java/com/monero/app/MainActivity.java b/android/app/src/main/java/com/monero/app/MainActivity.java
index 49c368ec7..e6306d27b 100644
--- a/android/app/src/main/java/com/monero/app/MainActivity.java
+++ b/android/app/src/main/java/com/monero/app/MainActivity.java
@@ -19,14 +19,10 @@ import android.net.Uri;
import android.os.PowerManager;
import android.provider.Settings;
-import com.unstoppabledomains.resolution.DomainResolution;
-import com.unstoppabledomains.resolution.Resolution;
-
import java.security.SecureRandom;
public class MainActivity extends FlutterFragmentActivity {
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
- final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
boolean isAppSecure = false;
@Override
@@ -52,14 +48,6 @@ public class MainActivity extends FlutterFragmentActivity {
random.nextBytes(bytes);
handler.post(() -> result.success(bytes));
break;
- case "getUnstoppableDomainAddress":
- int version = Build.VERSION.SDK_INT;
- if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
- getUnstoppableDomainAddress(call, result);
- } else {
- handler.post(() -> result.success(""));
- }
- break;
case "setIsAppSecure":
isAppSecure = call.argument("isAppSecure");
if (isAppSecure) {
@@ -84,23 +72,6 @@ public class MainActivity extends FlutterFragmentActivity {
}
}
- private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
- DomainResolution resolution = new Resolution();
- Handler handler = new Handler(Looper.getMainLooper());
- String domain = call.argument("domain");
- String ticker = call.argument("ticker");
-
- AsyncTask.execute(() -> {
- try {
- String address = resolution.getAddress(domain, ticker);
- handler.post(() -> result.success(address));
- } catch (Exception e) {
- System.out.println("Expected Address, but got " + e.getMessage());
- handler.post(() -> result.success(""));
- }
- });
- }
-
private void disableBatteryOptimization() {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/android/build.gradle b/android/build.gradle
index aa9f5005d..7ddb75179 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -2,7 +2,7 @@ buildscript {
ext.kotlin_version = '1.8.21'
repositories {
google()
- jcenter()
+ mavenCentral()
}
dependencies {
@@ -15,7 +15,7 @@ buildscript {
allprojects {
repositories {
google()
- jcenter()
+ mavenCentral()
}
}
diff --git a/assets/bitcoin_cash_electrum_server_list.yml b/assets/bitcoin_cash_electrum_server_list.yml
index d76668169..948e5f3dc 100644
--- a/assets/bitcoin_cash_electrum_server_list.yml
+++ b/assets/bitcoin_cash_electrum_server_list.yml
@@ -1,3 +1,10 @@
-
uri: bitcoincash.stackwallet.com:50002
- is_default: true
\ No newline at end of file
+ is_default: true
+ useSSL: true
+-
+ uri: bch.aftrek.org:50002
+ useSSL: true
+-
+ uri: node.minisatoshi.cash:50002
+ useSSL: true
diff --git a/assets/bitcoin_electrum_server_list.yml b/assets/bitcoin_electrum_server_list.yml
index 8b734a7bb..20a28cd24 100644
--- a/assets/bitcoin_electrum_server_list.yml
+++ b/assets/bitcoin_electrum_server_list.yml
@@ -3,6 +3,10 @@
useSSL: true
-
uri: btc-electrum.cakewallet.com:50002
+ useSSL: true
isDefault: true
-
uri: electrs.cakewallet.com:50001
+-
+ uri: fulcrum.sethforprivacy.com:50002
+ useSSL: true
diff --git a/assets/images/cards.png b/assets/images/cards.png
new file mode 100644
index 000000000..b263bc742
Binary files /dev/null and b/assets/images/cards.png differ
diff --git a/assets/images/cards.svg b/assets/images/cards.svg
deleted file mode 100644
index 699f9d311..000000000
--- a/assets/images/cards.svg
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
diff --git a/assets/images/dfx_dark.png b/assets/images/dfx_dark.png
index cbba87372..6ac112eae 100644
Binary files a/assets/images/dfx_dark.png and b/assets/images/dfx_dark.png differ
diff --git a/assets/images/dfx_light.png b/assets/images/dfx_light.png
index e4836be3e..a045d3e68 100644
Binary files a/assets/images/dfx_light.png and b/assets/images/dfx_light.png differ
diff --git a/assets/images/flags/are.png b/assets/images/flags/are.png
index ae68c4ff2..2df30486a 100644
Binary files a/assets/images/flags/are.png and b/assets/images/flags/are.png differ
diff --git a/assets/images/flags/arg.png b/assets/images/flags/arg.png
index c5bd233d2..d87458455 100644
Binary files a/assets/images/flags/arg.png and b/assets/images/flags/arg.png differ
diff --git a/assets/images/flags/arm.png b/assets/images/flags/arm.png
new file mode 100644
index 000000000..0e4c356e2
Binary files /dev/null and b/assets/images/flags/arm.png differ
diff --git a/assets/images/flags/aus.png b/assets/images/flags/aus.png
index c8837731c..2364fa9ef 100644
Binary files a/assets/images/flags/aus.png and b/assets/images/flags/aus.png differ
diff --git a/assets/images/flags/bgd.png b/assets/images/flags/bgd.png
index 0f8c5cfe5..802233d1c 100644
Binary files a/assets/images/flags/bgd.png and b/assets/images/flags/bgd.png differ
diff --git a/assets/images/flags/bgr.png b/assets/images/flags/bgr.png
index a89509f1f..fc53406b4 100644
Binary files a/assets/images/flags/bgr.png and b/assets/images/flags/bgr.png differ
diff --git a/assets/images/flags/bra.png b/assets/images/flags/bra.png
index ecac6f5a3..6c4ba8968 100644
Binary files a/assets/images/flags/bra.png and b/assets/images/flags/bra.png differ
diff --git a/assets/images/flags/cad.png b/assets/images/flags/cad.png
index 106cea5b9..a96ea16f6 100644
Binary files a/assets/images/flags/cad.png and b/assets/images/flags/cad.png differ
diff --git a/assets/images/flags/che.png b/assets/images/flags/che.png
index 427db0fbc..eab82b708 100644
Binary files a/assets/images/flags/che.png and b/assets/images/flags/che.png differ
diff --git a/assets/images/flags/chl.png b/assets/images/flags/chl.png
index 73a38f406..4328f0d08 100644
Binary files a/assets/images/flags/chl.png and b/assets/images/flags/chl.png differ
diff --git a/assets/images/flags/chn.png b/assets/images/flags/chn.png
index 7a03dd26e..d326f7afa 100644
Binary files a/assets/images/flags/chn.png and b/assets/images/flags/chn.png differ
diff --git a/assets/images/flags/col.png b/assets/images/flags/col.png
index 9a0fc6ac1..798cd6374 100644
Binary files a/assets/images/flags/col.png and b/assets/images/flags/col.png differ
diff --git a/assets/images/flags/czk.png b/assets/images/flags/czk.png
index a6c13a773..e4578e86c 100644
Binary files a/assets/images/flags/czk.png and b/assets/images/flags/czk.png differ
diff --git a/assets/images/flags/deu.png b/assets/images/flags/deu.png
index 95b88a0ea..9bebd76f3 100644
Binary files a/assets/images/flags/deu.png and b/assets/images/flags/deu.png differ
diff --git a/assets/images/flags/dnk.png b/assets/images/flags/dnk.png
index 69dd1b2b8..e02d42bfe 100644
Binary files a/assets/images/flags/dnk.png and b/assets/images/flags/dnk.png differ
diff --git a/assets/images/flags/egy.png b/assets/images/flags/egy.png
index 062ee21cf..692e7de78 100644
Binary files a/assets/images/flags/egy.png and b/assets/images/flags/egy.png differ
diff --git a/assets/images/flags/esp.png b/assets/images/flags/esp.png
index 0193a6a44..6b12aff49 100644
Binary files a/assets/images/flags/esp.png and b/assets/images/flags/esp.png differ
diff --git a/assets/images/flags/eur.png b/assets/images/flags/eur.png
index 1312b0200..2500968a9 100644
Binary files a/assets/images/flags/eur.png and b/assets/images/flags/eur.png differ
diff --git a/assets/images/flags/fra.png b/assets/images/flags/fra.png
index 91dce8ff2..2f432f4af 100644
Binary files a/assets/images/flags/fra.png and b/assets/images/flags/fra.png differ
diff --git a/assets/images/flags/gbr.png b/assets/images/flags/gbr.png
index 151f06db5..8b53f8851 100644
Binary files a/assets/images/flags/gbr.png and b/assets/images/flags/gbr.png differ
diff --git a/assets/images/flags/gha.png b/assets/images/flags/gha.png
index 8d6801e81..6e38331bb 100644
Binary files a/assets/images/flags/gha.png and b/assets/images/flags/gha.png differ
diff --git a/assets/images/flags/gtm.png b/assets/images/flags/gtm.png
index 2083ad806..8841a352a 100644
Binary files a/assets/images/flags/gtm.png and b/assets/images/flags/gtm.png differ
diff --git a/assets/images/flags/hau.png b/assets/images/flags/hau.png
index 7583b5daf..2bfb0a71c 100644
Binary files a/assets/images/flags/hau.png and b/assets/images/flags/hau.png differ
diff --git a/assets/images/flags/hkg.png b/assets/images/flags/hkg.png
index 85925604e..8c4cd78ae 100644
Binary files a/assets/images/flags/hkg.png and b/assets/images/flags/hkg.png differ
diff --git a/assets/images/flags/hrv.png b/assets/images/flags/hrv.png
index 9c87c5d0e..43c936b1e 100644
Binary files a/assets/images/flags/hrv.png and b/assets/images/flags/hrv.png differ
diff --git a/assets/images/flags/hun.png b/assets/images/flags/hun.png
index 9722561a8..397910aa3 100644
Binary files a/assets/images/flags/hun.png and b/assets/images/flags/hun.png differ
diff --git a/assets/images/flags/idn.png b/assets/images/flags/idn.png
index 52c965921..d1f01d8b5 100644
Binary files a/assets/images/flags/idn.png and b/assets/images/flags/idn.png differ
diff --git a/assets/images/flags/ind.png b/assets/images/flags/ind.png
index ef721a2aa..45d4a7109 100644
Binary files a/assets/images/flags/ind.png and b/assets/images/flags/ind.png differ
diff --git a/assets/images/flags/irn.png b/assets/images/flags/irn.png
index 151a03919..ec59e48c3 100644
Binary files a/assets/images/flags/irn.png and b/assets/images/flags/irn.png differ
diff --git a/assets/images/flags/isl.png b/assets/images/flags/isl.png
index ed545e905..d24f29abb 100644
Binary files a/assets/images/flags/isl.png and b/assets/images/flags/isl.png differ
diff --git a/assets/images/flags/isr.png b/assets/images/flags/isr.png
index 9f815dcbd..f28dff1ad 100644
Binary files a/assets/images/flags/isr.png and b/assets/images/flags/isr.png differ
diff --git a/assets/images/flags/ita.png b/assets/images/flags/ita.png
index 768f5a181..8af7190b8 100644
Binary files a/assets/images/flags/ita.png and b/assets/images/flags/ita.png differ
diff --git a/assets/images/flags/jpn.png b/assets/images/flags/jpn.png
index a13ef4178..b5c6fb4c4 100644
Binary files a/assets/images/flags/jpn.png and b/assets/images/flags/jpn.png differ
diff --git a/assets/images/flags/kor.png b/assets/images/flags/kor.png
index 36e867ea8..ccc181522 100644
Binary files a/assets/images/flags/kor.png and b/assets/images/flags/kor.png differ
diff --git a/assets/images/flags/mar.png b/assets/images/flags/mar.png
index 65b31c892..dda3a0131 100644
Binary files a/assets/images/flags/mar.png and b/assets/images/flags/mar.png differ
diff --git a/assets/images/flags/mex.png b/assets/images/flags/mex.png
index 9531a3ea2..f81102912 100644
Binary files a/assets/images/flags/mex.png and b/assets/images/flags/mex.png differ
diff --git a/assets/images/flags/mmr.png b/assets/images/flags/mmr.png
index 7fc6e1661..c2f9fec10 100644
Binary files a/assets/images/flags/mmr.png and b/assets/images/flags/mmr.png differ
diff --git a/assets/images/flags/mys.png b/assets/images/flags/mys.png
index 022476291..d151a3e4f 100644
Binary files a/assets/images/flags/mys.png and b/assets/images/flags/mys.png differ
diff --git a/assets/images/flags/nga.png b/assets/images/flags/nga.png
index ebfd82449..26efc073e 100644
Binary files a/assets/images/flags/nga.png and b/assets/images/flags/nga.png differ
diff --git a/assets/images/flags/nld.png b/assets/images/flags/nld.png
index 62dbc2058..220937426 100644
Binary files a/assets/images/flags/nld.png and b/assets/images/flags/nld.png differ
diff --git a/assets/images/flags/nor.png b/assets/images/flags/nor.png
index bd226c0a6..dfb43c5d5 100644
Binary files a/assets/images/flags/nor.png and b/assets/images/flags/nor.png differ
diff --git a/assets/images/flags/nzl.png b/assets/images/flags/nzl.png
index 11c6ade9c..306fdc778 100644
Binary files a/assets/images/flags/nzl.png and b/assets/images/flags/nzl.png differ
diff --git a/assets/images/flags/pak.png b/assets/images/flags/pak.png
index 1462650e4..b8c966ea1 100644
Binary files a/assets/images/flags/pak.png and b/assets/images/flags/pak.png differ
diff --git a/assets/images/flags/phl.png b/assets/images/flags/phl.png
index b453f3933..3c2ce7bf3 100644
Binary files a/assets/images/flags/phl.png and b/assets/images/flags/phl.png differ
diff --git a/assets/images/flags/pol.png b/assets/images/flags/pol.png
index 30d5a9371..1188eccd1 100644
Binary files a/assets/images/flags/pol.png and b/assets/images/flags/pol.png differ
diff --git a/assets/images/flags/prt.png b/assets/images/flags/prt.png
index ff5a25fa9..268676679 100644
Binary files a/assets/images/flags/prt.png and b/assets/images/flags/prt.png differ
diff --git a/assets/images/flags/rou.png b/assets/images/flags/rou.png
index 49b36b438..db1e24ca2 100644
Binary files a/assets/images/flags/rou.png and b/assets/images/flags/rou.png differ
diff --git a/assets/images/flags/rus.png b/assets/images/flags/rus.png
index 2633dcbd0..460c7b813 100644
Binary files a/assets/images/flags/rus.png and b/assets/images/flags/rus.png differ
diff --git a/assets/images/flags/saf.png b/assets/images/flags/saf.png
index 3b9cbded8..9accc6b5f 100644
Binary files a/assets/images/flags/saf.png and b/assets/images/flags/saf.png differ
diff --git a/assets/images/flags/sau.png b/assets/images/flags/sau.png
index 97951983a..255dabedd 100644
Binary files a/assets/images/flags/sau.png and b/assets/images/flags/sau.png differ
diff --git a/assets/images/flags/sgp.png b/assets/images/flags/sgp.png
index 5782ea144..a677561d4 100644
Binary files a/assets/images/flags/sgp.png and b/assets/images/flags/sgp.png differ
diff --git a/assets/images/flags/swe.png b/assets/images/flags/swe.png
index ef73086f6..e5ee36d2f 100644
Binary files a/assets/images/flags/swe.png and b/assets/images/flags/swe.png differ
diff --git a/assets/images/flags/tha.png b/assets/images/flags/tha.png
index 1bdb04d00..a99cd4d48 100644
Binary files a/assets/images/flags/tha.png and b/assets/images/flags/tha.png differ
diff --git a/assets/images/flags/tur.png b/assets/images/flags/tur.png
index 166c6313a..e86b5a85e 100644
Binary files a/assets/images/flags/tur.png and b/assets/images/flags/tur.png differ
diff --git a/assets/images/flags/twn.png b/assets/images/flags/twn.png
index 4af8ba78d..34a2b37db 100644
Binary files a/assets/images/flags/twn.png and b/assets/images/flags/twn.png differ
diff --git a/assets/images/flags/ukr.png b/assets/images/flags/ukr.png
index 61071e338..c4fe57fcc 100644
Binary files a/assets/images/flags/ukr.png and b/assets/images/flags/ukr.png differ
diff --git a/assets/images/flags/usa.png b/assets/images/flags/usa.png
index a8c44ce75..30fc880b7 100644
Binary files a/assets/images/flags/usa.png and b/assets/images/flags/usa.png differ
diff --git a/assets/images/flags/ven.png b/assets/images/flags/ven.png
index fcc25ef2b..c189b0545 100644
Binary files a/assets/images/flags/ven.png and b/assets/images/flags/ven.png differ
diff --git a/assets/images/flags/vnm.png b/assets/images/flags/vnm.png
index 3cbbf878f..d313c9912 100644
Binary files a/assets/images/flags/vnm.png and b/assets/images/flags/vnm.png differ
diff --git a/assets/images/hardware_wallet/ledger_flex.png b/assets/images/hardware_wallet/ledger_flex.png
new file mode 100644
index 000000000..fa39f241f
Binary files /dev/null and b/assets/images/hardware_wallet/ledger_flex.png differ
diff --git a/assets/images/hardware_wallet/ledger_nano_s.png b/assets/images/hardware_wallet/ledger_nano_s.png
new file mode 100644
index 000000000..02777aeb6
Binary files /dev/null and b/assets/images/hardware_wallet/ledger_nano_s.png differ
diff --git a/assets/images/hardware_wallet/ledger_nano_x.png b/assets/images/hardware_wallet/ledger_nano_x.png
new file mode 100644
index 000000000..e9328a5ef
Binary files /dev/null and b/assets/images/hardware_wallet/ledger_nano_x.png differ
diff --git a/assets/images/hardware_wallet/ledger_stax.png b/assets/images/hardware_wallet/ledger_stax.png
new file mode 100644
index 000000000..06c9c848e
Binary files /dev/null and b/assets/images/hardware_wallet/ledger_stax.png differ
diff --git a/assets/images/ledger_nano.png b/assets/images/ledger_nano.png
deleted file mode 100644
index bb61ba175..000000000
Binary files a/assets/images/ledger_nano.png and /dev/null differ
diff --git a/assets/images/letsexchange_icon.svg b/assets/images/letsexchange_icon.svg
new file mode 100644
index 000000000..104b43a6b
--- /dev/null
+++ b/assets/images/letsexchange_icon.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/assets/images/moonpay.png b/assets/images/moonpay.png
index b02af6c00..088c93d59 100644
Binary files a/assets/images/moonpay.png and b/assets/images/moonpay.png differ
diff --git a/assets/images/moonpay_dark.png b/assets/images/moonpay_dark.png
index 872e322e2..21de98eb4 100644
Binary files a/assets/images/moonpay_dark.png and b/assets/images/moonpay_dark.png differ
diff --git a/assets/images/moonpay_light.png b/assets/images/moonpay_light.png
index c76ae6e74..3d3de2e4f 100644
Binary files a/assets/images/moonpay_light.png and b/assets/images/moonpay_light.png differ
diff --git a/assets/images/mweb_logo.png b/assets/images/mweb_logo.png
new file mode 100644
index 000000000..92317203e
Binary files /dev/null and b/assets/images/mweb_logo.png differ
diff --git a/assets/images/nanogpt.png b/assets/images/nanogpt.png
new file mode 100644
index 000000000..958400452
Binary files /dev/null and b/assets/images/nanogpt.png differ
diff --git a/assets/images/stealthex.png b/assets/images/stealthex.png
new file mode 100644
index 000000000..311d47b74
Binary files /dev/null and b/assets/images/stealthex.png differ
diff --git a/assets/images/ton_icon.png b/assets/images/ton_icon.png
new file mode 100644
index 000000000..90f9968cc
Binary files /dev/null and b/assets/images/ton_icon.png differ
diff --git a/assets/images/trocador.png b/assets/images/trocador.png
index 67c9f221c..37e643de4 100644
Binary files a/assets/images/trocador.png and b/assets/images/trocador.png differ
diff --git a/assets/images/wallet_group_bright.png b/assets/images/wallet_group_bright.png
new file mode 100644
index 000000000..263361db6
Binary files /dev/null and b/assets/images/wallet_group_bright.png differ
diff --git a/assets/images/wallet_group_dark.png b/assets/images/wallet_group_dark.png
new file mode 100644
index 000000000..7cd08d2cd
Binary files /dev/null and b/assets/images/wallet_group_dark.png differ
diff --git a/assets/images/wallet_group_light.png b/assets/images/wallet_group_light.png
new file mode 100644
index 000000000..7827971e7
Binary files /dev/null and b/assets/images/wallet_group_light.png differ
diff --git a/assets/node_list.yml b/assets/node_list.yml
index bc7a9dc4a..d04a9a2e8 100644
--- a/assets/node_list.yml
+++ b/assets/node_list.yml
@@ -17,6 +17,3 @@
-
uri: node.community.rino.io:18081
is_default: false
--
- uri: node.moneroworld.com:18089
- is_default: false
diff --git a/assets/solana_node_list.yml b/assets/solana_node_list.yml
index 4a2e12161..e5641d3f8 100644
--- a/assets/solana_node_list.yml
+++ b/assets/solana_node_list.yml
@@ -1,4 +1,10 @@
-
uri: rpc.ankr.com
is_default: true
+ useSSL: true
+-
+ uri: api.mainnet-beta.solana.com:443
+ useSSL: true
+-
+ uri: solana-rpc.publicnode.com:443
useSSL: true
\ No newline at end of file
diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt
index 2a6c07abe..613ea4281 100644
--- a/assets/text/Monerocom_Release_Notes.txt
+++ b/assets/text/Monerocom_Release_Notes.txt
@@ -1,3 +1,3 @@
Monero enhancements
-Synchronization improvements
+Introducing StealthEx and LetxExchange
Bug fixes
\ No newline at end of file
diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt
index d17a22c84..61aafb6e4 100644
--- a/assets/text/Release_Notes.txt
+++ b/assets/text/Release_Notes.txt
@@ -1,5 +1,7 @@
-Monero and Ethereum enhancements
-Synchronization improvements
-Exchange flow enhancements
-Ledger improvements
+Added Litecoin MWEB
+Added wallet groups
+Silent Payment enhancements for speed & reliability
+Monero enhancements
+Introducing StealthEx and LetxExchange
+Additional ERC20 tokens scam detection
Bug fixes
\ No newline at end of file
diff --git a/build-guide-linux.md b/build-guide-linux.md
new file mode 100644
index 000000000..55264fbfa
--- /dev/null
+++ b/build-guide-linux.md
@@ -0,0 +1,176 @@
+# Building CakeWallet for Linux
+
+## Requirements and Setup
+
+The following are the system requirements to build CakeWallet for your Linux device.
+
+```
+Ubuntu >= 16.04
+Flutter 3.10.x
+```
+
+## Building CakeWallet on Linux
+
+These steps will help you configure and execute a build of CakeWallet from its source code.
+
+### 1. Installing Package Dependencies
+
+CakeWallet requires some packages to be installed on your build system. You may easily install them on your build system with the following command:
+
+`$ sudo apt install build-essential cmake pkg-config git curl autoconf libtool`
+
+> [!WARNING]
+>
+> ### Check gcc version
+>
+> It is needed to use gcc 10 or 9 to successfully link dependencies with flutter.\
+> To check what gcc version you are using:
+>
+> ```bash
+> $ gcc --version
+> $ g++ --version
+> ```
+>
+> If you are using gcc version newer than 10, then you need to downgrade to version 10.4.0:
+>
+> ```bash
+> $ sudo apt install gcc-10 g++-10
+> $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
+> $ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
+> ```
+
+> [!NOTE]
+>
+> Alternatively, you can use the [nix-shell](https://nixos.org/) with the `gcc10.nix` file\
+> present on `scripts/linux` like so:
+> ```bash
+> $ nix-shell gcc10.nix
+> ```
+> This will get you in a nix environment with all the required dependencies that you can use to build the software from,\
+> and it works in any linux distro.
+
+### 2. Installing Flutter
+
+Need to install flutter. For this please check section [How to install flutter on Linux](https://docs.flutter.dev/get-started/install/linux).
+
+### 3. Verify Installations
+
+Verify that the Flutter has been correctly installed on your system with the following command:
+
+`$ flutter doctor`
+
+The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding.
+
+```
+Doctor summary (to see all details, run flutter doctor -v):
+[✓] Flutter (Channel stable, 3.10.x, on Linux, locale en_US.UTF-8)
+```
+
+### 4. Acquiring the CakeWallet Source Code
+
+Download CakeWallet source code
+
+`$ git clone https://github.com/cake-tech/cake_wallet.git --branch linux/password-direct-input`
+
+Proceed into the source code before proceeding with the next steps:
+
+`$ cd cake_wallet/scripts/linux/`
+
+To configure some project properties run:
+
+`$ ./cakewallet.sh`
+
+Build the Monero libraries and their dependencies:
+
+`$ ./build_all.sh`
+
+Now the dependencies need to be copied into the CakeWallet project with this command:
+
+`$ ./setup.sh`
+
+It is now time to change back to the base directory of the CakeWallet source code:
+
+`$ cd ../../`
+
+Install Flutter package dependencies with this command:
+
+`$ flutter pub get`
+
+> #### If you will get an error like:
+>
+> ```
+> The plugin `cw_shared_external` requires your app to be migrated to the Android embedding v2. Follow the steps on the migration doc above and re-run
+> this command.
+> ```
+>
+> Then need to config Android project settings. For this open `scripts/android` (`$ cd scripts/android`) directory and run followed commands:
+>
+> ```
+> $ source ./app_env.sh cakewallet
+> $ ./app_config.sh
+> $ cd ../..
+> ```
+>
+> Then re-configure Linux project again. For this open `scripts/linux` (`$cd scripts/linux`) directory and run:
+> `$ ./cakewallet.sh`
+> and back to project root directory:
+> `$ cd ../..`
+> and fetch dependecies 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:
+
+`$ flutter packages pub run tool/generate_new_secrets.dart`
+
+We will generate mobx models for the project.
+
+`$ ./model_generator.sh`
+
+Then we need to generate localization files.
+
+`$ flutter packages pub run tool/generate_localization.dart`
+
+### 5. Build!
+
+`$ flutter build linux --release`
+
+Path to executable file will be:
+
+`build/linux/x64/release/bundle/cake_wallet`
+
+> ### Troubleshooting
+>
+> If you got an error while building the application with `$ flutter build linux --release` command, add `-v` argument to the command (`$ flutter build linux -v --release`) to get details.\
+> If you got in flutter build logs: undefined reference to `hid_free_enumeration`, or another error with undefined reference to `hid_*`, then rebuild monero lib without hidapi lib. Check does exists `libhidapi-dev` in your scope and remove it from your scope for build without it.
+
+# Flatpak
+
+For package the built application into flatpak you need firstly to install `flatpak` and `flatpak-builder`:
+
+`$ sudo apt install flatpak flatpak-builder`
+
+Then need to [add flathub](https://flatpak.org/setup/Ubuntu) (or just `$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`). Then need to install freedesktop runtime and sdk:
+
+`$ flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08`
+
+To build with using of `flatpak-build` directory run next:
+
+`$ flatpak-builder --force-clean flatpak-build com.cakewallet.CakeWallet.yml`
+
+And then export bundle:
+
+`$ flatpak build-export export flatpak-build`
+
+`$ flatpak build-bundle export cake_wallet.flatpak com.cakewallet.CakeWallet`
+
+Result file: `cake_wallet.flatpak` should be generated in the current directory.
+
+For install generated flatpak file use:
+
+`$ flatpak --user install cake_wallet.flatpak`
+
+For run the installed application run:
+
+`$ flatpak run com.cakewallet.CakeWallet`
+
+Copyright (c) 2023 Cake Technologies LLC.
diff --git a/com.cakewallet.CakeWallet.yml b/com.cakewallet.CakeWallet.yml
new file mode 100644
index 000000000..83efa1388
--- /dev/null
+++ b/com.cakewallet.CakeWallet.yml
@@ -0,0 +1,35 @@
+app-id: com.cakewallet.CakeWallet
+runtime: org.freedesktop.Platform
+runtime-version: '22.08'
+sdk: org.freedesktop.Sdk
+command: cake_wallet
+separate-locales: false
+finish-args:
+ - --share=ipc
+ - --socket=fallback-x11
+ - --socket=wayland
+ - --device=dri
+ - --socket=pulseaudio
+ - --share=network
+ - --filesystem=home
+modules:
+ - name: cake_wallet
+ buildsystem: simple
+ only-arches:
+ - x86_64
+ build-commands:
+ - "cp -R bundle /app/cake_wallet"
+ - "chmod +x /app/cake_wallet/cake_wallet"
+ - "mkdir -p /app/bin"
+ - "ln -s /app/cake_wallet/cake_wallet /app/bin/cake_wallet"
+ - "mkdir -p /app/share/icons/hicolor/scalable/apps"
+ - "cp cakewallet_icon_180.png /app/share/icons/hicolor/scalable/apps/com.cakewallet.CakeWallet.png"
+ - "mkdir -p /app/share/applications"
+ - "cp com.cakewallet.CakeWallet.desktop /app/share/applications"
+ sources:
+ - type: dir
+ path: build/linux/x64/release
+ - type: file
+ path: assets/images/cakewallet_icon_180.png
+ - type: file
+ path: linux/com.cakewallet.CakeWallet.desktop
diff --git a/configure_cake_wallet.sh b/configure_cake_wallet.sh
index 0539221a3..90ce1c446 100755
--- a/configure_cake_wallet.sh
+++ b/configure_cake_wallet.sh
@@ -3,12 +3,13 @@
IOS="ios"
ANDROID="android"
MACOS="macos"
+LINUX="linux"
-PLATFORMS=($IOS $ANDROID $MACOS)
+PLATFORMS=($IOS $ANDROID $MACOS $LINUX)
PLATFORM=$1
if ! [[ " ${PLATFORMS[*]} " =~ " ${PLATFORM} " ]]; then
- echo "specify platform: ./configure_cake_wallet.sh ios|android|macos"
+ echo "specify platform: ./configure_cake_wallet.sh ios|android|macos|linux"
exit 1
fi
@@ -27,9 +28,14 @@ if [ "$PLATFORM" == "$ANDROID" ]; then
cd scripts/android
fi
+if [ "$PLATFORM" == "$LINUX" ]; then
+ echo "Configuring for linux"
+ cd scripts/linux
+fi
+
source ./app_env.sh cakewallet
./app_config.sh
cd ../.. && flutter pub get
-#flutter packages pub run tool/generate_localization.dart
+flutter packages pub run tool/generate_localization.dart
./model_generator.sh
-#cd macos && pod install
\ No newline at end of file
+#cd macos && pod install
diff --git a/cw_bitcoin/lib/address_to_output_script.dart b/cw_bitcoin/lib/address_to_output_script.dart
deleted file mode 100644
index 892f7a0d6..000000000
--- a/cw_bitcoin/lib/address_to_output_script.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-import 'dart:typed_data';
-import 'package:bitcoin_base/bitcoin_base.dart' as bitcoin;
-
-List addressToOutputScript(String address, bitcoin.BasedUtxoNetwork network) {
- try {
- if (network == bitcoin.BitcoinCashNetwork.mainnet) {
- return bitcoin.BitcoinCashAddress(address).baseAddress.toScriptPubKey().toBytes();
- }
- return bitcoin.addressToOutputScript(address: address, network: network);
- } catch (err) {
- print(err);
- return Uint8List(0);
- }
-}
diff --git a/cw_bitcoin/lib/bitcoin_address_record.dart b/cw_bitcoin/lib/bitcoin_address_record.dart
index bf36e6fb9..7e4b5f58f 100644
--- a/cw_bitcoin/lib/bitcoin_address_record.dart
+++ b/cw_bitcoin/lib/bitcoin_address_record.dart
@@ -1,7 +1,6 @@
import 'dart:convert';
import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:cw_bitcoin/script_hash.dart' as sh;
abstract class BaseBitcoinAddressRecord {
BaseBitcoinAddressRecord(
@@ -65,8 +64,8 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
required super.type,
String? scriptHash,
required super.network,
- }) : scriptHash =
- scriptHash ?? (network != null ? sh.scriptHash(address, network: network) : null);
+ }) : scriptHash = scriptHash ??
+ (network != null ? BitcoinAddressUtils.scriptHash(address, network: network) : null);
factory BitcoinAddressRecord.fromJSON(String jsonSource, {BasedUtxoNetwork? network}) {
final decoded = json.decode(jsonSource) as Map;
@@ -92,7 +91,7 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
String getScriptHash(BasedUtxoNetwork network) {
if (scriptHash != null) return scriptHash!;
- scriptHash = sh.scriptHash(address, network: network);
+ scriptHash = BitcoinAddressUtils.scriptHash(address, network: network);
return scriptHash!;
}
diff --git a/cw_bitcoin/lib/bitcoin_hardware_wallet_service.dart b/cw_bitcoin/lib/bitcoin_hardware_wallet_service.dart
index 345d645d1..a02c51c69 100644
--- a/cw_bitcoin/lib/bitcoin_hardware_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_hardware_wallet_service.dart
@@ -1,33 +1,35 @@
import 'dart:async';
import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart';
+import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_bitcoin/utils.dart';
import 'package:cw_core/hardware/hardware_account_data.dart';
import 'package:ledger_bitcoin/ledger_bitcoin.dart';
-import 'package:ledger_flutter/ledger_flutter.dart';
+import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
class BitcoinHardwareWalletService {
- BitcoinHardwareWalletService(this.ledger, this.device);
+ BitcoinHardwareWalletService(this.ledgerConnection);
- final Ledger ledger;
- final LedgerDevice device;
+ final LedgerConnection ledgerConnection;
- Future> getAvailableAccounts({int index = 0, int limit = 5}) async {
- final bitcoinLedgerApp = BitcoinLedgerApp(ledger);
+ Future> getAvailableAccounts(
+ {int index = 0, int limit = 5}) async {
+ final bitcoinLedgerApp = BitcoinLedgerApp(ledgerConnection);
- final masterFp = await bitcoinLedgerApp.getMasterFingerprint(device);
- print(masterFp);
+ final masterFp = await bitcoinLedgerApp.getMasterFingerprint();
final accounts = [];
final indexRange = List.generate(limit, (i) => i + index);
for (final i in indexRange) {
final derivationPath = "m/84'/0'/$i'";
- final xpub = await bitcoinLedgerApp.getXPubKey(device, derivationPath: derivationPath);
- HDWallet hd = HDWallet.fromBase58(xpub).derive(0);
+ final xpub =
+ await bitcoinLedgerApp.getXPubKey(derivationPath: derivationPath);
+ Bip32Slip10Secp256k1 hd =
+ Bip32Slip10Secp256k1.fromExtendedKey(xpub).childKey(Bip32KeyIndex(0));
- final address = generateP2WPKHAddress(hd: hd, index: 0, network: BitcoinNetwork.mainnet);
+ final address = generateP2WPKHAddress(
+ hd: hd, index: 0, network: BitcoinNetwork.mainnet);
accounts.add(HardwareAccountData(
address: address,
diff --git a/cw_bitcoin/lib/bitcoin_mnemonic.dart b/cw_bitcoin/lib/bitcoin_mnemonic.dart
index 905aece28..21ff3891e 100644
--- a/cw_bitcoin/lib/bitcoin_mnemonic.dart
+++ b/cw_bitcoin/lib/bitcoin_mnemonic.dart
@@ -1,12 +1,14 @@
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
+
import 'package:crypto/crypto.dart';
import 'package:cryptography/cryptography.dart' as cryptography;
import 'package:cw_core/sec_random_native.dart';
import 'package:cw_core/utils/text_normalizer.dart';
const segwit = '100';
+const mweb = 'eb';
final wordlist = englishWordlist;
double logBase(num x, num base) => log(x) / log(base);
@@ -59,11 +61,7 @@ void maskBytes(Uint8List bytes, int bits) {
}
}
-String bufferToBin(Uint8List data) {
- final q1 = data.map((e) => e.toRadixString(2).padLeft(8, '0'));
- final q2 = q1.join('');
- return q2;
-}
+String bufferToBin(Uint8List data) => data.map((e) => e.toRadixString(2).padLeft(8, '0')).join('');
String encode(Uint8List data) {
final dataBitLen = data.length * 8;
@@ -112,22 +110,23 @@ Future checkIfMnemonicIsElectrum2(String mnemonic) async {
Future getMnemonicHash(String mnemonic) async {
final hmacSha512 = Hmac(sha512, utf8.encode('Seed version'));
final digest = hmacSha512.convert(utf8.encode(normalizeText(mnemonic)));
- final hx = digest.toString();
- return hx;
+ return digest.toString();
}
-Future mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) async {
+Future mnemonicToSeedBytes(String mnemonic,
+ {String prefix = segwit, String passphrase = ''}) async {
final pbkdf2 =
cryptography.Pbkdf2(macAlgorithm: cryptography.Hmac.sha512(), iterations: 2048, bits: 512);
final text = normalizeText(mnemonic);
- // pbkdf2.deriveKey(secretKey: secretKey, nonce: nonce)
+ final passphraseBytes = utf8.encode(normalizeText(passphrase));
final key = await pbkdf2.deriveKey(
- secretKey: cryptography.SecretKey(text.codeUnits), nonce: 'electrum'.codeUnits);
+ secretKey: cryptography.SecretKey(text.codeUnits),
+ nonce: [...'electrum'.codeUnits, ...passphraseBytes]);
final bytes = await key.extractBytes();
return Uint8List.fromList(bytes);
}
-bool matchesAnyPrefix(String mnemonic) => prefixMatches(mnemonic, [segwit]).any((el) => el);
+bool matchesAnyPrefix(String mnemonic) => prefixMatches(mnemonic, [segwit, mweb]).any((el) => el);
bool validateMnemonic(String mnemonic, {String prefix = segwit}) {
try {
diff --git a/cw_bitcoin_cash/lib/src/mnemonic.dart b/cw_bitcoin/lib/bitcoin_mnemonics_bip39.dart
similarity index 59%
rename from cw_bitcoin_cash/lib/src/mnemonic.dart
rename to cw_bitcoin/lib/bitcoin_mnemonics_bip39.dart
index b1f1ee984..ff02e875c 100644
--- a/cw_bitcoin_cash/lib/src/mnemonic.dart
+++ b/cw_bitcoin/lib/bitcoin_mnemonics_bip39.dart
@@ -2,10 +2,11 @@ import 'dart:typed_data';
import 'package:bip39/bip39.dart' as bip39;
-class Mnemonic {
+class MnemonicBip39 {
/// Generate bip39 mnemonic
static String generate({int strength = 128}) => bip39.generateMnemonic(strength: strength);
/// Create root seed from mnemonic
- static Uint8List toSeed(String mnemonic) => bip39.mnemonicToSeed(mnemonic);
+ static Uint8List toSeed(String mnemonic, {String? passphrase}) =>
+ bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
}
diff --git a/cw_bitcoin/lib/bitcoin_receive_page_option.dart b/cw_bitcoin/lib/bitcoin_receive_page_option.dart
index aa3d4a4cd..07083e111 100644
--- a/cw_bitcoin/lib/bitcoin_receive_page_option.dart
+++ b/cw_bitcoin/lib/bitcoin_receive_page_option.dart
@@ -7,6 +7,7 @@ class BitcoinReceivePageOption implements ReceivePageOption {
static const p2tr = BitcoinReceivePageOption._('Taproot (P2TR)');
static const p2wsh = BitcoinReceivePageOption._('Segwit (P2WSH)');
static const p2pkh = BitcoinReceivePageOption._('Legacy (P2PKH)');
+ static const mweb = BitcoinReceivePageOption._('MWEB');
static const silent_payments = BitcoinReceivePageOption._('Silent Payments');
@@ -27,6 +28,11 @@ class BitcoinReceivePageOption implements ReceivePageOption {
BitcoinReceivePageOption.p2pkh
];
+ static const allLitecoin = [
+ BitcoinReceivePageOption.p2wpkh,
+ BitcoinReceivePageOption.mweb,
+ ];
+
BitcoinAddressType toType() {
switch (this) {
case BitcoinReceivePageOption.p2tr:
@@ -39,6 +45,8 @@ class BitcoinReceivePageOption implements ReceivePageOption {
return P2shAddressType.p2wpkhInP2sh;
case BitcoinReceivePageOption.silent_payments:
return SilentPaymentsAddresType.p2sp;
+ case BitcoinReceivePageOption.mweb:
+ return SegwitAddresType.mweb;
case BitcoinReceivePageOption.p2wpkh:
default:
return SegwitAddresType.p2wpkh;
@@ -51,6 +59,8 @@ class BitcoinReceivePageOption implements ReceivePageOption {
return BitcoinReceivePageOption.p2tr;
case SegwitAddresType.p2wsh:
return BitcoinReceivePageOption.p2wsh;
+ case SegwitAddresType.mweb:
+ return BitcoinReceivePageOption.mweb;
case P2pkhAddressType.p2pkh:
return BitcoinReceivePageOption.p2pkh;
case P2shAddressType.p2wpkhInP2sh:
diff --git a/cw_bitcoin/lib/bitcoin_transaction_credentials.dart b/cw_bitcoin/lib/bitcoin_transaction_credentials.dart
index bda7c39ae..01e905fb0 100644
--- a/cw_bitcoin/lib/bitcoin_transaction_credentials.dart
+++ b/cw_bitcoin/lib/bitcoin_transaction_credentials.dart
@@ -1,11 +1,13 @@
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_core/output_info.dart';
+import 'package:cw_core/unspent_coin_type.dart';
class BitcoinTransactionCredentials {
BitcoinTransactionCredentials(this.outputs,
- {required this.priority, this.feeRate});
+ {required this.priority, this.feeRate, this.coinTypeToSpendFrom = UnspentCoinType.any});
final List outputs;
final BitcoinTransactionPriority? priority;
final int? feeRate;
+ final UnspentCoinType coinTypeToSpendFrom;
}
diff --git a/cw_bitcoin/lib/bitcoin_transaction_priority.dart b/cw_bitcoin/lib/bitcoin_transaction_priority.dart
index 7c4dcfd5f..d1f45a545 100644
--- a/cw_bitcoin/lib/bitcoin_transaction_priority.dart
+++ b/cw_bitcoin/lib/bitcoin_transaction_priority.dart
@@ -87,7 +87,7 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
}
@override
- String get units => 'Latoshi';
+ String get units => 'Litoshi';
@override
String toString() {
diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index d061480ed..908897845 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -2,23 +2,24 @@ import 'dart:convert';
import 'package:bip39/bip39.dart' as bip39;
import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
-import 'package:convert/convert.dart';
+import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
+import 'package:cw_bitcoin/psbt_transaction_builder.dart';
+import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_bitcoin/electrum_derivations.dart';
import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
-import 'package:cw_bitcoin/psbt_transaction_builder.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:ledger_bitcoin/ledger_bitcoin.dart';
-import 'package:ledger_flutter/ledger_flutter.dart';
+import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
import 'package:mobx/mobx.dart';
part 'bitcoin_wallet.g.dart';
@@ -30,6 +31,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required String password,
required WalletInfo walletInfo,
required Box unspentCoinsInfo,
+ required EncryptionFileUtils encryptionFileUtils,
Uint8List? seedBytes,
String? mnemonic,
String? xpub,
@@ -50,16 +52,18 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
password: password,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo,
- networkType: networkParam == null
- ? bitcoin.bitcoin
+ network: networkParam == null
+ ? BitcoinNetwork.mainnet
: networkParam == BitcoinNetwork.mainnet
- ? bitcoin.bitcoin
- : bitcoin.testnet,
+ ? BitcoinNetwork.mainnet
+ : BitcoinNetwork.testnet,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: seedBytes,
- currency:
- networkParam == BitcoinNetwork.testnet ? CryptoCurrency.tbtc : CryptoCurrency.btc,
+ encryptionFileUtils: encryptionFileUtils,
+ currency: networkParam == BitcoinNetwork.testnet
+ ? CryptoCurrency.tbtc
+ : CryptoCurrency.btc,
alwaysScan: alwaysScan,
) {
// in a standard BIP44 wallet, mainHd derivation path = m/84'/0'/0'/0 (account 0, index unspecified here)
@@ -75,14 +79,16 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialSilentAddresses: initialSilentAddresses,
initialSilentAddressIndex: initialSilentAddressIndex,
mainHd: hd,
- sideHd: accountHD.derive(1),
+ sideHd: accountHD.childKey(Bip32KeyIndex(1)),
network: networkParam ?? network,
masterHd:
- seedBytes != null ? bitcoin.HDWallet.fromSeed(seedBytes, network: networkType) : null,
+ seedBytes != null ? Bip32Slip10Secp256k1.fromSeed(seedBytes) : null,
+ isHardwareWallet: walletInfo.isHardwareWallet,
);
autorun((_) {
- this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress;
+ this.walletAddresses.isEnabledAutoGenerateSubaddress =
+ this.isEnabledAutoGenerateSubaddress;
});
}
@@ -91,6 +97,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required String password,
required WalletInfo walletInfo,
required Box unspentCoinsInfo,
+ required EncryptionFileUtils encryptionFileUtils,
String? passphrase,
String? addressPageType,
BasedUtxoNetwork? network,
@@ -112,7 +119,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
break;
case DerivationType.electrum:
default:
- seedBytes = await mnemonicToSeedBytes(mnemonic);
+ seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
break;
}
return BitcoinWallet(
@@ -125,6 +132,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialSilentAddresses: initialSilentAddresses,
initialSilentAddressIndex: initialSilentAddressIndex,
initialBalance: initialBalance,
+ encryptionFileUtils: encryptionFileUtils,
seedBytes: seedBytes,
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex,
@@ -138,68 +146,102 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required WalletInfo walletInfo,
required Box unspentCoinsInfo,
required String password,
+ required EncryptionFileUtils encryptionFileUtils,
required bool alwaysScan,
}) async {
final network = walletInfo.network != null
? BasedUtxoNetwork.fromName(walletInfo.network!)
: BitcoinNetwork.mainnet;
- final snp = await ElectrumWalletSnapshot.load(name, walletInfo.type, password, network);
- walletInfo.derivationInfo ??= DerivationInfo(
- derivationType: snp.derivationType ?? DerivationType.electrum,
- derivationPath: snp.derivationPath,
- );
+ final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
+
+ ElectrumWalletSnapshot? snp = null;
+
+ try {
+ snp = await ElectrumWalletSnapshot.load(
+ encryptionFileUtils,
+ name,
+ walletInfo.type,
+ password,
+ network,
+ );
+ } catch (e) {
+ if (!hasKeysFile) rethrow;
+ }
+
+ final WalletKeysData keysData;
+ // Migrate wallet from the old scheme to then new .keys file scheme
+ if (!hasKeysFile) {
+ keysData = WalletKeysData(
+ mnemonic: snp!.mnemonic,
+ xPub: snp.xpub,
+ passphrase: snp.passphrase,
+ );
+ } else {
+ keysData = await WalletKeysFile.readKeysFile(
+ name,
+ walletInfo.type,
+ password,
+ encryptionFileUtils,
+ );
+ }
+
+ walletInfo.derivationInfo ??= DerivationInfo();
// set the default if not present:
- walletInfo.derivationInfo!.derivationPath = snp.derivationPath ?? electrum_path;
- walletInfo.derivationInfo!.derivationType = snp.derivationType ?? DerivationType.electrum;
+ walletInfo.derivationInfo!.derivationPath ??=
+ snp?.derivationPath ?? electrum_path;
+ walletInfo.derivationInfo!.derivationType ??=
+ snp?.derivationType ?? DerivationType.electrum;
Uint8List? seedBytes = null;
+ final mnemonic = keysData.mnemonic;
+ final passphrase = keysData.passphrase;
- if (snp.mnemonic != null) {
+ if (mnemonic != null) {
switch (walletInfo.derivationInfo!.derivationType) {
case DerivationType.electrum:
- seedBytes = await mnemonicToSeedBytes(snp.mnemonic!);
+ seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
break;
case DerivationType.bip39:
default:
seedBytes = await bip39.mnemonicToSeed(
- snp.mnemonic!,
- passphrase: snp.passphrase ?? '',
+ mnemonic,
+ passphrase: passphrase ?? '',
);
break;
}
}
return BitcoinWallet(
- mnemonic: snp.mnemonic,
- xpub: snp.xpub,
+ mnemonic: mnemonic,
+ xpub: keysData.xPub,
password: password,
- passphrase: snp.passphrase,
+ passphrase: passphrase,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo,
- initialAddresses: snp.addresses,
- initialSilentAddresses: snp.silentAddresses,
- initialSilentAddressIndex: snp.silentAddressIndex,
- initialBalance: snp.balance,
+ initialAddresses: snp?.addresses,
+ initialSilentAddresses: snp?.silentAddresses,
+ initialSilentAddressIndex: snp?.silentAddressIndex ?? 0,
+ initialBalance: snp?.balance,
+ encryptionFileUtils: encryptionFileUtils,
seedBytes: seedBytes,
- initialRegularAddressIndex: snp.regularAddressIndex,
- initialChangeAddressIndex: snp.changeAddressIndex,
- addressPageType: snp.addressPageType,
+ initialRegularAddressIndex: snp?.regularAddressIndex,
+ initialChangeAddressIndex: snp?.changeAddressIndex,
+ addressPageType: snp?.addressPageType,
networkParam: network,
alwaysScan: alwaysScan,
);
}
- Ledger? _ledger;
- LedgerDevice? _ledgerDevice;
+ LedgerConnection? _ledgerConnection;
BitcoinLedgerApp? _bitcoinLedgerApp;
- void setLedger(Ledger setLedger, LedgerDevice setLedgerDevice) {
- _ledger = setLedger;
- _ledgerDevice = setLedgerDevice;
- _bitcoinLedgerApp =
- BitcoinLedgerApp(_ledger!, derivationPath: walletInfo.derivationInfo!.derivationPath!);
+ @override
+ void setLedgerConnection(LedgerConnection connection) {
+ _ledgerConnection = connection;
+ _bitcoinLedgerApp = BitcoinLedgerApp(_ledgerConnection!,
+ derivationPath: walletInfo.derivationInfo!.derivationPath!);
}
@override
@@ -214,12 +256,14 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
BitcoinOrdering inputOrdering = BitcoinOrdering.bip69,
BitcoinOrdering outputOrdering = BitcoinOrdering.bip69,
}) async {
- final masterFingerprint = await _bitcoinLedgerApp!.getMasterFingerprint(_ledgerDevice!);
+ final masterFingerprint = await _bitcoinLedgerApp!.getMasterFingerprint();
final psbtReadyInputs = [];
for (final utxo in utxos) {
- final rawTx = await electrumClient.getTransactionHex(hash: utxo.utxo.txHash);
- final publicKeyAndDerivationPath = publicKeys[utxo.ownerDetails.address.pubKeyHash()]!;
+ final rawTx =
+ await electrumClient.getTransactionHex(hash: utxo.utxo.txHash);
+ final publicKeyAndDerivationPath =
+ publicKeys[utxo.ownerDetails.address.pubKeyHash()]!;
psbtReadyInputs.add(PSBTReadyUtxoWithAddress(
utxo: utxo.utxo,
@@ -231,26 +275,28 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
));
}
- final psbt =
- PSBTTransactionBuild(inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF);
+ final psbt = PSBTTransactionBuild(
+ inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF);
- final rawHex = await _bitcoinLedgerApp!.signPsbt(_ledgerDevice!, psbt: psbt.psbt);
- return BtcTransaction.fromRaw(hex.encode(rawHex));
+ final rawHex = await _bitcoinLedgerApp!.signPsbt(psbt: psbt.psbt);
+ return BtcTransaction.fromRaw(BytesUtils.toHexString(rawHex));
}
@override
Future signMessage(String message, {String? address = null}) async {
if (walletInfo.isHardwareWallet) {
final addressEntry = address != null
- ? walletAddresses.allAddresses.firstWhere((element) => element.address == address)
+ ? walletAddresses.allAddresses
+ .firstWhere((element) => element.address == address)
: null;
final index = addressEntry?.index ?? 0;
final isChange = addressEntry?.isHidden == true ? 1 : 0;
final accountPath = walletInfo.derivationInfo?.derivationPath;
- final derivationPath = accountPath != null ? "$accountPath/$isChange/$index" : null;
+ final derivationPath =
+ accountPath != null ? "$accountPath/$isChange/$index" : null;
- final signature = await _bitcoinLedgerApp!
- .signMessage(_ledgerDevice!, message: ascii.encode(message), signDerivationPath: derivationPath);
+ final signature = await _bitcoinLedgerApp!.signMessage(
+ message: ascii.encode(message), signDerivationPath: derivationPath);
return base64Encode(signature);
}
diff --git a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
index 486e69b11..04a3cae36 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
@@ -1,5 +1,5 @@
import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart';
+import 'package:blockchain_utils/bip/bip/bip32/bip32.dart';
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
import 'package:cw_bitcoin/utils.dart';
import 'package:cw_core/wallet_info.dart';
@@ -15,6 +15,7 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
required super.mainHd,
required super.sideHd,
required super.network,
+ required super.isHardwareWallet,
super.initialAddresses,
super.initialRegularAddressIndex,
super.initialChangeAddressIndex,
@@ -24,7 +25,8 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
}) : super(walletInfo);
@override
- String getAddress({required int index, required HDWallet hd, BitcoinAddressType? addressType}) {
+ String getAddress(
+ {required int index, required Bip32Slip10Secp256k1 hd, BitcoinAddressType? addressType}) {
if (addressType == P2pkhAddressType.p2pkh)
return generateP2PKHAddress(hd: hd, index: index, network: network);
diff --git a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
index 915d7cc10..a1b1418b8 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
@@ -3,15 +3,24 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
class BitcoinNewWalletCredentials extends WalletCredentials {
- BitcoinNewWalletCredentials(
- {required String name,
- WalletInfo? walletInfo,
- DerivationType? derivationType,
- String? derivationPath})
- : super(
+ BitcoinNewWalletCredentials({
+ required String name,
+ WalletInfo? walletInfo,
+ String? password,
+ DerivationType? derivationType,
+ String? derivationPath,
+ String? passphrase,
+ this.mnemonic,
+ String? parentAddress,
+ }) : super(
name: name,
walletInfo: walletInfo,
+ password: password,
+ passphrase: passphrase,
+ parentAddress: parentAddress,
);
+
+ final String? mnemonic;
}
class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart
index a9a6d96db..06f2082e4 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart
@@ -1,8 +1,10 @@
import 'dart:io';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
+import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart';
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
+import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_service.dart';
@@ -19,11 +21,12 @@ class BitcoinWalletService extends WalletService<
BitcoinRestoreWalletFromSeedCredentials,
BitcoinRestoreWalletFromWIFCredentials,
BitcoinRestoreWalletFromHardware> {
- BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan);
+ BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan, this.isDirect);
final Box walletInfoSource;
final Box unspentCoinsInfoSource;
final bool alwaysScan;
+ final bool isDirect;
@override
WalletType getType() => WalletType.bitcoin;
@@ -33,16 +36,32 @@ class BitcoinWalletService extends WalletService<
final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet;
credentials.walletInfo?.network = network.value;
+ final String mnemonic;
+ switch ( credentials.walletInfo?.derivationInfo?.derivationType) {
+ case DerivationType.bip39:
+ final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
+
+ mnemonic = credentials.mnemonic ?? await MnemonicBip39.generate(strength: strength);
+ break;
+ case DerivationType.electrum:
+ default:
+ mnemonic = await generateElectrumMnemonic();
+ break;
+ }
+
final wallet = await BitcoinWalletBase.create(
- mnemonic: await generateElectrumMnemonic(),
+ mnemonic: mnemonic,
password: credentials.password!,
passphrase: credentials.passphrase,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
network: network,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
+
await wallet.save();
await wallet.init();
+
return wallet;
}
@@ -61,6 +80,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
alwaysScan: alwaysScan,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.init();
saveBackup(name);
@@ -73,6 +93,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
alwaysScan: alwaysScan,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.init();
return wallet;
@@ -97,6 +118,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: currentWalletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
alwaysScan: alwaysScan,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await currentWallet.renameWalletFiles(newName);
@@ -123,6 +145,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
networkParam: network,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.save();
await wallet.init();
@@ -151,6 +174,7 @@ class BitcoinWalletService extends WalletService<
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
network: network,
+ encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.save();
await wallet.init();
diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index b52015794..a18c038fa 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -4,10 +4,11 @@ import 'dart:io';
import 'dart:typed_data';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
-import 'package:cw_bitcoin/script_hash.dart';
import 'package:flutter/foundation.dart';
import 'package:rxdart/rxdart.dart';
+enum ConnectionStatus { connected, disconnected, connecting, failed }
+
String jsonrpcparams(List