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 f37919e9d..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: "11.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 77441e66f..970241189 100644
--- a/.gitignore
+++ b/.gitignore
@@ -160,6 +160,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
@@ -169,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/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/README.md b/README.md
index 7823734fb..1c28f92a2 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-

+
@@ -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 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
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..98bbb1236 100644
--- a/android/app/src/main/AndroidManifestBase.xml
+++ b/android/app/src/main/AndroidManifestBase.xml
@@ -1,35 +1,30 @@
-
-
-
-
-
+
+
-
-
+
-
-
-
+
+
+
-
-
-
+
+
+
+
-
+
+
+
+
-
+
+
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/litecoin_electrum_server_list.yml b/assets/litecoin_electrum_server_list.yml
index 991762885..550b900e1 100644
--- a/assets/litecoin_electrum_server_list.yml
+++ b/assets/litecoin_electrum_server_list.yml
@@ -1,4 +1,19 @@
-
uri: ltc-electrum.cakewallet.com:50002
useSSL: true
- isDefault: true
\ No newline at end of file
+ isDefault: true
+-
+ uri: litecoin.stackwallet.com:20063
+ useSSL: true
+-
+ uri: electrum-ltc.bysh.me:50002
+ useSSL: true
+-
+ uri: lightweight.fiatfaucet.com:50002
+ useSSL: true
+-
+ uri: electrum.ltc.xurious.com:50002
+ useSSL: true
+-
+ uri: backup.electrum-ltc.org:443
+ useSSL: true
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..50ecc76fe
--- /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 have 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 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