Merge branch 'main' of https://github.com/cake-tech/cake_wallet into fix-p2sh

# Conflicts:
#	cw_bitcoin/lib/electrum_wallet_addresses.dart
This commit is contained in:
OmarHatem 2024-10-29 02:38:58 +03:00
commit ce88b5efab
481 changed files with 18656 additions and 3871 deletions

View file

@ -23,9 +23,10 @@ jobs:
docker-images: true docker-images: true
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-java@v1 - uses: actions/setup-java@v2
with: with:
java-version: "17.x" distribution: "temurin"
java-version: "17"
- name: Configure placeholder git details - name: Configure placeholder git details
run: | run: |
git config --global user.email "CI@cakewallet.com" git config --global user.email "CI@cakewallet.com"

View file

@ -13,6 +13,9 @@ on:
jobs: jobs:
PR_test_build: PR_test_build:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
strategy:
matrix:
api-level: [29]
env: env:
STORE_PASS: test@cake_wallet STORE_PASS: test@cake_wallet
KEY_PASS: test@cake_wallet KEY_PASS: test@cake_wallet
@ -39,9 +42,10 @@ jobs:
docker-images: true docker-images: true
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-java@v1 - uses: actions/setup-java@v2
with: with:
java-version: "17.x" distribution: "temurin"
java-version: "17"
- name: Configure placeholder git details - name: Configure placeholder git details
run: | run: |
git config --global user.email "CI@cakewallet.com" git config --global user.email "CI@cakewallet.com"
@ -92,6 +96,25 @@ jobs:
cd /opt/android/cake_wallet cd /opt/android/cake_wallet
flutter pub get 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 - name: Generate KeyStore
run: | run: |
cd /opt/android/cake_wallet/android/app cd /opt/android/cake_wallet/android/app
@ -148,6 +171,8 @@ jobs:
echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> 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 payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
echo "const ankrApiKey = '${{ secrets.ANKR_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 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 moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
@ -167,6 +192,10 @@ jobs:
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_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 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 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 - name: Rename app
run: | run: |
@ -195,6 +224,7 @@ jobs:
cd /opt/android/cake_wallet/build/app/outputs/flutter-apk cd /opt/android/cake_wallet/build/app/outputs/flutter-apk
mkdir test-apk mkdir test-apk
cp app-arm64-v8a-release.apk test-apk/${{env.BRANCH_NAME}}.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 - name: Upload Artifact
uses: kittaakos/upload-artifact-as-is@v0 uses: kittaakos/upload-artifact-as-is@v0

View file

@ -89,6 +89,25 @@ jobs:
cd /opt/android/cake_wallet cd /opt/android/cake_wallet
flutter pub get flutter pub get
- name: Install go and gomobile
run: |
# install go > 1.23:
wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
export PATH=$PATH:~/go/bin
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
- name: Build mwebd
run: |
# paths are reset after each step, so we need to set them again:
export PATH=$PATH:/usr/local/go/bin
export PATH=$PATH:~/go/bin
# build mwebd:
cd /opt/android/cake_wallet/scripts/android/
./build_mwebd.sh --dont-install
- name: Generate localization - name: Generate localization
run: | run: |
cd /opt/android/cake_wallet cd /opt/android/cake_wallet
@ -125,6 +144,8 @@ jobs:
echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> 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 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 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 onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> 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 ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
@ -154,6 +175,10 @@ jobs:
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_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 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 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 - name: Rename app
run: | run: |

3
.gitignore vendored
View file

@ -171,6 +171,9 @@ macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
macos/Runner/Configs/AppInfo.xcconfig macos/Runner/Configs/AppInfo.xcconfig
integration_test/playground.dart
# Monero.dart (Monero_C) # Monero.dart (Monero_C)
scripts/monero_c scripts/monero_c
# iOS generated framework bin # iOS generated framework bin

View file

@ -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. 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 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.
6. Add the new language code to `tool/utils/translation/translation_constants.dart`
## Add a new fiat currency ## Add a new fiat currency

View file

