diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 88dd2c1eb..4df215e13 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -6,9 +6,9 @@ on:
workflow_dispatch:
inputs:
branch:
- description: 'Branch name to build'
+ description: "Branch name to build"
required: true
- default: 'main'
+ default: "main"
jobs:
PR_test_build:
@@ -104,22 +104,14 @@ jobs:
- name: Build generated code
run: |
cd /opt/android/cake_wallet
- cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
- cd cw_evm && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
- cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
- cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
- cd cw_haven && 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_ethereum && flutter pub get && cd ..
- cd cw_polygon && flutter pub get && cd ..
- flutter packages pub run build_runner build --delete-conflicting-outputs
+ ./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
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
@@ -154,45 +146,50 @@ jobs:
echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+ echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
- name: Rename app
- run: echo -e "id=com.cakewallet.test\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+ run: |
+ hash=`sha512sum <<<"${{ env.BRANCH_NAME }}"`
+ substring=${hash:0:15}
+ echo substring
+ echo -e "id=com.cakewallet.test_$(substring)\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
- name: Build
run: |
cd /opt/android/cake_wallet
- flutter build apk --release
+ flutter build apk --release --split-per-abi
-# - name: Push to App Center
-# run: |
-# echo 'Installing App Center CLI tools'
-# npm install -g appcenter-cli
-# echo "Publishing test to App Center"
-# appcenter distribute release \
-# --group "Testers" \
-# --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \
-# --release-notes ${{ env.BRANCH_NAME }} \
-# --app Cake-Labs/Cake-Wallet \
-# --token ${{ secrets.APP_CENTER_TOKEN }} \
-# --quiet
+ # - name: Push to App Center
+ # run: |
+ # echo 'Installing App Center CLI tools'
+ # npm install -g appcenter-cli
+ # echo "Publishing test to App Center"
+ # appcenter distribute release \
+ # --group "Testers" \
+ # --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \
+ # --release-notes ${{ env.BRANCH_NAME }} \
+ # --app Cake-Labs/Cake-Wallet \
+ # --token ${{ secrets.APP_CENTER_TOKEN }} \
+ # --quiet
- name: Rename apk file
run: |
- cd /opt/android/cake_wallet/build/app/outputs/apk/release
+ cd /opt/android/cake_wallet/build/app/outputs/flutter-apk
mkdir test-apk
- cp app-release.apk test-apk/${{env.BRANCH_NAME}}.apk
+ cp app-arm64-v8a-release.apk test-apk/${{env.BRANCH_NAME}}.apk
- name: Upload Artifact
uses: kittaakos/upload-artifact-as-is@v0
with:
- path: /opt/android/cake_wallet/build/app/outputs/apk/release/test-apk/
+ path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/
- 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/app/outputs/apk/release/app-release.apk
+ path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/${{env.BRANCH_NAME}}.apk
channel: ${{ secrets.SLACK_APK_CHANNEL }}
title: "${{ env.BRANCH_NAME }}.apk"
filename: ${{ env.BRANCH_NAME }}.apk
diff --git a/.gitignore b/.gitignore
index f084f8d0d..6f2d0a182 100644
--- a/.gitignore
+++ b/.gitignore
@@ -86,14 +86,17 @@ cw_monero/cw_monero/android/.cxx/
**/*.g.dart
android/key.properties
+android/app/key.jks
**/tool/.secrets-prod.json
**/tool/.secrets-test.json
**/tool/.secrets-config.json
**/tool/.evm-secrets-config.json
**/tool/.ethereum-secrets-config.json
+**/tool/.solana-secrets-config.json
**/lib/.secrets.g.dart
**/cw_evm/lib/.secrets.g.dart
+**/cw_solana/lib/.secrets.g.dart
vendor/
@@ -128,6 +131,7 @@ lib/ethereum/ethereum.dart
lib/bitcoin_cash/bitcoin_cash.dart
lib/nano/nano.dart
lib/polygon/polygon.dart
+lib/solana/solana.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 180190914..eea9b5521 100644
--- a/android/app/src/main/AndroidManifestBase.xml
+++ b/android/app/src/main/AndroidManifestBase.xml
@@ -66,6 +66,7 @@
+
[OPS['OP_HASH160'], hash, OPS['OP_EQUAL']]);
-}
-
-Uint8List addressToOutputScript(
- String address, bitcoin.NetworkType networkType) {
+List addressToOutputScript(String address, bitcoin.BasedUtxoNetwork network) {
try {
- // FIXME: improve validation for p2sh addresses
- // 3 for bitcoin
- // m for litecoin
- if (address.startsWith('3') || address.toLowerCase().startsWith('m')) {
- return p2shAddressToOutputScript(address);
- }
-
- return Address.addressToOutputScript(address, networkType);
+ 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 676edb4a5..d8d908230 100644
--- a/cw_bitcoin/lib/bitcoin_address_record.dart
+++ b/cw_bitcoin/lib/bitcoin_address_record.dart
@@ -1,6 +1,9 @@
import 'dart:convert';
import 'package:bitbox/bitbox.dart' as bitbox;
+import 'package:bitcoin_base/bitcoin_base.dart';
+import 'package:cw_bitcoin/script_hash.dart' as sh;
+
class BitcoinAddressRecord {
BitcoinAddressRecord(
this.address, {
@@ -10,23 +13,41 @@ class BitcoinAddressRecord {
int balance = 0,
String name = '',
bool isUsed = false,
+ required this.type,
+ String? scriptHash,
+ required this.network,
}) : _txCount = txCount,
_balance = balance,
_name = name,
- _isUsed = isUsed;
+ _isUsed = isUsed,
+ scriptHash =
+ scriptHash ?? (network != null ? sh.scriptHash(address, network: network) : null);
- factory BitcoinAddressRecord.fromJSON(String jsonSource) {
+ factory BitcoinAddressRecord.fromJSON(String jsonSource, BasedUtxoNetwork? network) {
final decoded = json.decode(jsonSource) as Map;
- return BitcoinAddressRecord(decoded['address'] as String,
- index: decoded['index'] as int,
- isHidden: decoded['isHidden'] as bool? ?? false,
- isUsed: decoded['isUsed'] as bool? ?? false,
- txCount: decoded['txCount'] as int? ?? 0,
- name: decoded['name'] as String? ?? '',
- balance: decoded['balance'] as int? ?? 0);
+ return BitcoinAddressRecord(
+ decoded['address'] as String,
+ index: decoded['index'] as int,
+ isHidden: decoded['isHidden'] as bool? ?? false,
+ isUsed: decoded['isUsed'] as bool? ?? false,
+ txCount: decoded['txCount'] as int? ?? 0,
+ name: decoded['name'] as String? ?? '',
+ balance: decoded['balance'] as int? ?? 0,
+ type: decoded['type'] != null && decoded['type'] != ''
+ ? BitcoinAddressType.values
+ .firstWhere((type) => type.toString() == decoded['type'] as String)
+ : SegwitAddresType.p2wpkh,
+ scriptHash: decoded['scriptHash'] as String?,
+ network: (decoded['network'] as String?) == null
+ ? network
+ : BasedUtxoNetwork.fromName(decoded['network'] as String),
+ );
}
+ @override
+ bool operator ==(Object o) => o is BitcoinAddressRecord && address == o.address;
+
final String address;
bool isHidden;
final int index;
@@ -34,6 +55,8 @@ class BitcoinAddressRecord {
int _balance;
String _name;
bool _isUsed;
+ String? scriptHash;
+ BasedUtxoNetwork? network;
int get txCount => _txCount;
@@ -50,21 +73,28 @@ class BitcoinAddressRecord {
void setAsUsed() => _isUsed = true;
void setNewName(String label) => _name = label;
- @override
- bool operator ==(Object o) => o is BitcoinAddressRecord && address == o.address;
-
@override
int get hashCode => address.hashCode;
String get cashAddr => bitbox.Address.toCashAddress(address);
+ BitcoinAddressType type;
+
+ String updateScriptHash(BasedUtxoNetwork network) {
+ scriptHash = sh.scriptHash(address, network: network);
+ return scriptHash!;
+ }
+
String toJSON() => json.encode({
'address': address,
'index': index,
'isHidden': isHidden,
+ 'isUsed': isUsed,
'txCount': txCount,
'name': name,
- 'isUsed': isUsed,
'balance': balance,
+ 'type': type.toString(),
+ 'scriptHash': scriptHash,
+ 'network': network?.value,
});
}
diff --git a/cw_bitcoin/lib/bitcoin_receive_page_option.dart b/cw_bitcoin/lib/bitcoin_receive_page_option.dart
new file mode 100644
index 000000000..2d2339a41
--- /dev/null
+++ b/cw_bitcoin/lib/bitcoin_receive_page_option.dart
@@ -0,0 +1,42 @@
+import 'package:bitcoin_base/bitcoin_base.dart';
+import 'package:cw_core/receive_page_option.dart';
+
+class BitcoinReceivePageOption implements ReceivePageOption {
+ static const p2wpkh = BitcoinReceivePageOption._('Segwit (P2WPKH) (Default)');
+ static const p2sh = BitcoinReceivePageOption._('Segwit-Compatible (P2SH)');
+ static const p2tr = BitcoinReceivePageOption._('Taproot (P2TR)');
+ static const p2wsh = BitcoinReceivePageOption._('Segwit (P2WSH)');
+ static const p2pkh = BitcoinReceivePageOption._('Legacy (P2PKH)');
+
+ const BitcoinReceivePageOption._(this.value);
+
+ final String value;
+
+ String toString() {
+ return value;
+ }
+
+ static const all = [
+ BitcoinReceivePageOption.p2wpkh,
+ BitcoinReceivePageOption.p2tr,
+ BitcoinReceivePageOption.p2wsh,
+ BitcoinReceivePageOption.p2sh,
+ BitcoinReceivePageOption.p2pkh
+ ];
+
+ factory BitcoinReceivePageOption.fromType(BitcoinAddressType type) {
+ switch (type) {
+ case SegwitAddresType.p2tr:
+ return BitcoinReceivePageOption.p2tr;
+ case SegwitAddresType.p2wsh:
+ return BitcoinReceivePageOption.p2wsh;
+ case P2pkhAddressType.p2pkh:
+ return BitcoinReceivePageOption.p2pkh;
+ case P2shAddressType.p2wpkhInP2sh:
+ return BitcoinReceivePageOption.p2sh;
+ case SegwitAddresType.p2wpkh:
+ default:
+ return BitcoinReceivePageOption.p2wpkh;
+ }
+ }
+}
diff --git a/cw_bitcoin/lib/bitcoin_unspent.dart b/cw_bitcoin/lib/bitcoin_unspent.dart
index 9c198c27c..52edea091 100644
--- a/cw_bitcoin/lib/bitcoin_unspent.dart
+++ b/cw_bitcoin/lib/bitcoin_unspent.dart
@@ -6,10 +6,9 @@ class BitcoinUnspent extends Unspent {
: bitcoinAddressRecord = addressRecord,
super(addressRecord.address, hash, value, vout, null);
- factory BitcoinUnspent.fromJSON(
- BitcoinAddressRecord address, Map json) =>
- BitcoinUnspent(address, json['tx_hash'] as String, json['value'] as int,
- json['tx_pos'] as int);
+ factory BitcoinUnspent.fromJSON(BitcoinAddressRecord address, Map json) =>
+ BitcoinUnspent(
+ address, json['tx_hash'] as String, json['value'] as int, json['tx_pos'] as int);
final BitcoinAddressRecord bitcoinAddressRecord;
}
diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index 9cdb78f2d..3b3e9c636 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -1,3 +1,4 @@
+import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/unspent_coins_info.dart';
@@ -17,36 +18,42 @@ part 'bitcoin_wallet.g.dart';
class BitcoinWallet = BitcoinWalletBase with _$BitcoinWallet;
abstract class BitcoinWalletBase extends ElectrumWallet with Store {
- BitcoinWalletBase(
- {required String mnemonic,
- required String password,
- required WalletInfo walletInfo,
- required Box unspentCoinsInfo,
- required Uint8List seedBytes,
- List? initialAddresses,
- ElectrumBalance? initialBalance,
- int initialRegularAddressIndex = 0,
- int initialChangeAddressIndex = 0})
- : super(
+ BitcoinWalletBase({
+ required String mnemonic,
+ required String password,
+ required WalletInfo walletInfo,
+ required Box unspentCoinsInfo,
+ required Uint8List seedBytes,
+ String? addressPageType,
+ BasedUtxoNetwork? networkParam,
+ List? initialAddresses,
+ ElectrumBalance? initialBalance,
+ Map? initialRegularAddressIndex,
+ Map? initialChangeAddressIndex,
+ }) : super(
mnemonic: mnemonic,
password: password,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo,
- networkType: bitcoin.bitcoin,
+ networkType: networkParam == null
+ ? bitcoin.bitcoin
+ : networkParam == BitcoinNetwork.mainnet
+ ? bitcoin.bitcoin
+ : bitcoin.testnet,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: seedBytes,
currency: CryptoCurrency.btc) {
walletAddresses = BitcoinWalletAddresses(
- walletInfo,
- electrumClient: electrumClient,
- initialAddresses: initialAddresses,
- initialRegularAddressIndex: initialRegularAddressIndex,
- initialChangeAddressIndex: initialChangeAddressIndex,
- mainHd: hd,
- sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
- .derivePath("m/0'/1"),
- networkType: networkType);
+ walletInfo,
+ electrumClient: electrumClient,
+ initialAddresses: initialAddresses,
+ initialRegularAddressIndex: initialRegularAddressIndex,
+ initialChangeAddressIndex: initialChangeAddressIndex,
+ mainHd: hd,
+ sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath("m/0'/1"),
+ network: networkParam ?? network,
+ );
autorun((_) {
this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress;
});
@@ -57,21 +64,26 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required String password,
required WalletInfo walletInfo,
required Box unspentCoinsInfo,
+ String? addressPageType,
+ BasedUtxoNetwork? network,
List? initialAddresses,
ElectrumBalance? initialBalance,
- int initialRegularAddressIndex = 0,
- int initialChangeAddressIndex = 0
+ Map? initialRegularAddressIndex,
+ Map? initialChangeAddressIndex,
}) async {
return BitcoinWallet(
- mnemonic: mnemonic,
- password: password,
- walletInfo: walletInfo,
- unspentCoinsInfo: unspentCoinsInfo,
- initialAddresses: initialAddresses,
- initialBalance: initialBalance,
- seedBytes: await mnemonicToSeedBytes(mnemonic),
- initialRegularAddressIndex: initialRegularAddressIndex,
- initialChangeAddressIndex: initialChangeAddressIndex);
+ mnemonic: mnemonic,
+ password: password,
+ walletInfo: walletInfo,
+ unspentCoinsInfo: unspentCoinsInfo,
+ initialAddresses: initialAddresses,
+ initialBalance: initialBalance,
+ seedBytes: await mnemonicToSeedBytes(mnemonic),
+ initialRegularAddressIndex: initialRegularAddressIndex,
+ initialChangeAddressIndex: initialChangeAddressIndex,
+ addressPageType: addressPageType,
+ networkParam: network,
+ );
}
static Future open({
@@ -80,16 +92,21 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required Box unspentCoinsInfo,
required String password,
}) async {
- final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
+ final snp = await ElectrumWalletSnapshot.load(name, walletInfo.type, password,
+ walletInfo.network != null ? BasedUtxoNetwork.fromName(walletInfo.network!) : null);
+
return BitcoinWallet(
- mnemonic: snp.mnemonic,
- password: password,
- walletInfo: walletInfo,
- unspentCoinsInfo: unspentCoinsInfo,
- initialAddresses: snp.addresses,
- initialBalance: snp.balance,
- seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
- initialRegularAddressIndex: snp.regularAddressIndex,
- initialChangeAddressIndex: snp.changeAddressIndex);
+ mnemonic: snp.mnemonic,
+ password: password,
+ walletInfo: walletInfo,
+ unspentCoinsInfo: unspentCoinsInfo,
+ initialAddresses: snp.addresses,
+ initialBalance: snp.balance,
+ seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
+ initialRegularAddressIndex: snp.regularAddressIndex,
+ initialChangeAddressIndex: snp.changeAddressIndex,
+ addressPageType: snp.addressPageType,
+ networkParam: snp.network,
+ );
}
-}
\ No newline at end of file
+}
diff --git a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
index 36d37127d..f12577492 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
@@ -1,6 +1,5 @@
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
-import 'package:cw_bitcoin/bitcoin_address_record.dart';
-import 'package:cw_bitcoin/electrum.dart';
+import 'package:bitcoin_base/bitcoin_base.dart';
+import 'package:bitcoin_flutter/bitcoin_flutter.dart';
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
import 'package:cw_bitcoin/utils.dart';
import 'package:cw_core/wallet_info.dart';
@@ -11,24 +10,31 @@ part 'bitcoin_wallet_addresses.g.dart';
class BitcoinWalletAddresses = BitcoinWalletAddressesBase with _$BitcoinWalletAddresses;
abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with Store {
- BitcoinWalletAddressesBase(WalletInfo walletInfo,
- {required bitcoin.HDWallet mainHd,
- required bitcoin.HDWallet sideHd,
- required bitcoin.NetworkType networkType,
- required ElectrumClient electrumClient,
- List? initialAddresses,
- int initialRegularAddressIndex = 0,
- int initialChangeAddressIndex = 0})
- : super(walletInfo,
- initialAddresses: initialAddresses,
- initialRegularAddressIndex: initialRegularAddressIndex,
- initialChangeAddressIndex: initialChangeAddressIndex,
- mainHd: mainHd,
- sideHd: sideHd,
- electrumClient: electrumClient,
- networkType: networkType);
+ BitcoinWalletAddressesBase(
+ WalletInfo walletInfo, {
+ required super.mainHd,
+ required super.sideHd,
+ required super.network,
+ required super.electrumClient,
+ super.initialAddresses,
+ super.initialRegularAddressIndex,
+ super.initialChangeAddressIndex,
+ }) : super(walletInfo);
@override
- String getAddress({required int index, required bitcoin.HDWallet hd}) =>
- generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
+ String getAddress({required int index, required HDWallet hd, BitcoinAddressType? addressType}) {
+ if (addressType == P2pkhAddressType.p2pkh)
+ return generateP2PKHAddress(hd: hd, index: index, network: network);
+
+ if (addressType == SegwitAddresType.p2tr)
+ return generateP2TRAddress(hd: hd, index: index, network: network);
+
+ if (addressType == SegwitAddresType.p2wsh)
+ return generateP2WSHAddress(hd: hd, index: index, network: network);
+
+ if (addressType == P2shAddressType.p2wpkhInP2sh)
+ return generateP2SHAddress(hd: hd, index: index, network: network);
+
+ return generateP2WPKHAddress(hd: hd, index: index, network: network);
+ }
}
diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart
index 736ec1044..38e769d15 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart
@@ -1,6 +1,7 @@
import 'dart:io';
+import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
-import 'package:cw_bitcoin/bitcoin_mnemonic_is_incorrect_exception.dart';
+import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart';
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
@@ -23,12 +24,17 @@ class BitcoinWalletService extends WalletService WalletType.bitcoin;
@override
- Future create(BitcoinNewWalletCredentials credentials) async {
+ Future create(BitcoinNewWalletCredentials credentials, {bool? isTestnet}) async {
+ final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet;
+ credentials.walletInfo?.network = network.value;
+
final wallet = await BitcoinWalletBase.create(
- mnemonic: await generateMnemonic(),
- password: credentials.password!,
- walletInfo: credentials.walletInfo!,
- unspentCoinsInfo: unspentCoinsInfoSource);
+ mnemonic: await generateMnemonic(),
+ password: credentials.password!,
+ walletInfo: credentials.walletInfo!,
+ unspentCoinsInfo: unspentCoinsInfoSource,
+ network: network,
+ );
await wallet.save();
await wallet.init();
return wallet;
@@ -92,20 +98,27 @@ class BitcoinWalletService extends WalletService restoreFromKeys(BitcoinRestoreWalletFromWIFCredentials credentials) async =>
+ Future restoreFromKeys(BitcoinRestoreWalletFromWIFCredentials credentials,
+ {bool? isTestnet}) async =>
throw UnimplementedError();
@override
- Future restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials) async {
+ Future restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials,
+ {bool? isTestnet}) async {
if (!validateMnemonic(credentials.mnemonic)) {
throw BitcoinMnemonicIsIncorrectException();
}
+ final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet;
+ credentials.walletInfo?.network = network.value;
+
final wallet = await BitcoinWalletBase.create(
- password: credentials.password!,
- mnemonic: credentials.mnemonic,
- walletInfo: credentials.walletInfo!,
- unspentCoinsInfo: unspentCoinsInfoSource);
+ password: credentials.password!,
+ mnemonic: credentials.mnemonic,
+ walletInfo: credentials.walletInfo!,
+ unspentCoinsInfo: unspentCoinsInfoSource,
+ network: network,
+ );
await wallet.save();
await wallet.init();
return wallet;
diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index a05c251fe..51a53e285 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -2,12 +2,12 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart';
+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';
-import 'package:collection/collection.dart';
+import 'package:http/http.dart' as http;
String jsonrpcparams(List