diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 7b2b611d3..88cdc6f6c 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -3,6 +3,12 @@ name: PR Test Build
on:
pull_request:
branches: [main]
+ workflow_dispatch:
+ inputs:
+ branch:
+ description: 'Branch name to build'
+ required: true
+ default: 'main'
jobs:
PR_test_build:
@@ -12,6 +18,14 @@ jobs:
KEY_PASS: test@cake_wallet
steps:
+ - name: is pr
+ if: github.event_name == 'pull_request'
+ run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
+
+ - name: is not pr
+ if: github.event_name != 'pull_request'
+ run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENV
+
- name: Free Up GitHub Actions Ubuntu Runner Disk Space
run: |
sudo rm -rf /usr/share/dotnet
@@ -40,7 +54,7 @@ jobs:
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 $GITHUB_HEAD_REF
+ git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
cd cake_wallet/scripts/android/
./install_ndk.sh
source ./app_env.sh cakewallet
@@ -97,6 +111,7 @@ jobs:
cd cw_ethereum && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_bitcoin_cash && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_nano && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+ cd cw_polygon && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
flutter packages pub run build_runner build --delete-conflicting-outputs
- name: Add secrets
@@ -104,6 +119,7 @@ jobs:
cd /opt/android/cake_wallet
touch lib/.secrets.g.dart
touch cw_ethereum/lib/.secrets.g.dart
+ touch cw_polygon/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
@@ -137,9 +153,10 @@ jobs:
echo "const robinhoodCIdApiSecret = '${{ 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_ethereum/lib/.secrets.g.dart
- name: Rename app
- run: echo -e "id=com.cakewallet.test\nname=$GITHUB_HEAD_REF" > /opt/android/cake_wallet/android/app.properties
+ run: echo -e "id=com.cakewallet.test\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
- name: Build
run: |
@@ -154,7 +171,7 @@ jobs:
# appcenter distribute release \
# --group "Testers" \
# --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \
-# --release-notes ${GITHUB_HEAD_REF} \
+# --release-notes ${{ env.BRANCH_NAME }} \
# --app Cake-Labs/Cake-Wallet \
# --token ${{ secrets.APP_CENTER_TOKEN }} \
# --quiet
@@ -163,7 +180,7 @@ jobs:
run: |
cd /opt/android/cake_wallet/build/app/outputs/apk/release
mkdir test-apk
- cp app-release.apk test-apk/$GITHUB_HEAD_REF.apk
+ cp app-release.apk test-apk/${{env.BRANCH_NAME}}.apk
- name: Upload Artifact
uses: kittaakos/upload-artifact-as-is@v0
@@ -177,6 +194,6 @@ jobs:
token: ${{ secrets.SLACK_APP_TOKEN }}
path: /opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk
channel: ${{ secrets.SLACK_APK_CHANNEL }}
- title: "${{github.head_ref}}.apk"
- filename: ${{github.head_ref}}.apk
+ title: "${{ env.BRANCH_NAME }}.apk"
+ filename: ${{ env.BRANCH_NAME }}.apk
initial_comment: ${{ github.event.head_commit.message }}
diff --git a/.gitignore b/.gitignore
index c735d4058..0a883dd18 100644
--- a/.gitignore
+++ b/.gitignore
@@ -126,6 +126,7 @@ lib/haven/haven.dart
lib/ethereum/ethereum.dart
lib/bitcoin_cash/bitcoin_cash.dart
lib/nano/nano.dart
+lib/polygon/polygon.dart
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_180.png
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_120.png
diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml
index 910149f60..f32482e22 100644
--- a/android/app/src/main/AndroidManifestBase.xml
+++ b/android/app/src/main/AndroidManifestBase.xml
@@ -62,6 +62,9 @@
+
+
+
bitcoinAmountToString(amount: confirmed - frozen);
+ String get formattedAvailableBalance =>
+ bitcoinAmountToString(amount: confirmed - unconfirmed.abs() - frozen);
@override
- String get formattedAdditionalBalance => bitcoinAmountToString(amount: unconfirmed);
+ String get formattedAdditionalBalance =>
+ bitcoinAmountToString(amount: unconfirmed);
- String get formattedFrozenBalance {
+ @override
+ String get formattedUnAvailableBalance {
final frozenFormatted = bitcoinAmountToString(amount: frozen);
return frozenFormatted == '0.0' ? '' : frozenFormatted;
}
- String toJSON() =>
- json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed, 'frozen': frozen});
+ String toJSON() => json.encode(
+ {'confirmed': confirmed, 'unconfirmed': unconfirmed, 'frozen': frozen});
}
diff --git a/cw_bitcoin/lib/electrum_transaction_history.dart b/cw_bitcoin/lib/electrum_transaction_history.dart
index be039fa36..d478c3b12 100644
--- a/cw_bitcoin/lib/electrum_transaction_history.dart
+++ b/cw_bitcoin/lib/electrum_transaction_history.dart
@@ -1,10 +1,11 @@
import 'dart:convert';
+
+import 'package:cw_bitcoin/electrum_transaction_info.dart';
import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/transaction_history.dart';
+import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:mobx/mobx.dart';
-import 'package:cw_core/transaction_history.dart';
-import 'package:cw_bitcoin/file.dart';
-import 'package:cw_bitcoin/electrum_transaction_info.dart';
part 'electrum_transaction_history.g.dart';
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 903fa14cc..4c5ecc7f2 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -18,7 +18,6 @@ import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/electrum_transaction_history.dart';
import 'package:cw_bitcoin/electrum_transaction_info.dart';
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
-import 'package:cw_bitcoin/file.dart';
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
import 'package:cw_bitcoin/script_hash.dart';
import 'package:cw_bitcoin/utils.dart';
@@ -30,6 +29,7 @@ import 'package:cw_core/sync_status.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/unspent_coins_info.dart';
+import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:flutter/foundation.dart';
@@ -82,7 +82,7 @@ abstract class ElectrumWalletBase
bitcoin.HDWallet.fromSeed(seedBytes).derivePath("m/44'/145'/0'/0");
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
- inputsCount * 146 + outputsCounts * 33 + 8;
+ inputsCount * 68 + outputsCounts * 34 + 10;
final bitcoin.HDWallet hd;
final String mnemonic;
@@ -725,8 +725,7 @@ abstract class ElectrumWalletBase
final index = address != null
? walletAddresses.addresses.firstWhere((element) => element.address == address).index
: null;
- return index == null
- ? base64Encode(hd.sign(message))
- : base64Encode(hd.derive(index).sign(message));
+ final HD = index == null ? hd : hd.derive(index);
+ return base64Encode(HD.signMessage(message));
}
}
diff --git a/cw_bitcoin/lib/electrum_wallet_snapshot.dart b/cw_bitcoin/lib/electrum_wallet_snapshot.dart
index 0f570071b..ca7c19927 100644
--- a/cw_bitcoin/lib/electrum_wallet_snapshot.dart
+++ b/cw_bitcoin/lib/electrum_wallet_snapshot.dart
@@ -1,9 +1,9 @@
import 'dart:convert';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/electrum_balance.dart';
-import 'package:cw_bitcoin/file.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_type.dart';
class ElectrumWallletSnapshot {
@@ -67,4 +67,4 @@ class ElectrumWallletSnapshot {
derivationType: derivationType,
derivationPath: derivationPath);
}
-}
\ No newline at end of file
+}
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index 43391881f..3344cb807 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -79,11 +79,11 @@ packages:
dependency: "direct main"
description:
path: "."
- ref: cake-update-v3
- resolved-ref: df9204144011ed9419eff7d9ef3143102a40252d
+ ref: cake-update-v4
+ resolved-ref: e19ffb7e7977278a75b27e0479b3c6f4034223b3
url: "https://github.com/cake-tech/bitcoin_flutter.git"
source: git
- version: "2.0.2"
+ version: "2.1.0"
boolean_selector:
dependency: transitive
description:
@@ -244,7 +244,7 @@ packages:
source: hosted
version: "2.2.4"
encrypt:
- dependency: "direct main"
+ dependency: transitive
description:
name: encrypt
sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
@@ -698,15 +698,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
- tor:
- dependency: transitive
- description:
- path: "."
- ref: main
- resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
- url: "https://github.com/cake-tech/tor.git"
- source: git
- version: "0.0.1"
typed_data:
dependency: transitive
description:
diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index 693d5af7a..a50ff68ad 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -22,7 +22,7 @@ dependencies:
bitcoin_flutter:
git:
url: https://github.com/cake-tech/bitcoin_flutter.git
- ref: cake-update-v3
+ ref: cake-update-v4
bitbox:
git:
url: https://github.com/cake-tech/bitbox-flutter.git
@@ -30,7 +30,6 @@ dependencies:
rxdart: ^0.27.5
unorm_dart: ^0.2.0
cryptography: ^2.0.5
- encrypt: ^5.0.1
dev_dependencies:
flutter_test:
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
index 5f2a33ab6..c23220423 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
@@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:bitbox/bitbox.dart' as bitbox;
+import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
@@ -210,9 +211,28 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
txb.addInput(input.hash, input.vout);
});
+ final String bchPrefix = "bitcoincash:";
+
outputs.forEach((item) {
final outputAmount = hasMultiDestination ? item.formattedCryptoAmount : amount;
- final outputAddress = item.isParsedAddress ? item.extractedAddress! : item.address;
+ String outputAddress = item.isParsedAddress ? item.extractedAddress! : item.address;
+
+ if (!outputAddress.startsWith(bchPrefix)) {
+ outputAddress = "$bchPrefix$outputAddress";
+ }
+
+ bool isP2sh = outputAddress.startsWith("p", bchPrefix.length);
+
+ if (isP2sh) {
+ final p2sh = P2shAddress.fromAddress(
+ address: outputAddress,
+ network: BitcoinCashNetwork.mainnet,
+ );
+
+ txb.addOutput(Uint8List.fromList(p2sh.toScriptPubKey().toBytes()), outputAmount!);
+ return;
+ }
+
txb.addOutput(outputAddress, outputAmount!);
});
@@ -302,10 +322,8 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
final index = address != null
? walletAddresses.addresses
.firstWhere((element) => element.address == AddressUtils.toLegacyAddress(address))
- .index
- : null;
- return index == null
- ? base64Encode(hd.sign(message))
- : base64Encode(hd.derive(index).sign(message));
+ .index : null;
+ final HD = index == null ? hd : hd.derive(index);
+ return base64Encode(HD.signMessage(message));
}
}
diff --git a/cw_bitcoin_cash/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux b/cw_bitcoin_cash/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux
deleted file mode 120000
index 0ed52b295..000000000
--- a/cw_bitcoin_cash/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux
+++ /dev/null
@@ -1 +0,0 @@
-/Users/blazebrain/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/
\ No newline at end of file
diff --git a/cw_bitcoin_cash/linux/flutter/ephemeral/.plugin_symlinks/tor b/cw_bitcoin_cash/linux/flutter/ephemeral/.plugin_symlinks/tor
deleted file mode 120000
index 7ee2b206d..000000000
--- a/cw_bitcoin_cash/linux/flutter/ephemeral/.plugin_symlinks/tor
+++ /dev/null
@@ -1 +0,0 @@
-/Users/blazebrain/.pub-cache/git/tor-09ba92cb11d4e3cacf97256e57863b805f79f2e5/
\ No newline at end of file
diff --git a/cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.cc b/cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index e71a16d23..000000000
--- a/cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void fl_register_plugins(FlPluginRegistry* registry) {
-}
diff --git a/cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.h b/cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.h
deleted file mode 100644
index e0f0a47bc..000000000
--- a/cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include
-
-// Registers Flutter plugins.
-void fl_register_plugins(FlPluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/cw_bitcoin_cash/linux/flutter/generated_plugins.cmake b/cw_bitcoin_cash/linux/flutter/generated_plugins.cmake
deleted file mode 100644
index 3d57782b2..000000000
--- a/cw_bitcoin_cash/linux/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
- tor
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/cw_bitcoin_cash/macos/Flutter/GeneratedPluginRegistrant.swift b/cw_bitcoin_cash/macos/Flutter/GeneratedPluginRegistrant.swift
deleted file mode 100644
index e777c67df..000000000
--- a/cw_bitcoin_cash/macos/Flutter/GeneratedPluginRegistrant.swift
+++ /dev/null
@@ -1,12 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-import FlutterMacOS
-import Foundation
-
-import path_provider_foundation
-
-func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
- PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
-}
diff --git a/cw_bitcoin_cash/macos/Flutter/ephemeral/Flutter-Generated.xcconfig b/cw_bitcoin_cash/macos/Flutter/ephemeral/Flutter-Generated.xcconfig
deleted file mode 100644
index 2f46994d3..000000000
--- a/cw_bitcoin_cash/macos/Flutter/ephemeral/Flutter-Generated.xcconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-// This is a generated file; do not edit or check into version control.
-FLUTTER_ROOT=C:\Users\borod\flutter
-FLUTTER_APPLICATION_PATH=C:\cake_wallet\cw_bitcoin_cash
-COCOAPODS_PARALLEL_CODE_SIGN=true
-FLUTTER_BUILD_DIR=build
-FLUTTER_BUILD_NAME=0.0.1
-FLUTTER_BUILD_NUMBER=0.0.1
-DART_OBFUSCATION=false
-TRACK_WIDGET_CREATION=true
-TREE_SHAKE_ICONS=false
-PACKAGE_CONFIG=.dart_tool/package_config.json
diff --git a/cw_bitcoin_cash/macos/Flutter/ephemeral/flutter_export_environment.sh b/cw_bitcoin_cash/macos/Flutter/ephemeral/flutter_export_environment.sh
deleted file mode 100644
index 2a3bcca5a..000000000
--- a/cw_bitcoin_cash/macos/Flutter/ephemeral/flutter_export_environment.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-# This is a generated file; do not edit or check into version control.
-export "FLUTTER_ROOT=C:\Users\borod\flutter"
-export "FLUTTER_APPLICATION_PATH=C:\cake_wallet\cw_bitcoin_cash"
-export "COCOAPODS_PARALLEL_CODE_SIGN=true"
-export "FLUTTER_BUILD_DIR=build"
-export "FLUTTER_BUILD_NAME=0.0.1"
-export "FLUTTER_BUILD_NUMBER=0.0.1"
-export "DART_OBFUSCATION=false"
-export "TRACK_WIDGET_CREATION=true"
-export "TREE_SHAKE_ICONS=false"
-export "PACKAGE_CONFIG=.dart_tool/package_config.json"
diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml
index 30ed49e80..49a5efb15 100644
--- a/cw_bitcoin_cash/pubspec.yaml
+++ b/cw_bitcoin_cash/pubspec.yaml
@@ -24,11 +24,12 @@ dependencies:
bitcoin_flutter:
git:
url: https://github.com/cake-tech/bitcoin_flutter.git
- ref: cake-update-v3
+ ref: cake-update-v4
bitbox:
git:
url: https://github.com/cake-tech/bitbox-flutter.git
ref: master
+ bitcoin_base: ^3.0.1
diff --git a/cw_bitcoin_cash/windows/flutter/generated_plugin_registrant.cc b/cw_bitcoin_cash/windows/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index 8b6d4680a..000000000
--- a/cw_bitcoin_cash/windows/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void RegisterPlugins(flutter::PluginRegistry* registry) {
-}
diff --git a/cw_bitcoin_cash/windows/flutter/generated_plugin_registrant.h b/cw_bitcoin_cash/windows/flutter/generated_plugin_registrant.h
deleted file mode 100644
index dc139d85a..000000000
--- a/cw_bitcoin_cash/windows/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include
-
-// Registers Flutter plugins.
-void RegisterPlugins(flutter::PluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/cw_bitcoin_cash/windows/flutter/generated_plugins.cmake b/cw_bitcoin_cash/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c30c..000000000
--- a/cw_bitcoin_cash/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart
index 1936a87cf..0f7f25d9b 100644
--- a/cw_core/lib/crypto_currency.dart
+++ b/cw_core/lib/crypto_currency.dart
@@ -93,6 +93,8 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen
CryptoCurrency.dydx,
CryptoCurrency.steth,
CryptoCurrency.banano,
+ CryptoCurrency.usdtPoly,
+ CryptoCurrency.usdcEPoly,
];
static const havenCurrencies = [
@@ -202,6 +204,8 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen
static const dydx = CryptoCurrency(title: 'DYDX', tag: 'ETH', fullName: 'dYdX', raw: 84, name: 'dydx', iconPath: 'assets/images/dydx_icon.png', decimals: 18);
static const steth = CryptoCurrency(title: 'STETH', tag: 'ETH', fullName: 'Lido Staked Ethereum', raw: 85, name: 'steth', iconPath: 'assets/images/steth_icon.png', decimals: 18);
static const banano = CryptoCurrency(title: 'BAN', fullName: 'Banano', raw: 86, name: 'banano', iconPath: 'assets/images/nano_icon.png', decimals: 29);
+ static const usdtPoly = CryptoCurrency(title: 'USDT', tag: 'POLY', fullName: 'Tether USD (PoS)', raw: 87, name: 'usdtpoly', iconPath: 'assets/images/usdt_icon.png', decimals: 6);
+ static const usdcEPoly = CryptoCurrency(title: 'USDC.E', tag: 'POLY', fullName: 'USD Coin (PoS)', raw: 88, name: 'usdcepoly', iconPath: 'assets/images/usdc_icon.png', decimals: 6);
static final Map _rawCurrencyMap =
@@ -241,7 +245,7 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen
}
static CryptoCurrency fromFullName(String name) {
- if (CryptoCurrency._fullNameCurrencyMap[name.toLowerCase()] == null) {
+ if (CryptoCurrency._fullNameCurrencyMap[name.split("(").first.trim().toLowerCase()] == null) {
final s = 'Unexpected token: $name for CryptoCurrency fromFullName';
throw ArgumentError.value(name, 'Fullname', s);
}
diff --git a/cw_core/lib/currency_for_wallet_type.dart b/cw_core/lib/currency_for_wallet_type.dart
index 4c330b073..ce0219f1f 100644
--- a/cw_core/lib/currency_for_wallet_type.dart
+++ b/cw_core/lib/currency_for_wallet_type.dart
@@ -19,6 +19,8 @@ CryptoCurrency currencyForWalletType(WalletType type) {
return CryptoCurrency.nano;
case WalletType.banano:
return CryptoCurrency.banano;
+ case WalletType.polygon:
+ return CryptoCurrency.maticpoly;
default:
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
}
diff --git a/cw_core/lib/erc20_token.dart b/cw_core/lib/erc20_token.dart
index 011fdef1d..f8c2afc06 100644
--- a/cw_core/lib/erc20_token.dart
+++ b/cw_core/lib/erc20_token.dart
@@ -18,6 +18,8 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin {
bool _enabled;
@HiveField(5)
final String? iconPath;
+ @HiveField(6)
+ final String? tag;
bool get enabled => _enabled;
@@ -30,37 +32,41 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin {
required this.decimal,
bool enabled = true,
this.iconPath,
+ this.tag,
}) : _enabled = enabled,
super(
- name: symbol.toLowerCase(),
- title: symbol.toUpperCase(),
- fullName: name,
- tag: "ETH",
- iconPath: iconPath,
- decimals: decimal
- );
+ name: symbol.toLowerCase(),
+ title: symbol.toUpperCase(),
+ fullName: name,
+ tag: tag,
+ iconPath: iconPath,
+ decimals: decimal);
- Erc20Token.copyWith(Erc20Token other, String? icon)
+ Erc20Token.copyWith(Erc20Token other, String? icon, String? tag)
: this.name = other.name,
this.symbol = other.symbol,
this.contractAddress = other.contractAddress,
this.decimal = other.decimal,
this._enabled = other.enabled,
+ this.tag = tag,
this.iconPath = icon,
super(
name: other.name,
title: other.symbol.toUpperCase(),
fullName: other.name,
- tag: "ETH",
+ tag: tag,
iconPath: icon,
- decimals: other.decimal
+ decimals: other.decimal,
);
static const typeId = ERC20_TOKEN_TYPE_ID;
static const boxName = 'Erc20Tokens';
+ static const ethereumBoxName = 'EthereumErc20Tokens';
+ static const polygonBoxName = 'PolygonErc20Tokens';
@override
- bool operator ==(other) => (other is Erc20Token && other.contractAddress == contractAddress) ||
+ bool operator ==(other) =>
+ (other is Erc20Token && other.contractAddress == contractAddress) ||
(other is CryptoCurrency && other.title == title);
@override
diff --git a/cw_core/lib/get_height_by_date.dart b/cw_core/lib/get_height_by_date.dart
index a680e6c25..6f3ccaf68 100644
--- a/cw_core/lib/get_height_by_date.dart
+++ b/cw_core/lib/get_height_by_date.dart
@@ -118,7 +118,10 @@ final dates = {
"2023-6": 2898234,
"2023-7": 2919771,
"2023-8": 2942045,
- "2023-9": 2964280
+ "2023-9": 2964280,
+ "2023-10": 2985937,
+ "2023-11": 3008178,
+ "2023-12": 3029759
};
int getMoneroHeigthByDate({required DateTime date}) {
diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart
index 484325f91..2c43dd21a 100644
--- a/cw_core/lib/node.dart
+++ b/cw_core/lib/node.dart
@@ -6,7 +6,7 @@ import 'package:hive/hive.dart';
import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:http/io_client.dart' as ioc;
-import 'package:tor/tor.dart';
+// import 'package:tor/tor.dart';
part 'node.g.dart';
@@ -88,6 +88,8 @@ class Node extends HiveObject with Keyable {
} else {
return Uri.http(uriRaw, '');
}
+ case WalletType.polygon:
+ return Uri.https(uriRaw, '');
default:
throw Exception('Unexpected type ${type.toString()} for Node uri');
}
@@ -146,6 +148,8 @@ class Node extends HiveObject with Keyable {
case WalletType.nano:
case WalletType.banano:
return requestNanoNode();
+ case WalletType.polygon:
+ return requestElectrumServer();
default:
return false;
}
@@ -210,14 +214,17 @@ class Node extends HiveObject with Keyable {
}
Future requestNodeWithProxy() async {
- if (!isValidProxyAddress && !Tor.instance.enabled) {
+ if (!isValidProxyAddress /* && !Tor.instance.enabled*/) {
return false;
}
String? proxy = socksProxyAddress;
- if ((proxy?.isEmpty ?? true) && Tor.instance.enabled) {
- proxy = "${InternetAddress.loopbackIPv4.address}:${Tor.instance.port}";
+ // if ((proxy?.isEmpty ?? true) && Tor.instance.enabled) {
+ // proxy = "${InternetAddress.loopbackIPv4.address}:${Tor.instance.port}";
+ // }
+ if (proxy == null) {
+ return false;
}
final proxyAddress = proxy!.split(':')[0];
final proxyPort = int.parse(proxy.split(':')[1]);
diff --git a/cw_bitcoin/lib/file.dart b/cw_core/lib/utils/file.dart
similarity index 66%
rename from cw_bitcoin/lib/file.dart
rename to cw_core/lib/utils/file.dart
index 8fd236ec3..0b1c5cffd 100644
--- a/cw_bitcoin/lib/file.dart
+++ b/cw_core/lib/utils/file.dart
@@ -2,17 +2,8 @@ import 'dart:io';
import 'package:cw_core/key.dart';
import 'package:encrypt/encrypt.dart' as encrypt;
-Future write(
- {required String path,
- required String password,
- required String data}) async {
- final keys = extractKeys(password);
- final key = encrypt.Key.fromBase64(keys.first);
- final iv = encrypt.IV.fromBase64(keys.last);
- final encrypted = await encode(key: key, iv: iv, data: data);
- final f = File(path);
- f.writeAsStringSync(encrypted);
-}
+Future write({required String path, required String password, required String data}) async =>
+ writeData(path: path, password: password, data: data);
Future writeData(
{required String path,
diff --git a/cw_core/lib/wallet_type.dart b/cw_core/lib/wallet_type.dart
index debf92e11..20f0bdb19 100644
--- a/cw_core/lib/wallet_type.dart
+++ b/cw_core/lib/wallet_type.dart
@@ -13,6 +13,7 @@ const walletTypes = [
WalletType.bitcoinCash,
WalletType.nano,
WalletType.banano,
+ WalletType.polygon,
];
@HiveType(typeId: WALLET_TYPE_TYPE_ID)
@@ -44,6 +45,8 @@ enum WalletType {
@HiveField(8)
bitcoinCash,
+ @HiveField(9)
+ polygon
}
int serializeToInt(WalletType type) {
@@ -64,6 +67,8 @@ int serializeToInt(WalletType type) {
return 6;
case WalletType.bitcoinCash:
return 7;
+ case WalletType.polygon:
+ return 8;
default:
return -1;
}
@@ -87,6 +92,8 @@ WalletType deserializeFromInt(int raw) {
return WalletType.banano;
case 7:
return WalletType.bitcoinCash;
+ case 8:
+ return WalletType.polygon;
default:
throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
}
@@ -110,6 +117,8 @@ String walletTypeToString(WalletType type) {
return 'Nano';
case WalletType.banano:
return 'Banano';
+ case WalletType.polygon:
+ return 'Polygon';
default:
return '';
}
@@ -133,6 +142,8 @@ String walletTypeToDisplayName(WalletType type) {
return 'Nano (XNO)';
case WalletType.banano:
return 'Banano (BAN)';
+ case WalletType.polygon:
+ return 'Polygon (MATIC)';
default:
return '';
}
@@ -156,7 +167,10 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
return CryptoCurrency.nano;
case WalletType.banano:
return CryptoCurrency.banano;
+ case WalletType.polygon:
+ return CryptoCurrency.maticpoly;
default:
- throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
+ throw Exception(
+ 'Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
}
}
diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock
index f351759ed..aacbd9ddd 100644
--- a/cw_core/pubspec.lock
+++ b/cw_core/pubspec.lock
@@ -616,15 +616,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
- tor:
- dependency: "direct main"
- description:
- path: "."
- ref: main
- resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
- url: "https://github.com/cake-tech/tor.git"
- source: git
- version: "0.0.1"
typed_data:
dependency: transitive
description:
diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml
index 533b578ad..04a840d4e 100644
--- a/cw_core/pubspec.yaml
+++ b/cw_core/pubspec.yaml
@@ -20,10 +20,10 @@ dependencies:
intl: ^0.18.0
encrypt: ^5.0.1
socks5_proxy: ^1.0.4
- tor:
- git:
- url: https://github.com/cake-tech/tor.git
- ref: main
+# tor:
+# git:
+# url: https://github.com/cake-tech/tor.git
+# ref: main
dev_dependencies:
flutter_test:
diff --git a/cw_ethereum/lib/default_erc20_tokens.dart b/cw_ethereum/lib/default_ethereum_erc20_tokens.dart
similarity index 95%
rename from cw_ethereum/lib/default_erc20_tokens.dart
rename to cw_ethereum/lib/default_ethereum_erc20_tokens.dart
index 8c38e2e64..a8f82d181 100644
--- a/cw_ethereum/lib/default_erc20_tokens.dart
+++ b/cw_ethereum/lib/default_ethereum_erc20_tokens.dart
@@ -293,17 +293,13 @@ class DefaultErc20Tokens {
];
List get initialErc20Tokens => _defaultTokens.map((token) {
- String? iconPath;
- try {
- iconPath = CryptoCurrency.all
- .firstWhere((element) => element.title.toUpperCase() == token.symbol.toUpperCase())
- .iconPath;
- } catch (_) {}
+ String? iconPath;
+ try {
+ iconPath = CryptoCurrency.all
+ .firstWhere((element) => element.title.toUpperCase() == token.symbol.toUpperCase())
+ .iconPath;
+ } catch (_) {}
- if (iconPath != null) {
- return Erc20Token.copyWith(token, iconPath);
- }
-
- return token;
- }).toList();
+ return Erc20Token.copyWith(token, iconPath, 'ETH');
+ }).toList();
}
diff --git a/cw_ethereum/lib/ethereum_client.dart b/cw_ethereum/lib/ethereum_client.dart
index f0c7381e8..fccbf778d 100644
--- a/cw_ethereum/lib/ethereum_client.dart
+++ b/cw_ethereum/lib/ethereum_client.dart
@@ -15,12 +15,12 @@ import 'package:cw_ethereum/ethereum_transaction_priority.dart';
import 'package:cw_ethereum/.secrets.g.dart' as secrets;
class EthereumClient {
- final _httpClient = Client();
+ final httpClient = Client();
Web3Client? _client;
bool connect(Node node) {
try {
- _client = Web3Client(node.uri.toString(), _httpClient);
+ _client = Web3Client(node.uri.toString(), httpClient);
return true;
} catch (e) {
@@ -74,29 +74,34 @@ class EthereumClient {
required int exponent,
String? contractAddress,
}) async {
- assert(currency == CryptoCurrency.eth || contractAddress != null);
+ assert(currency == CryptoCurrency.eth ||
+ currency == CryptoCurrency.maticpoly ||
+ contractAddress != null);
- bool _isEthereum = currency == CryptoCurrency.eth;
+ bool _isEVMCompatibleChain =
+ currency == CryptoCurrency.eth || currency == CryptoCurrency.maticpoly;
final price = _client!.getGasPrice();
- final Transaction transaction = Transaction(
+ final Transaction transaction = createTransaction(
from: privateKey.address,
to: EthereumAddress.fromHex(toAddress),
maxPriorityFeePerGas: EtherAmount.fromInt(EtherUnit.gwei, priority.tip),
- value: _isEthereum ? EtherAmount.inWei(BigInt.parse(amount)) : EtherAmount.zero(),
+ amount: _isEVMCompatibleChain ? EtherAmount.inWei(BigInt.parse(amount)) : EtherAmount.zero(),
);
- final signedTransaction = await _client!.signTransaction(privateKey, transaction);
+ final signedTransaction =
+ await _client!.signTransaction(privateKey, transaction, chainId: chainId);
final Function _sendTransaction;
- if (_isEthereum) {
+ if (_isEVMCompatibleChain) {
_sendTransaction = () async => await sendTransaction(signedTransaction);
} else {
final erc20 = ERC20(
client: _client!,
address: EthereumAddress.fromHex(contractAddress!),
+ chainId: chainId,
);
_sendTransaction = () async {
@@ -118,8 +123,27 @@ class EthereumClient {
);
}
+ int get chainId => 1;
+
+ Transaction createTransaction({
+ required EthereumAddress from,
+ required EthereumAddress to,
+ required EtherAmount amount,
+ EtherAmount? maxPriorityFeePerGas,
+ }) {
+ return Transaction(
+ from: from,
+ to: to,
+ maxPriorityFeePerGas: maxPriorityFeePerGas,
+ value: amount,
+ );
+ }
+
Future sendTransaction(Uint8List signedTransaction) async =>
- await _client!.sendRawTransaction(prependTransactionType(0x02, signedTransaction));
+ await _client!.sendRawTransaction(prepareSignedTransactionForSending(signedTransaction));
+
+ Uint8List prepareSignedTransactionForSending(Uint8List signedTransaction) =>
+ prependTransactionType(0x02, signedTransaction);
Future getTransactionDetails(String transactionHash) async {
// Wait for the transaction receipt to become available
@@ -198,7 +222,7 @@ I/flutter ( 4474): Gas Used: 53000
Future> fetchTransactions(String address,
{String? contractAddress}) async {
try {
- final response = await _httpClient.get(Uri.https("api.etherscan.io", "/api", {
+ final response = await httpClient.get(Uri.https("api.etherscan.io", "/api", {
"module": "account",
"action": contractAddress != null ? "tokentx" : "txlist",
if (contractAddress != null) "contractaddress": contractAddress,
diff --git a/cw_ethereum/lib/ethereum_transaction_info.dart b/cw_ethereum/lib/ethereum_transaction_info.dart
index a0649ba25..f0deae931 100644
--- a/cw_ethereum/lib/ethereum_transaction_info.dart
+++ b/cw_ethereum/lib/ethereum_transaction_info.dart
@@ -1,3 +1,5 @@
+import 'dart:math';
+
import 'package:cw_core/format_amount.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_info.dart';
@@ -34,8 +36,10 @@ class EthereumTransactionInfo extends TransactionInfo {
final String? to;
@override
- String amountFormatted() =>
- '${formatAmount((ethAmount / BigInt.from(10).pow(exponent)).toString())} $tokenSymbol';
+ String amountFormatted() {
+ final amount = formatAmount((ethAmount / BigInt.from(10).pow(exponent)).toString());
+ return '${amount.substring(0, min(10, amount.length))} $tokenSymbol';
+ }
@override
String fiatAmount() => _fiatAmount ?? '';
@@ -44,7 +48,10 @@ class EthereumTransactionInfo extends TransactionInfo {
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
@override
- String feeFormatted() => '${(ethFee / BigInt.from(10).pow(18)).toString()} ETH';
+ String feeFormatted() {
+ final amount = (ethFee / BigInt.from(10).pow(18)).toString();
+ return '${amount.substring(0, min(10, amount.length))} ETH';
+ }
factory EthereumTransactionInfo.fromJson(Map data) {
return EthereumTransactionInfo(
diff --git a/cw_ethereum/lib/ethereum_transaction_model.dart b/cw_ethereum/lib/ethereum_transaction_model.dart
index c1260795a..3b5f724fc 100644
--- a/cw_ethereum/lib/ethereum_transaction_model.dart
+++ b/cw_ethereum/lib/ethereum_transaction_model.dart
@@ -1,3 +1,4 @@
+//! Model used for in parsing transactions fetched using etherscan
class EthereumTransactionModel {
final DateTime date;
final String hash;
diff --git a/cw_ethereum/lib/ethereum_wallet.dart b/cw_ethereum/lib/ethereum_wallet.dart
index 21bde1233..cd4bd84cc 100644
--- a/cw_ethereum/lib/ethereum_wallet.dart
+++ b/cw_ethereum/lib/ethereum_wallet.dart
@@ -14,7 +14,7 @@ import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/wallet_addresses.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_info.dart';
-import 'package:cw_ethereum/default_erc20_tokens.dart';
+import 'package:cw_ethereum/default_ethereum_erc20_tokens.dart';
import 'package:cw_ethereum/erc20_balance.dart';
import 'package:cw_ethereum/ethereum_client.dart';
import 'package:cw_ethereum/ethereum_exceptions.dart';
@@ -75,6 +75,8 @@ abstract class EthereumWalletBase
late final Box erc20TokensBox;
+ late final Box ethereumErc20TokensBox;
+
late final EthPrivateKey _ethPrivateKey;
EthPrivateKey get ethPrivateKey => _ethPrivateKey;
@@ -102,7 +104,8 @@ abstract class EthereumWalletBase
Completer _sharedPrefs = Completer();
Future init() async {
- erc20TokensBox = await CakeHive.openBox(Erc20Token.boxName);
+ await movePreviousErc20BoxConfigsToNewBox();
+
await walletAddresses.init();
await transactionHistory.init();
_ethPrivateKey = await getPrivateKey(
@@ -114,6 +117,33 @@ abstract class EthereumWalletBase
await save();
}
+ /// Majorly for backward compatibility for previous configs that have been set.
+ Future movePreviousErc20BoxConfigsToNewBox() async {
+ // Opens a box specific to this wallet
+ ethereumErc20TokensBox = await CakeHive.openBox(
+ "${walletInfo.name.replaceAll(" ", "_")}_${Erc20Token.ethereumBoxName}");
+
+ //Open the previous token configs box
+ erc20TokensBox = await CakeHive.openBox(Erc20Token.boxName);
+
+ // Check if it's empty, if it is, we stop the flow and return.
+ if (erc20TokensBox.isEmpty) {
+ // If it's empty, but the new wallet specific box is also empty,
+ // we load the initial tokens to the new box.
+ if (ethereumErc20TokensBox.isEmpty) addInitialTokens();
+ return;
+ }
+
+ final allValues = erc20TokensBox.values.toList();
+
+ // Clear and delete the old token box
+ await erc20TokensBox.clear();
+ await erc20TokensBox.deleteFromDisk();
+
+ // Add all the previous tokens with configs to the new box
+ ethereumErc20TokensBox.addAll(allValues);
+ }
+
@override
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
try {
@@ -378,7 +408,7 @@ abstract class EthereumWalletBase
}
Future _fetchErc20Balances() async {
- for (var token in erc20TokensBox.values) {
+ for (var token in ethereumErc20TokensBox.values) {
try {
if (token.enabled) {
balance[token] = await _client.fetchERC20Balances(
@@ -413,7 +443,7 @@ abstract class EthereumWalletBase
Future? updateBalance() async => await _updateBalance();
- List get erc20Currencies => erc20TokensBox.values.toList();
+ List get erc20Currencies => ethereumErc20TokensBox.values.toList();
Future addErc20Token(Erc20Token token) async {
String? iconPath;
@@ -429,10 +459,11 @@ abstract class EthereumWalletBase
contractAddress: token.contractAddress,
decimal: token.decimal,
enabled: token.enabled,
+ tag: token.tag ?? "ETH",
iconPath: iconPath,
);
- await erc20TokensBox.put(_token.contractAddress, _token);
+ await ethereumErc20TokensBox.put(_token.contractAddress, _token);
if (_token.enabled) {
balance[_token] = await _client.fetchERC20Balances(
@@ -462,7 +493,7 @@ abstract class EthereumWalletBase
void addInitialTokens() {
final initialErc20Tokens = DefaultErc20Tokens().initialErc20Tokens;
- initialErc20Tokens.forEach((token) => erc20TokensBox.put(token.contractAddress, token));
+ initialErc20Tokens.forEach((token) => ethereumErc20TokensBox.put(token.contractAddress, token));
}
@override
@@ -492,7 +523,7 @@ abstract class EthereumWalletBase
_transactionsUpdateTimer!.cancel();
}
- _transactionsUpdateTimer = Timer.periodic(Duration(seconds: 10), (_) {
+ _transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 10), (_) {
_updateTransactions();
_updateBalance();
});
@@ -508,7 +539,7 @@ abstract class EthereumWalletBase
}
@override
- String signMessage(String message, {String? address = null}) =>
+ String signMessage(String message, {String? address}) =>
bytesToHex(_ethPrivateKey.signPersonalMessageToUint8List(ascii.encode(message)));
Web3Client? getWeb3Client() => _client.getWeb3Client();
diff --git a/cw_ethereum/lib/ethereum_wallet_service.dart b/cw_ethereum/lib/ethereum_wallet_service.dart
index 8810d6014..0acc90bac 100644
--- a/cw_ethereum/lib/ethereum_wallet_service.dart
+++ b/cw_ethereum/lib/ethereum_wallet_service.dart
@@ -20,12 +20,7 @@ class EthereumWalletService extends WalletService create(EthereumNewWalletCredentials credentials) async {
-
- final strength = (credentials.seedPhraseLength == 12)
- ? 128
- : (credentials.seedPhraseLength == 24)
- ? 256
- : 128;
+ final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
final mnemonic = bip39.generateMnemonic(strength: strength);
final wallet = EthereumWallet(
@@ -67,8 +62,8 @@ class EthereumWalletService extends WalletService remove(String wallet) async {
File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
- final walletInfo = walletInfoSource.values.firstWhereOrNull(
- (info) => info.id == WalletBase.idFor(wallet, getType()))!;
+ final walletInfo = walletInfoSource.values
+ .firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
await walletInfoSource.delete(walletInfo.key);
}
diff --git a/cw_ethereum/lib/pending_ethereum_transaction.dart b/cw_ethereum/lib/pending_ethereum_transaction.dart
index 35b0123cc..d47630fd6 100644
--- a/cw_ethereum/lib/pending_ethereum_transaction.dart
+++ b/cw_ethereum/lib/pending_ethereum_transaction.dart
@@ -21,8 +21,8 @@ class PendingEthereumTransaction with PendingTransaction {
@override
String get amountFormatted {
- final _amount = BigInt.parse(amount) / BigInt.from(pow(10, exponent));
- return _amount.toStringAsFixed(min(15, _amount.toString().length));
+ final _amount = (BigInt.parse(amount) / BigInt.from(pow(10, exponent))).toString();
+ return _amount.substring(0, min(10, _amount.length));
}
@override
@@ -30,8 +30,8 @@ class PendingEthereumTransaction with PendingTransaction {
@override
String get feeFormatted {
- final _fee = fee / BigInt.from(pow(10, 18));
- return _fee.toStringAsFixed(min(15, _fee.toString().length));
+ final _fee = (fee / BigInt.from(pow(10, 18))).toString();
+ return _fee.substring(0, min(10, _fee.length));
}
@override
diff --git a/cw_ethereum/pubspec.yaml b/cw_ethereum/pubspec.yaml
index 5d19589f3..6946a43a1 100644
--- a/cw_ethereum/pubspec.yaml
+++ b/cw_ethereum/pubspec.yaml
@@ -17,7 +17,6 @@ dependencies:
mobx: ^2.0.7+4
bip39: ^1.0.6
bip32: ^2.0.0
- ed25519_hd_key: ^2.2.0
hex: ^0.2.0
http: ^1.1.0
shared_preferences: ^2.0.15
diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock
index 525e8e5fa..b0a350cc7 100644
--- a/cw_haven/pubspec.lock
+++ b/cw_haven/pubspec.lock
@@ -623,15 +623,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
- tor:
- dependency: transitive
- description:
- path: "."
- ref: main
- resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
- url: "https://github.com/cake-tech/tor.git"
- source: git
- version: "0.0.1"
typed_data:
dependency: transitive
description:
diff --git a/cw_monero/example/pubspec.lock b/cw_monero/example/pubspec.lock
index 3dd2b5b61..c9ca8d92b 100644
--- a/cw_monero/example/pubspec.lock
+++ b/cw_monero/example/pubspec.lock
@@ -153,6 +153,22 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ hashlib:
+ dependency: transitive
+ description:
+ name: hashlib
+ sha256: "71bf102329ddb8e50c8a995ee4645ae7f1728bb65e575c17196b4d8262121a96"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.12.0"
+ hashlib_codecs:
+ dependency: transitive
+ description:
+ name: hashlib_codecs
+ sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.0"
http:
dependency: transitive
description:
@@ -308,12 +324,11 @@ packages:
polyseed:
dependency: transitive
description:
- path: "."
- ref: HEAD
- resolved-ref: "504d58a5b147fccd3bc85a25f2e72fb32771ddd7"
- url: "https://github.com/cake-tech/polyseed_dart.git"
- source: git
- version: "0.0.1"
+ name: polyseed
+ sha256: "9b48ec535b10863f78f6354ec983b4cc0c88ca69ff48fee469d0fd1954b01d4f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.2"
process:
dependency: transitive
description:
@@ -383,15 +398,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.1"
- tor:
- dependency: transitive
- description:
- path: "."
- ref: main
- resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
- url: "https://github.com/cake-tech/tor.git"
- source: git
- version: "0.0.1"
typed_data:
dependency: transitive
description:
diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp
index 7ad873647..87be785ac 100644
--- a/cw_monero/ios/Classes/monero_api.cpp
+++ b/cw_monero/ios/Classes/monero_api.cpp
@@ -385,6 +385,9 @@ extern "C"
(uint64_t)restoreHeight,
std::string(spendKey));
+ // Cache Raw to support Polyseed
+ wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
+
int status;
std::string errorString;
@@ -396,9 +399,6 @@ extern "C"
return false;
}
- // Cache Raw to support Polyseed
- wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
-
change_current_wallet(wallet);
return true;
}
@@ -926,6 +926,8 @@ extern "C"
return m_wallet->trustedDaemon();
}
+ // Coin Control //
+
CoinsInfoRow* coin(int index)
{
if (index >= 0 && index < m_coins_info.size()) {
@@ -1020,6 +1022,13 @@ extern "C"
m_coins->thaw(index);
}
+ // Sign Messages //
+
+ char *sign_message(char *message, char *address = "")
+ {
+ return strdup(get_current_wallet()->signMessage(std::string(message), std::string(address)).c_str());
+ }
+
#ifdef __cplusplus
}
#endif
diff --git a/cw_monero/ios/Classes/monero_api.h b/cw_monero/ios/Classes/monero_api.h
index 74258ba4c..fa92a038d 100644
--- a/cw_monero/ios/Classes/monero_api.h
+++ b/cw_monero/ios/Classes/monero_api.h
@@ -32,7 +32,8 @@ void store(char *path);
void set_trusted_daemon(bool arg);
bool trusted_daemon();
+char *sign_message(char *message, char *address);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/cw_monero/lib/api/signatures.dart b/cw_monero/lib/api/signatures.dart
index 17099db91..bc4fc9d38 100644
--- a/cw_monero/lib/api/signatures.dart
+++ b/cw_monero/lib/api/signatures.dart
@@ -149,3 +149,5 @@ typedef coin = Pointer Function(Int32 index);
typedef freeze_coin = Void Function(Int32 index);
typedef thaw_coin = Void Function(Int32 index);
+
+typedef sign_message = Pointer Function(Pointer message, Pointer address);
diff --git a/cw_monero/lib/api/types.dart b/cw_monero/lib/api/types.dart
index 1d3904870..40a1e0321 100644
--- a/cw_monero/lib/api/types.dart
+++ b/cw_monero/lib/api/types.dart
@@ -149,3 +149,5 @@ typedef GetCoin = Pointer Function(int);
typedef FreezeCoin = void Function(int);
typedef ThawCoin = void Function(int);
+
+typedef SignMessage = Pointer Function(Pointer, Pointer);
diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart
index 1680918e5..ffa5fe13b 100644
--- a/cw_monero/lib/api/wallet.dart
+++ b/cw_monero/lib/api/wallet.dart
@@ -8,7 +8,6 @@ import 'package:cw_monero/api/types.dart';
import 'package:cw_monero/api/monero_api.dart';
import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart';
import 'package:flutter/foundation.dart';
-import 'package:flutter/services.dart';
int _boolToInt(bool value) => value ? 1 : 0;
@@ -128,6 +127,10 @@ final trustedDaemonNative = moneroApi
.lookup>('trusted_daemon')
.asFunction();
+final signMessageNative = moneroApi
+ .lookup>('sign_message')
+ .asFunction();
+
int getSyncingHeight() => getSyncingHeightNative();
bool isNeededToRefresh() => isNeededToRefreshNative() != 0;
@@ -296,7 +299,7 @@ class SyncListener {
final bchHeight = await getNodeHeightOrUpdate(syncHeight);
- if (_lastKnownBlockHeight == syncHeight || syncHeight == null) {
+ if (_lastKnownBlockHeight == syncHeight) {
return;
}
@@ -311,7 +314,7 @@ class SyncListener {
}
// 1. Actual new height; 2. Blocks left to finish; 3. Progress in percents;
- onNewBlock?.call(syncHeight, left, ptc);
+ onNewBlock.call(syncHeight, left, ptc);
});
}
@@ -382,4 +385,15 @@ String getSubaddressLabel(int accountIndex, int addressIndex) {
Future setTrustedDaemon(bool trusted) async => setTrustedDaemonNative(_boolToInt(trusted));
-Future trustedDaemon() async => trustedDaemonNative() != 0;
\ No newline at end of file
+Future trustedDaemon() async => trustedDaemonNative() != 0;
+
+String signMessage(String message, {String address = ""}) {
+ final messagePointer = message.toNativeUtf8();
+ final addressPointer = address.toNativeUtf8();
+
+ final signature = convertUTF8ToString(pointer: signMessageNative(messagePointer, addressPointer));
+ calloc.free(messagePointer);
+ calloc.free(addressPointer);
+
+ return signature;
+}
diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart
index 260b420c5..0aa694e9a 100644
--- a/cw_monero/lib/api/wallet_manager.dart
+++ b/cw_monero/lib/api/wallet_manager.dart
@@ -1,14 +1,16 @@
import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-import 'package:flutter/foundation.dart';
+
import 'package:cw_monero/api/convert_utf8_to_string.dart';
-import 'package:cw_monero/api/signatures.dart';
-import 'package:cw_monero/api/types.dart';
-import 'package:cw_monero/api/monero_api.dart';
-import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
import 'package:cw_monero/api/exceptions/wallet_creation_exception.dart';
+import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart';
import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart';
+import 'package:cw_monero/api/monero_api.dart';
+import 'package:cw_monero/api/signatures.dart';
+import 'package:cw_monero/api/types.dart';
+import 'package:cw_monero/api/wallet.dart';
+import 'package:ffi/ffi.dart';
+import 'package:flutter/foundation.dart';
final createWalletNative = moneroApi
.lookup>('create_wallet')
@@ -175,6 +177,8 @@ void restoreWalletFromSpendKeySync(
calloc.free(languagePointer);
calloc.free(spendKeyPointer);
+ storeSync();
+
if (!isWalletRestored) {
throw WalletRestoreFromKeysException(
message: convertUTF8ToString(pointer: errorMessagePointer));
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 71c7e3967..4b71fb5ff 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -651,4 +651,10 @@ abstract class MoneroWalletBase
@override
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError;
+
+ @override
+ String signMessage(String message, {String? address}) {
+ final useAddress = address ?? "";
+ return monero_wallet.signMessage(message, address: useAddress);
+ }
}
diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart
index 8e9eb6eac..9b9e254d0 100644
--- a/cw_monero/lib/monero_wallet_service.dart
+++ b/cw_monero/lib/monero_wallet_service.dart
@@ -13,7 +13,6 @@ import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
import 'package:cw_monero/monero_wallet.dart';
import 'package:hive/hive.dart';
import 'package:polyseed/polyseed.dart';
-import 'package:polyseed/src/utils/key_utils.dart';
class MoneroNewWalletCredentials extends WalletCredentials {
MoneroNewWalletCredentials({required String name, required this.language, required this.isPolyseed, String? password})
@@ -77,8 +76,12 @@ class MoneroWalletService extends WalletService<
final polyseed = Polyseed.create();
final lang = PolyseedLang.getByEnglishName(credentials.language);
+ final heightOverride =
+ getMoneroHeigthByDate(date: DateTime.now().subtract(Duration(days: 2)));
+
return _restoreFromPolyseed(
- path, credentials.password!, polyseed, credentials.walletInfo!, lang);
+ path, credentials.password!, polyseed, credentials.walletInfo!, lang,
+ overrideHeight: heightOverride);
}
await monero_wallet_manager.createWallet(
@@ -268,18 +271,23 @@ class MoneroWalletService extends WalletService<
Future _restoreFromPolyseed(String path, String password, Polyseed polyseed,
WalletInfo walletInfo, PolyseedLang lang,
- {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO}) async {
- final height = getMoneroHeigthByDate(
+ {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO, int? overrideHeight}) async {
+ final height = overrideHeight ?? getMoneroHeigthByDate(
date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000));
- final spendKey = keyToHexString(polyseed.generateKey(coin, 32));
+ final spendKey = polyseed.generateKey(coin, 32).toHexString();
+ final seed = polyseed.encode(lang, coin);
+
+ walletInfo.isRecovery = true;
+ walletInfo.restoreHeight = height;
await monero_wallet_manager.restoreFromSpendKey(
path: path,
password: password,
- seed: polyseed.encode(lang, coin),
+ seed: seed,
language: lang.nameEnglish,
restoreHeight: height,
spendKey: spendKey);
+
final wallet = MoneroWallet(
walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
await wallet.init();
diff --git a/cw_monero/macos/Classes/monero_api.cpp b/cw_monero/macos/Classes/monero_api.cpp
index ac8a64861..fe75dea98 100644
--- a/cw_monero/macos/Classes/monero_api.cpp
+++ b/cw_monero/macos/Classes/monero_api.cpp
@@ -234,7 +234,6 @@ extern "C"
}
void setUnlocked(bool unlocked);
-
};
Monero::Coins *m_coins;
@@ -375,6 +374,35 @@ extern "C"
return true;
}
+ bool restore_wallet_from_spend_key(char *path, char *password, char *seed, char *language, char *spendKey, int32_t networkType, uint64_t restoreHeight, char *error)
+ {
+ Monero::NetworkType _networkType = static_cast(networkType);
+ Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->createDeterministicWalletFromSpendKey(
+ std::string(path),
+ std::string(password),
+ std::string(language),
+ _networkType,
+ (uint64_t)restoreHeight,
+ std::string(spendKey));
+
+ // Cache Raw to support Polyseed
+ wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
+
+ int status;
+ std::string errorString;
+
+ wallet->statusWithErrorString(status, errorString);
+
+ if (status != Monero::Wallet::Status_Ok || !errorString.empty())
+ {
+ error = strdup(errorString.c_str());
+ return false;
+ }
+
+ change_current_wallet(wallet);
+ return true;
+ }
+
bool load_wallet(char *path, char *password, int32_t nettype)
{
nice(19);
@@ -439,6 +467,11 @@ extern "C"
const char *seed()
{
+ std::string _rawSeed = get_current_wallet()->getCacheAttribute("cakewallet.seed");
+ if (!_rawSeed.empty())
+ {
+ return strdup(_rawSeed.c_str());
+ }
return strdup(get_current_wallet()->seed().c_str());
}
@@ -842,6 +875,12 @@ extern "C"
return m_transaction_history->count();
}
+ TransactionInfoRow* get_transaction(char * txId)
+ {
+ Monero::TransactionInfo *row = m_transaction_history->transaction(std::string(txId));
+ return new TransactionInfoRow(row);
+ }
+
int LedgerExchange(
unsigned char *command,
unsigned int cmd_len,
@@ -971,6 +1010,22 @@ extern "C"
return result;
}
+ void freeze_coin(int index)
+ {
+ m_coins->setFrozen(index);
+ }
+
+ void thaw_coin(int index)
+ {
+ m_coins->thaw(index);
+ }
+
+ // Sign Messages //
+
+ char *sign_message(char *message, char *address = "")
+ {
+ return strdup(get_current_wallet()->signMessage(std::string(message), std::string(address)).c_str());
+ }
#ifdef __cplusplus
}
diff --git a/cw_monero/macos/Classes/monero_api.h b/cw_monero/macos/Classes/monero_api.h
index 74258ba4c..fa92a038d 100644
--- a/cw_monero/macos/Classes/monero_api.h
+++ b/cw_monero/macos/Classes/monero_api.h
@@ -32,7 +32,8 @@ void store(char *path);
void set_trusted_daemon(bool arg);
bool trusted_daemon();
+char *sign_message(char *message, char *address);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
index 46ebe8028..0f8f2c90e 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -266,6 +266,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0"
+ hashlib:
+ dependency: transitive
+ description:
+ name: hashlib
+ sha256: "71bf102329ddb8e50c8a995ee4645ae7f1728bb65e575c17196b4d8262121a96"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.12.0"
+ hashlib_codecs:
+ dependency: transitive
+ description:
+ name: hashlib_codecs
+ sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.0"
hive:
dependency: transitive
description:
@@ -485,12 +501,11 @@ packages:
polyseed:
dependency: "direct main"
description:
- path: "."
- ref: HEAD
- resolved-ref: "504d58a5b147fccd3bc85a25f2e72fb32771ddd7"
- url: "https://github.com/cake-tech/polyseed_dart.git"
- source: git
- version: "0.0.1"
+ name: polyseed
+ sha256: "9b48ec535b10863f78f6354ec983b4cc0c88ca69ff48fee469d0fd1954b01d4f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.2"
pool:
dependency: transitive
description:
@@ -632,15 +647,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
- tor:
- dependency: transitive
- description:
- path: "."
- ref: main
- resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
- url: "https://github.com/cake-tech/tor.git"
- source: git
- version: "0.0.1"
typed_data:
dependency: transitive
description:
diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml
index 55e9b354c..a6fe7f967 100644
--- a/cw_monero/pubspec.yaml
+++ b/cw_monero/pubspec.yaml
@@ -19,9 +19,7 @@ dependencies:
flutter_mobx: ^2.0.6+1
intl: ^0.18.0
encrypt: ^5.0.1
- polyseed:
- git:
- url: https://github.com/cake-tech/polyseed_dart.git
+ polyseed: ^0.0.2
cw_core:
path: ../cw_core
diff --git a/cw_polygon/.gitignore b/cw_polygon/.gitignore
new file mode 100644
index 000000000..96486fd93
--- /dev/null
+++ b/cw_polygon/.gitignore
@@ -0,0 +1,30 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
+/pubspec.lock
+**/doc/api/
+.dart_tool/
+.packages
+build/
diff --git a/cw_polygon/.metadata b/cw_polygon/.metadata
new file mode 100644
index 000000000..fa347fc6a
--- /dev/null
+++ b/cw_polygon/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
+ channel: stable
+
+project_type: package
diff --git a/cw_polygon/CHANGELOG.md b/cw_polygon/CHANGELOG.md
new file mode 100644
index 000000000..41cc7d819
--- /dev/null
+++ b/cw_polygon/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.0.1
+
+* TODO: Describe initial release.
diff --git a/cw_polygon/LICENSE b/cw_polygon/LICENSE
new file mode 100644
index 000000000..ba75c69f7
--- /dev/null
+++ b/cw_polygon/LICENSE
@@ -0,0 +1 @@
+TODO: Add your license here.
diff --git a/cw_polygon/README.md b/cw_polygon/README.md
new file mode 100644
index 000000000..02fe8ecab
--- /dev/null
+++ b/cw_polygon/README.md
@@ -0,0 +1,39 @@
+
+
+TODO: Put a short description of the package here that helps potential users
+know whether this package might be useful for them.
+
+## Features
+
+TODO: List what your package can do. Maybe include images, gifs, or videos.
+
+## Getting started
+
+TODO: List prerequisites and provide or point to information on how to
+start using the package.
+
+## Usage
+
+TODO: Include short and useful examples for package users. Add longer examples
+to `/example` folder.
+
+```dart
+const like = 'sample';
+```
+
+## Additional information
+
+TODO: Tell users more about the package: where to find more information, how to
+contribute to the package, how to file issues, what response they can expect
+from the package authors, and more.
diff --git a/cw_polygon/analysis_options.yaml b/cw_polygon/analysis_options.yaml
new file mode 100644
index 000000000..a5744c1cf
--- /dev/null
+++ b/cw_polygon/analysis_options.yaml
@@ -0,0 +1,4 @@
+include: package:flutter_lints/flutter.yaml
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/cw_polygon/lib/cw_polygon.dart b/cw_polygon/lib/cw_polygon.dart
new file mode 100644
index 000000000..5d4e447d1
--- /dev/null
+++ b/cw_polygon/lib/cw_polygon.dart
@@ -0,0 +1,7 @@
+library cw_polygon;
+
+/// A Calculator.
+class Calculator {
+ /// Returns [value] plus 1.
+ int addOne(int value) => value + 1;
+}
diff --git a/cw_polygon/lib/default_polygon_erc20_tokens.dart b/cw_polygon/lib/default_polygon_erc20_tokens.dart
new file mode 100644
index 000000000..deff285c0
--- /dev/null
+++ b/cw_polygon/lib/default_polygon_erc20_tokens.dart
@@ -0,0 +1,82 @@
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/erc20_token.dart';
+
+class DefaultPolygonErc20Tokens {
+ final List _defaultTokens = [
+ Erc20Token(
+ name: "Wrapped Ether",
+ symbol: "WETH",
+ contractAddress: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
+ decimal: 18,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Tether USD (PoS)",
+ symbol: "USDT",
+ contractAddress: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
+ decimal: 6,
+ enabled: true,
+ ),
+ Erc20Token(
+ name: "USD Coin",
+ symbol: "USDC",
+ contractAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
+ decimal: 6,
+ enabled: true,
+ ),
+ Erc20Token(
+ name: "USD Coin (POS)",
+ symbol: "USDC.e",
+ contractAddress: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
+ decimal: 6,
+ enabled: true,
+ ),
+ Erc20Token(
+ name: "Avalanche Token",
+ symbol: "AVAX",
+ contractAddress: "0x2C89bbc92BD86F8075d1DEcc58C7F4E0107f286b",
+ decimal: 18,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Wrapped BTC (PoS)",
+ symbol: "WBTC",
+ contractAddress: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
+ decimal: 8,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Dai (PoS)",
+ symbol: "DAI",
+ contractAddress: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
+ decimal: 18,
+ enabled: true,
+ ),
+ Erc20Token(
+ name: "SHIBA INU (PoS)",
+ symbol: "SHIB",
+ contractAddress: "0x6f8a06447Ff6FcF75d803135a7de15CE88C1d4ec",
+ decimal: 18,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Uniswap (PoS)",
+ symbol: "UNI",
+ contractAddress: "0xb33EaAd8d922B1083446DC23f610c2567fB5180f",
+ decimal: 18,
+ enabled: false,
+ ),
+ ];
+
+ List get initialPolygonErc20Tokens => _defaultTokens.map((token) {
+ String? iconPath;
+ try {
+ iconPath = CryptoCurrency.all
+ .firstWhere((element) =>
+ element.title.toUpperCase() == token.symbol.split(".").first.toUpperCase())
+ .iconPath;
+ } catch (_) {}
+
+ return Erc20Token.copyWith(token, iconPath, 'POLY');
+ }).toList();
+}
diff --git a/cw_polygon/lib/pending_polygon_transaction.dart b/cw_polygon/lib/pending_polygon_transaction.dart
new file mode 100644
index 000000000..50f1f0638
--- /dev/null
+++ b/cw_polygon/lib/pending_polygon_transaction.dart
@@ -0,0 +1,19 @@
+import 'dart:typed_data';
+
+import 'package:cw_ethereum/pending_ethereum_transaction.dart';
+
+class PendingPolygonTransaction extends PendingEthereumTransaction {
+ PendingPolygonTransaction({
+ required Function sendTransaction,
+ required Uint8List signedTransaction,
+ required BigInt fee,
+ required String amount,
+ required int exponent,
+ }) : super(
+ amount: amount,
+ sendTransaction: sendTransaction,
+ signedTransaction: signedTransaction,
+ fee: fee,
+ exponent: exponent,
+ );
+}
diff --git a/cw_polygon/lib/polygon_client.dart b/cw_polygon/lib/polygon_client.dart
new file mode 100644
index 000000000..876f4c60d
--- /dev/null
+++ b/cw_polygon/lib/polygon_client.dart
@@ -0,0 +1,55 @@
+import 'dart:convert';
+
+import 'package:cw_ethereum/ethereum_client.dart';
+import 'package:cw_polygon/polygon_transaction_model.dart';
+import 'package:cw_ethereum/.secrets.g.dart' as secrets;
+import 'package:flutter/foundation.dart';
+import 'package:web3dart/web3dart.dart';
+
+class PolygonClient extends EthereumClient {
+ @override
+ Transaction createTransaction({
+ required EthereumAddress from,
+ required EthereumAddress to,
+ required EtherAmount amount,
+ EtherAmount? maxPriorityFeePerGas,
+ }) {
+ return Transaction(
+ from: from,
+ to: to,
+ value: amount,
+ );
+ }
+
+ @override
+ Uint8List prepareSignedTransactionForSending(Uint8List signedTransaction) => signedTransaction;
+
+ @override
+ int get chainId => 137;
+
+ @override
+ Future> fetchTransactions(String address,
+ {String? contractAddress}) async {
+ try {
+ final response = await httpClient.get(Uri.https("api.polygonscan.com", "/api", {
+ "module": "account",
+ "action": contractAddress != null ? "tokentx" : "txlist",
+ if (contractAddress != null) "contractaddress": contractAddress,
+ "address": address,
+ "apikey": secrets.polygonScanApiKey,
+ }));
+
+ final jsonResponse = json.decode(response.body) as Map;
+
+ if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0) {
+ return (jsonResponse['result'] as List)
+ .map((e) => PolygonTransactionModel.fromJson(e as Map))
+ .toList();
+ }
+
+ return [];
+ } catch (e) {
+ return [];
+ }
+ }
+}
diff --git a/cw_polygon/lib/polygon_exceptions.dart b/cw_polygon/lib/polygon_exceptions.dart
new file mode 100644
index 000000000..2d08106b6
--- /dev/null
+++ b/cw_polygon/lib/polygon_exceptions.dart
@@ -0,0 +1,6 @@
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_ethereum/ethereum_exceptions.dart';
+
+class PolygonTransactionCreationException extends EthereumTransactionCreationException {
+ PolygonTransactionCreationException(CryptoCurrency currency) : super(currency);
+}
diff --git a/cw_polygon/lib/polygon_formatter.dart b/cw_polygon/lib/polygon_formatter.dart
new file mode 100644
index 000000000..f016db7ab
--- /dev/null
+++ b/cw_polygon/lib/polygon_formatter.dart
@@ -0,0 +1,25 @@
+import 'package:intl/intl.dart';
+
+const polygonAmountLength = 12;
+const polygonAmountDivider = 1000000000000;
+final polygonAmountFormat = NumberFormat()
+ ..maximumFractionDigits = polygonAmountLength
+ ..minimumFractionDigits = 1;
+
+class PolygonFormatter {
+ static int parsePolygonAmount(String amount) {
+ try {
+ return (double.parse(amount) * polygonAmountDivider).round();
+ } catch (_) {
+ return 0;
+ }
+ }
+
+ static double parsePolygonAmountToDouble(int amount) {
+ try {
+ return amount / polygonAmountDivider;
+ } catch (_) {
+ return 0;
+ }
+ }
+}
diff --git a/cw_polygon/lib/polygon_mnemonics_exception.dart b/cw_polygon/lib/polygon_mnemonics_exception.dart
new file mode 100644
index 000000000..c1a2fcc84
--- /dev/null
+++ b/cw_polygon/lib/polygon_mnemonics_exception.dart
@@ -0,0 +1,5 @@
+class PolygonMnemonicIsIncorrectException implements Exception {
+ @override
+ String toString() =>
+ 'Polygon mnemonic has incorrect format. Mnemonic should contain 12 or 24 words separated by space.';
+}
diff --git a/cw_polygon/lib/polygon_transaction_credentials.dart b/cw_polygon/lib/polygon_transaction_credentials.dart
new file mode 100644
index 000000000..6611e15da
--- /dev/null
+++ b/cw_polygon/lib/polygon_transaction_credentials.dart
@@ -0,0 +1,18 @@
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/output_info.dart';
+import 'package:cw_ethereum/ethereum_transaction_credentials.dart';
+import 'package:cw_polygon/polygon_transaction_priority.dart';
+
+class PolygonTransactionCredentials extends EthereumTransactionCredentials {
+ PolygonTransactionCredentials(
+ List outputs, {
+ required PolygonTransactionPriority? priority,
+ required CryptoCurrency currency,
+ final int? feeRate,
+ }) : super(
+ outputs,
+ currency: currency,
+ priority: priority,
+ feeRate: feeRate,
+ );
+}
diff --git a/cw_polygon/lib/polygon_transaction_history.dart b/cw_polygon/lib/polygon_transaction_history.dart
new file mode 100644
index 000000000..a06b8be4a
--- /dev/null
+++ b/cw_polygon/lib/polygon_transaction_history.dart
@@ -0,0 +1,77 @@
+import 'dart:convert';
+import 'dart:core';
+import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/wallet_info.dart';
+import 'package:cw_ethereum/file.dart';
+import 'package:cw_polygon/polygon_transaction_info.dart';
+import 'package:mobx/mobx.dart';
+import 'package:cw_core/transaction_history.dart';
+
+part 'polygon_transaction_history.g.dart';
+
+const transactionsHistoryFileName = 'polygon_transactions.json';
+
+class PolygonTransactionHistory = PolygonTransactionHistoryBase with _$PolygonTransactionHistory;
+
+abstract class PolygonTransactionHistoryBase extends TransactionHistoryBase
+ with Store {
+ PolygonTransactionHistoryBase({required this.walletInfo, required String password})
+ : _password = password {
+ transactions = ObservableMap();
+ }
+
+ final WalletInfo walletInfo;
+ String _password;
+
+ Future init() async => await _load();
+
+ @override
+ Future save() async {
+ try {
+ final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
+ final path = '$dirPath/$transactionsHistoryFileName';
+ final data = json.encode({'transactions': transactions});
+ await writeData(path: path, password: _password, data: data);
+ } catch (e, s) {
+ print('Error while saving polygon transaction history: ${e.toString()}');
+ print(s);
+ }
+ }
+
+ @override
+ void addOne(PolygonTransactionInfo transaction) => transactions[transaction.id] = transaction;
+
+ @override
+ void addMany(Map transactions) =>
+ this.transactions.addAll(transactions);
+
+ Future