@ -1,5 +1,6 @@
include: package:lints/recommended.yaml include: package:lints/recommended.yaml
analyzer: analyzer:
exclude: [ exclude: [
build/**, build/**,
@ -10,7 +11,18 @@ analyzer:
lib/generated/*.dart, lib/generated/*.dart,
cw_monero/ios/External/**, cw_monero/ios/External/**,
cw_shared_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: language:
strict-casts: true strict-casts: true
strict-raw-types: true strict-raw-types: true

View file

@ -1,35 +1,30 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="__APP_PACKAGE__"> package="__APP_PACKAGE__">
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_FINGERPRINT"/> <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--bibo01 : hardware option--> <!-- bibo01 : hardware option-->
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/> <uses-feature android:name="android.hardware.bluetooth" android:required="false" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/> <uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
<!-- required for API 18 - 30 --> <!-- required for API 18 - 30 -->
<uses-permission <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
android:name="android.permission.BLUETOOTH" <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- API 31+ --> <!-- required for API <= 29 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<!-- API 31+ -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<application <application
android:name=".Application" android:name=".Application"
android:label="${APP_NAME}" android:label="${APP_NAME}"

View file

@ -1,3 +1,10 @@
- -
uri: bitcoincash.stackwallet.com:50002 uri: bitcoincash.stackwallet.com:50002
is_default: true is_default: true
useSSL: true
-
uri: bch.aftrek.org:50002
useSSL: true
-
uri: node.minisatoshi.cash:50002
useSSL: true

View file

@ -3,6 +3,10 @@
useSSL: true useSSL: true
- -
uri: btc-electrum.cakewallet.com:50002 uri: btc-electrum.cakewallet.com:50002
useSSL: true
isDefault: true isDefault: true
- -
uri: electrs.cakewallet.com:50001 uri: electrs.cakewallet.com:50001
-
uri: fulcrum.sethforprivacy.com:50002
useSSL: true

BIN
assets/images/cards.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 376 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

BIN
assets/images/flags/arm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 913 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 372 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,005 B

After

Width:  |  Height:  |  Size: 788 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

After

Width:  |  Height:  |  Size: 371 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 B

After

Width:  |  Height:  |  Size: 753 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 B

After

Width:  |  Height:  |  Size: 840 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

After

Width:  |  Height:  |  Size: 381 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 B

After

Width:  |  Height:  |  Size: 830 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 B

After

Width:  |  Height:  |  Size: 370 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 801 B

After

Width:  |  Height:  |  Size: 387 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

After

Width:  |  Height:  |  Size: 553 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,005 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

After

Width:  |  Height:  |  Size: 351 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

After

Width:  |  Height:  |  Size: 762 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,023 B

After

Width:  |  Height:  |  Size: 2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 B

After

Width:  |  Height:  |  Size: 373 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 684 B

After

Width:  |  Height:  |  Size: 360 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 845 B

After

Width:  |  Height:  |  Size: 975 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 615 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 867 B

After

Width:  |  Height:  |  Size: 424 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 937 B

After

Width:  |  Height:  |  Size: 994 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 705 B

After

Width:  |  Height:  |  Size: 351 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 896 B

After

Width:  |  Height:  |  Size: 851 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 849 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,013 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 902 B

After

Width:  |  Height:  |  Size: 1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 351 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 372 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 898 B

After

Width:  |  Height:  |  Size: 424 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

After

Width:  |  Height:  |  Size: 366 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 705 B

After

Width:  |  Height:  |  Size: 351 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 B

After

Width:  |  Height:  |  Size: 371 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 750 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 476 B

After

Width:  |  Height:  |  Size: 2.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 902 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 752 B

After

Width:  |  Height:  |  Size: 390 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

After

Width:  |  Height:  |  Size: 384 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 B

After

Width:  |  Height:  |  Size: 1,005 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 695 B

After

Width:  |  Height:  |  Size: 366 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 597 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,009 B

After

Width:  |  Height:  |  Size: 887 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 882 B

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M16 1.37854C16 0.764286 16.6636 0.379192 17.1969 0.68395L23 4L29.4961 7.71208C29.8077 7.89012 30 8.22147 30 8.58032V16L23.9923 12.567C23.3774 12.2157 22.6226 12.2157 22.0077 12.567L16 16V8V1.37854ZM2 16V8.58032C2 8.22147 2.19229 7.89012 2.50386 7.71208L8.00772 4.56702C8.62259 4.21566 9.37741 4.21566 9.99228 4.56702L16 8L2 16ZM16 30.6215C16 31.2357 15.3364 31.6208 14.8031 31.3161L9 28L2.50386 24.2879C2.19229 24.1099 2 23.7785 2 23.4197V16L8.00772 19.433C8.62259 19.7843 9.37741 19.7843 9.99228 19.433L16 16V24V30.6215ZM22.0077 27.433C22.6226 27.7843 23.3774 27.7843 23.9923 27.433L29.4961 24.2879C29.8077 24.1099 30 23.7785 30 23.4197V16L16 24L22.0077 27.433Z"
fill="#159DFF"></path>
</svg>

After

Width:  |  Height:  |  Size: 846 B

BIN
assets/images/mweb_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
assets/images/nanogpt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

BIN
assets/images/stealthex.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
assets/images/ton_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

View file

@ -17,6 +17,3 @@
- -
uri: node.community.rino.io:18081 uri: node.community.rino.io:18081
is_default: false is_default: false
-
uri: node.moneroworld.com:18089
is_default: false

View file

@ -5,3 +5,6 @@
- -
uri: api.mainnet-beta.solana.com:443 uri: api.mainnet-beta.solana.com:443
useSSL: true useSSL: true
-
uri: solana-rpc.publicnode.com:443
useSSL: true

View file

@ -1,3 +1,3 @@
Scan and verify messages Monero enhancements
Synchronization enhancements Introducing StealthEx and LetxExchange
Bug fixes Bug fixes

View file

@ -1,3 +1,7 @@
Scan and verify messages Added Litecoin MWEB
Synchronization enhancements Added wallet groups
Silent Payment enhancements for speed & reliability
Monero enhancements
Introducing StealthEx and LetxExchange
Additional ERC20 tokens scam detection
Bug fixes Bug fixes

View file

@ -15,7 +15,7 @@ These steps will help you configure and execute a build of CakeWallet from its s
### 1. Installing Package Dependencies ### 1. Installing Package Dependencies
CakeWallet requires some packages to be install on your build system. You may easily install them on your build system with the following command: 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` `$ sudo apt install build-essential cmake pkg-config git curl autoconf libtool`
@ -145,7 +145,7 @@ Path to executable file will be:
# Flatpak # Flatpak
For package the built application into flatpak you need fistly to install `flatpak` and `flatpak-builder`: For package the built application into flatpak you need firstly to install `flatpak` and `flatpak-builder`:
`$ sudo apt install flatpak flatpak-builder` `$ sudo apt install flatpak flatpak-builder`

View file

@ -1,14 +0,0 @@
import 'dart:typed_data';
import 'package:bitcoin_base/bitcoin_base.dart' as bitcoin;
List<int> 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);
}
}

View file

@ -1,7 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/script_hash.dart' as sh;
abstract class BaseBitcoinAddressRecord { abstract class BaseBitcoinAddressRecord {
BaseBitcoinAddressRecord( BaseBitcoinAddressRecord(
@ -65,8 +64,8 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
required super.type, required super.type,
String? scriptHash, String? scriptHash,
required super.network, required super.network,
}) : scriptHash = }) : scriptHash = scriptHash ??
scriptHash ?? (network != null ? sh.scriptHash(address, network: network) : null); (network != null ? BitcoinAddressUtils.scriptHash(address, network: network) : null);
factory BitcoinAddressRecord.fromJSON(String jsonSource, {BasedUtxoNetwork? network}) { factory BitcoinAddressRecord.fromJSON(String jsonSource, {BasedUtxoNetwork? network}) {
final decoded = json.decode(jsonSource) as Map; final decoded = json.decode(jsonSource) as Map;
@ -92,7 +91,7 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
String getScriptHash(BasedUtxoNetwork network) { String getScriptHash(BasedUtxoNetwork network) {
if (scriptHash != null) return scriptHash!; if (scriptHash != null) return scriptHash!;
scriptHash = sh.scriptHash(address, network: network); scriptHash = BitcoinAddressUtils.scriptHash(address, network: network);
return scriptHash!; return scriptHash!;
} }

View file

@ -5,30 +5,31 @@ import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_bitcoin/utils.dart'; import 'package:cw_bitcoin/utils.dart';
import 'package:cw_core/hardware/hardware_account_data.dart'; import 'package:cw_core/hardware/hardware_account_data.dart';
import 'package:ledger_bitcoin/ledger_bitcoin.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 { class BitcoinHardwareWalletService {
BitcoinHardwareWalletService(this.ledger, this.device); BitcoinHardwareWalletService(this.ledgerConnection);
final Ledger ledger; final LedgerConnection ledgerConnection;
final LedgerDevice device;
Future<List<HardwareAccountData>> getAvailableAccounts({int index = 0, int limit = 5}) async { Future<List<HardwareAccountData>> getAvailableAccounts(
final bitcoinLedgerApp = BitcoinLedgerApp(ledger); {int index = 0, int limit = 5}) async {
final bitcoinLedgerApp = BitcoinLedgerApp(ledgerConnection);
final masterFp = await bitcoinLedgerApp.getMasterFingerprint(device); final masterFp = await bitcoinLedgerApp.getMasterFingerprint();
print(masterFp);
final accounts = <HardwareAccountData>[]; final accounts = <HardwareAccountData>[];
final indexRange = List.generate(limit, (i) => i + index); final indexRange = List.generate(limit, (i) => i + index);
for (final i in indexRange) { for (final i in indexRange) {
final derivationPath = "m/84'/0'/$i'"; final derivationPath = "m/84'/0'/$i'";
final xpub = await bitcoinLedgerApp.getXPubKey(device, derivationPath: derivationPath); final xpub =
await bitcoinLedgerApp.getXPubKey(derivationPath: derivationPath);
Bip32Slip10Secp256k1 hd = Bip32Slip10Secp256k1 hd =
Bip32Slip10Secp256k1.fromExtendedKey(xpub).childKey(Bip32KeyIndex(0)); 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( accounts.add(HardwareAccountData(
address: address, address: address,

View file

@ -1,12 +1,14 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:cryptography/cryptography.dart' as cryptography; import 'package:cryptography/cryptography.dart' as cryptography;
import 'package:cw_core/sec_random_native.dart'; import 'package:cw_core/sec_random_native.dart';
import 'package:cw_core/utils/text_normalizer.dart'; import 'package:cw_core/utils/text_normalizer.dart';
const segwit = '100'; const segwit = '100';
const mweb = 'eb';
final wordlist = englishWordlist; final wordlist = englishWordlist;
double logBase(num x, num base) => log(x) / log(base); double logBase(num x, num base) => log(x) / log(base);
@ -59,11 +61,7 @@ void maskBytes(Uint8List bytes, int bits) {
} }
} }
String bufferToBin(Uint8List data) { String bufferToBin(Uint8List data) => data.map((e) => e.toRadixString(2).padLeft(8, '0')).join('');
final q1 = data.map((e) => e.toRadixString(2).padLeft(8, '0'));
final q2 = q1.join('');
return q2;
}
String encode(Uint8List data) { String encode(Uint8List data) {
final dataBitLen = data.length * 8; final dataBitLen = data.length * 8;
@ -112,22 +110,23 @@ Future<bool> checkIfMnemonicIsElectrum2(String mnemonic) async {
Future<String> getMnemonicHash(String mnemonic) async { Future<String> getMnemonicHash(String mnemonic) async {
final hmacSha512 = Hmac(sha512, utf8.encode('Seed version')); final hmacSha512 = Hmac(sha512, utf8.encode('Seed version'));
final digest = hmacSha512.convert(utf8.encode(normalizeText(mnemonic))); final digest = hmacSha512.convert(utf8.encode(normalizeText(mnemonic)));
final hx = digest.toString(); return digest.toString();
return hx;
} }
Future<Uint8List> mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) async { Future<Uint8List> mnemonicToSeedBytes(String mnemonic,
{String prefix = segwit, String passphrase = ''}) async {
final pbkdf2 = final pbkdf2 =
cryptography.Pbkdf2(macAlgorithm: cryptography.Hmac.sha512(), iterations: 2048, bits: 512); cryptography.Pbkdf2(macAlgorithm: cryptography.Hmac.sha512(), iterations: 2048, bits: 512);
final text = normalizeText(mnemonic); final text = normalizeText(mnemonic);
// pbkdf2.deriveKey(secretKey: secretKey, nonce: nonce) final passphraseBytes = utf8.encode(normalizeText(passphrase));
final key = await pbkdf2.deriveKey( 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(); final bytes = await key.extractBytes();
return Uint8List.fromList(bytes); 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}) { bool validateMnemonic(String mnemonic, {String prefix = segwit}) {
try { try {

View file

@ -7,5 +7,6 @@ class MnemonicBip39 {
static String generate({int strength = 128}) => bip39.generateMnemonic(strength: strength); static String generate({int strength = 128}) => bip39.generateMnemonic(strength: strength);
/// Create root seed from mnemonic /// 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 ?? '');
} }

View file

@ -7,6 +7,7 @@ class BitcoinReceivePageOption implements ReceivePageOption {
static const p2tr = BitcoinReceivePageOption._('Taproot (P2TR)'); static const p2tr = BitcoinReceivePageOption._('Taproot (P2TR)');
static const p2wsh = BitcoinReceivePageOption._('Segwit (P2WSH)'); static const p2wsh = BitcoinReceivePageOption._('Segwit (P2WSH)');
static const p2pkh = BitcoinReceivePageOption._('Legacy (P2PKH)'); static const p2pkh = BitcoinReceivePageOption._('Legacy (P2PKH)');
static const mweb = BitcoinReceivePageOption._('MWEB');
static const silent_payments = BitcoinReceivePageOption._('Silent Payments'); static const silent_payments = BitcoinReceivePageOption._('Silent Payments');
@ -27,6 +28,11 @@ class BitcoinReceivePageOption implements ReceivePageOption {
BitcoinReceivePageOption.p2pkh BitcoinReceivePageOption.p2pkh
]; ];
static const allLitecoin = [
BitcoinReceivePageOption.p2wpkh,
BitcoinReceivePageOption.mweb,
];
BitcoinAddressType toType() { BitcoinAddressType toType() {
switch (this) { switch (this) {
case BitcoinReceivePageOption.p2tr: case BitcoinReceivePageOption.p2tr:
@ -39,6 +45,8 @@ class BitcoinReceivePageOption implements ReceivePageOption {
return P2shAddressType.p2wshInP2sh; return P2shAddressType.p2wshInP2sh;
case BitcoinReceivePageOption.silent_payments: case BitcoinReceivePageOption.silent_payments:
return SilentPaymentsAddresType.p2sp; return SilentPaymentsAddresType.p2sp;
case BitcoinReceivePageOption.mweb:
return SegwitAddresType.mweb;
case BitcoinReceivePageOption.p2wpkh: case BitcoinReceivePageOption.p2wpkh:
default: default:
return SegwitAddresType.p2wpkh; return SegwitAddresType.p2wpkh;
@ -51,6 +59,8 @@ class BitcoinReceivePageOption implements ReceivePageOption {
return BitcoinReceivePageOption.p2tr; return BitcoinReceivePageOption.p2tr;
case SegwitAddresType.p2wsh: case SegwitAddresType.p2wsh:
return BitcoinReceivePageOption.p2wsh; return BitcoinReceivePageOption.p2wsh;
case SegwitAddresType.mweb:
return BitcoinReceivePageOption.mweb;
case P2pkhAddressType.p2pkh: case P2pkhAddressType.p2pkh:
return BitcoinReceivePageOption.p2pkh; return BitcoinReceivePageOption.p2pkh;
case P2shAddressType.p2wshInP2sh: case P2shAddressType.p2wshInP2sh:

View file

@ -1,11 +1,13 @@
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_core/output_info.dart'; import 'package:cw_core/output_info.dart';
import 'package:cw_core/unspent_coin_type.dart';
class BitcoinTransactionCredentials { class BitcoinTransactionCredentials {
BitcoinTransactionCredentials(this.outputs, BitcoinTransactionCredentials(this.outputs,
{required this.priority, this.feeRate}); {required this.priority, this.feeRate, this.coinTypeToSpendFrom = UnspentCoinType.any});
final List<OutputInfo> outputs; final List<OutputInfo> outputs;
final BitcoinTransactionPriority? priority; final BitcoinTransactionPriority? priority;
final int? feeRate; final int? feeRate;
final UnspentCoinType coinTypeToSpendFrom;
} }

View file

@ -87,7 +87,7 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
} }
@override @override
String get units => 'Latoshi'; String get units => 'Litoshi';
@override @override
String toString() { String toString() {

View file

@ -5,13 +5,13 @@ import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:blockchain_utils/blockchain_utils.dart'; import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.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_core/encryption_file_utils.dart';
import 'package:cw_bitcoin/electrum_derivations.dart'; import 'package:cw_bitcoin/electrum_derivations.dart';
import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart'; import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
import 'package:cw_bitcoin/electrum_balance.dart'; import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:cw_bitcoin/electrum_wallet_snapshot.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/crypto_currency.dart';
import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
@ -19,7 +19,7 @@ import 'package:cw_core/wallet_keys_file.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:ledger_bitcoin/ledger_bitcoin.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'; import 'package:mobx/mobx.dart';
part 'bitcoin_wallet.g.dart'; part 'bitcoin_wallet.g.dart';
@ -61,8 +61,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialBalance: initialBalance, initialBalance: initialBalance,
seedBytes: seedBytes, seedBytes: seedBytes,
encryptionFileUtils: encryptionFileUtils, encryptionFileUtils: encryptionFileUtils,
currency: currency: networkParam == BitcoinNetwork.testnet
networkParam == BitcoinNetwork.testnet ? CryptoCurrency.tbtc : CryptoCurrency.btc, ? CryptoCurrency.tbtc
: CryptoCurrency.btc,
alwaysScan: alwaysScan, alwaysScan: alwaysScan,
) { ) {
// in a standard BIP44 wallet, mainHd derivation path = m/84'/0'/0'/0 (account 0, index unspecified here) // in a standard BIP44 wallet, mainHd derivation path = m/84'/0'/0'/0 (account 0, index unspecified here)
@ -80,11 +81,14 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
mainHd: hd, mainHd: hd,
sideHd: accountHD.childKey(Bip32KeyIndex(1)), sideHd: accountHD.childKey(Bip32KeyIndex(1)),
network: networkParam ?? network, network: networkParam ?? network,
masterHd: seedBytes != null ? Bip32Slip10Secp256k1.fromSeed(seedBytes) : null, masterHd:
seedBytes != null ? Bip32Slip10Secp256k1.fromSeed(seedBytes) : null,
isHardwareWallet: walletInfo.isHardwareWallet,
); );
autorun((_) { autorun((_) {
this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress; this.walletAddresses.isEnabledAutoGenerateSubaddress =
this.isEnabledAutoGenerateSubaddress;
}); });
} }
@ -115,7 +119,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
break; break;
case DerivationType.electrum: case DerivationType.electrum:
default: default:
seedBytes = await mnemonicToSeedBytes(mnemonic); seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
break; break;
} }
return BitcoinWallet( return BitcoinWallet(
@ -185,8 +189,10 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
walletInfo.derivationInfo ??= DerivationInfo(); walletInfo.derivationInfo ??= DerivationInfo();
// set the default if not present: // set the default if not present:
walletInfo.derivationInfo!.derivationPath ??= snp?.derivationPath ?? electrum_path; walletInfo.derivationInfo!.derivationPath ??=
walletInfo.derivationInfo!.derivationType ??= snp?.derivationType ?? DerivationType.electrum; snp?.derivationPath ?? electrum_path;
walletInfo.derivationInfo!.derivationType ??=
snp?.derivationType ?? DerivationType.electrum;
Uint8List? seedBytes = null; Uint8List? seedBytes = null;
final mnemonic = keysData.mnemonic; final mnemonic = keysData.mnemonic;
@ -195,7 +201,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
if (mnemonic != null) { if (mnemonic != null) {
switch (walletInfo.derivationInfo!.derivationType) { switch (walletInfo.derivationInfo!.derivationType) {
case DerivationType.electrum: case DerivationType.electrum:
seedBytes = await mnemonicToSeedBytes(mnemonic); seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
break; break;
case DerivationType.bip39: case DerivationType.bip39:
default: default:
@ -228,15 +234,14 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
); );
} }
Ledger? _ledger; LedgerConnection? _ledgerConnection;
LedgerDevice? _ledgerDevice;
BitcoinLedgerApp? _bitcoinLedgerApp; BitcoinLedgerApp? _bitcoinLedgerApp;
void setLedger(Ledger setLedger, LedgerDevice setLedgerDevice) { @override
_ledger = setLedger; void setLedgerConnection(LedgerConnection connection) {
_ledgerDevice = setLedgerDevice; _ledgerConnection = connection;
_bitcoinLedgerApp = _bitcoinLedgerApp = BitcoinLedgerApp(_ledgerConnection!,
BitcoinLedgerApp(_ledger!, derivationPath: walletInfo.derivationInfo!.derivationPath!); derivationPath: walletInfo.derivationInfo!.derivationPath!);
} }
@override @override
@ -251,12 +256,14 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
BitcoinOrdering inputOrdering = BitcoinOrdering.bip69, BitcoinOrdering inputOrdering = BitcoinOrdering.bip69,
BitcoinOrdering outputOrdering = BitcoinOrdering.bip69, BitcoinOrdering outputOrdering = BitcoinOrdering.bip69,
}) async { }) async {
final masterFingerprint = await _bitcoinLedgerApp!.getMasterFingerprint(_ledgerDevice!); final masterFingerprint = await _bitcoinLedgerApp!.getMasterFingerprint();
final psbtReadyInputs = <PSBTReadyUtxoWithAddress>[]; final psbtReadyInputs = <PSBTReadyUtxoWithAddress>[];
for (final utxo in utxos) { for (final utxo in utxos) {
final rawTx = await electrumClient.getTransactionHex(hash: utxo.utxo.txHash); final rawTx =
final publicKeyAndDerivationPath = publicKeys[utxo.ownerDetails.address.pubKeyHash()]!; await electrumClient.getTransactionHex(hash: utxo.utxo.txHash);
final publicKeyAndDerivationPath =
publicKeys[utxo.ownerDetails.address.pubKeyHash()]!;
psbtReadyInputs.add(PSBTReadyUtxoWithAddress( psbtReadyInputs.add(PSBTReadyUtxoWithAddress(
utxo: utxo.utxo, utxo: utxo.utxo,
@ -268,10 +275,10 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
)); ));
} }
final psbt = final psbt = PSBTTransactionBuild(
PSBTTransactionBuild(inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF); inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF);
final rawHex = await _bitcoinLedgerApp!.signPsbt(_ledgerDevice!, psbt: psbt.psbt); final rawHex = await _bitcoinLedgerApp!.signPsbt(psbt: psbt.psbt);
return BtcTransaction.fromRaw(BytesUtils.toHexString(rawHex)); return BtcTransaction.fromRaw(BytesUtils.toHexString(rawHex));
} }
@ -279,14 +286,16 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
Future<String> signMessage(String message, {String? address = null}) async { Future<String> signMessage(String message, {String? address = null}) async {
if (walletInfo.isHardwareWallet) { if (walletInfo.isHardwareWallet) {
final addressEntry = address != null final addressEntry = address != null
? walletAddresses.allAddresses.firstWhere((element) => element.address == address) ? walletAddresses.allAddresses
.firstWhere((element) => element.address == address)
: null; : null;
final index = addressEntry?.index ?? 0; final index = addressEntry?.index ?? 0;
final isChange = addressEntry?.isHidden == true ? 1 : 0; final isChange = addressEntry?.isHidden == true ? 1 : 0;
final accountPath = walletInfo.derivationInfo?.derivationPath; 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!, final signature = await _bitcoinLedgerApp!.signMessage(
message: ascii.encode(message), signDerivationPath: derivationPath); message: ascii.encode(message), signDerivationPath: derivationPath);
return base64Encode(signature); return base64Encode(signature);
} }

View file

@ -15,6 +15,7 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
required super.mainHd, required super.mainHd,
required super.sideHd, required super.sideHd,
required super.network, required super.network,
required super.isHardwareWallet,
super.initialAddresses, super.initialAddresses,
super.initialRegularAddressIndex, super.initialRegularAddressIndex,
super.initialChangeAddressIndex, super.initialChangeAddressIndex,

View file

@ -3,17 +3,24 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
class BitcoinNewWalletCredentials extends WalletCredentials { class BitcoinNewWalletCredentials extends WalletCredentials {
BitcoinNewWalletCredentials( BitcoinNewWalletCredentials({
{required String name, required String name,
WalletInfo? walletInfo, WalletInfo? walletInfo,
String? password, String? password,
DerivationType? derivationType, DerivationType? derivationType,
String? derivationPath}) String? derivationPath,
: super( String? passphrase,
this.mnemonic,
String? parentAddress,
}) : super(
name: name, name: name,
walletInfo: walletInfo, walletInfo: walletInfo,
password: password, password: password,
passphrase: passphrase,
parentAddress: parentAddress,
); );
final String? mnemonic;
} }
class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials { class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {

View file

@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.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/mnemonic_is_incorrect_exception.dart';
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart'; import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/encryption_file_utils.dart';
@ -35,8 +36,21 @@ class BitcoinWalletService extends WalletService<
final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet; final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet;
credentials.walletInfo?.network = network.value; 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( final wallet = await BitcoinWalletBase.create(
mnemonic: await generateElectrumMnemonic(), mnemonic: mnemonic,
password: credentials.password!, password: credentials.password!,
passphrase: credentials.passphrase, passphrase: credentials.passphrase,
walletInfo: credentials.walletInfo!, walletInfo: credentials.walletInfo!,

Some files were not shown because too many files have changed in this diff Show more