diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index acaa12fe0..b4ddcfefe 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -42,7 +42,7 @@ jobs:
- name: Flutter action
uses: subosito/flutter-action@v1
with:
- flutter-version: "3.19.5"
+ flutter-version: "3.19.6"
channel: stable
- name: Install package dependencies
diff --git a/assets/images/cards.svg b/assets/images/cards.svg
new file mode 100644
index 000000000..699f9d311
--- /dev/null
+++ b/assets/images/cards.svg
@@ -0,0 +1,65 @@
+
+
+
+
diff --git a/assets/images/tbtc.png b/assets/images/tbtc.png
new file mode 100644
index 000000000..bd4323edf
Binary files /dev/null and b/assets/images/tbtc.png differ
diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt
index 483f249cf..557dd8b26 100644
--- a/assets/text/Release_Notes.txt
+++ b/assets/text/Release_Notes.txt
@@ -1,3 +1,2 @@
-Add Tron wallet
-Hardware wallets enhancements
-Bug fixes
\ No newline at end of file
+Bitcoin Silent Payments
+Bug fixes and generic enhancements
diff --git a/cw_bitcoin/lib/bitcoin_address_record.dart b/cw_bitcoin/lib/bitcoin_address_record.dart
index d1c3b6a61..bf36e6fb9 100644
--- a/cw_bitcoin/lib/bitcoin_address_record.dart
+++ b/cw_bitcoin/lib/bitcoin_address_record.dart
@@ -3,8 +3,8 @@ import 'dart:convert';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/script_hash.dart' as sh;
-class BitcoinAddressRecord {
- BitcoinAddressRecord(
+abstract class BaseBitcoinAddressRecord {
+ BaseBitcoinAddressRecord(
this.address, {
required this.index,
this.isHidden = false,
@@ -13,15 +13,62 @@ class BitcoinAddressRecord {
String name = '',
bool isUsed = false,
required this.type,
- String? scriptHash,
required this.network,
}) : _txCount = txCount,
_balance = balance,
_name = name,
- _isUsed = isUsed,
- scriptHash = scriptHash ?? sh.scriptHash(address, network: network);
+ _isUsed = isUsed;
- factory BitcoinAddressRecord.fromJSON(String jsonSource, BasedUtxoNetwork network) {
+ @override
+ bool operator ==(Object o) => o is BaseBitcoinAddressRecord && address == o.address;
+
+ final String address;
+ bool isHidden;
+ final int index;
+ int _txCount;
+ int _balance;
+ String _name;
+ bool _isUsed;
+ BasedUtxoNetwork? network;
+
+ int get txCount => _txCount;
+
+ String get name => _name;
+
+ int get balance => _balance;
+
+ set txCount(int value) => _txCount = value;
+
+ set balance(int value) => _balance = value;
+
+ bool get isUsed => _isUsed;
+
+ void setAsUsed() => _isUsed = true;
+ void setNewName(String label) => _name = label;
+
+ int get hashCode => address.hashCode;
+
+ BitcoinAddressType type;
+
+ String toJSON();
+}
+
+class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
+ BitcoinAddressRecord(
+ super.address, {
+ required super.index,
+ super.isHidden = false,
+ super.txCount = 0,
+ super.balance = 0,
+ super.name = '',
+ super.isUsed = false,
+ required super.type,
+ String? scriptHash,
+ required super.network,
+ }) : scriptHash =
+ scriptHash ?? (network != null ? sh.scriptHash(address, network: network) : null);
+
+ factory BitcoinAddressRecord.fromJSON(String jsonSource, {BasedUtxoNetwork? network}) {
final decoded = json.decode(jsonSource) as Map;
return BitcoinAddressRecord(
@@ -41,44 +88,15 @@ class BitcoinAddressRecord {
);
}
- @override
- bool operator ==(Object o) => o is BitcoinAddressRecord && address == o.address;
-
- final String address;
- bool isHidden;
- final int index;
- int _txCount;
- int _balance;
- String _name;
- bool _isUsed;
String? scriptHash;
- BasedUtxoNetwork network;
- int get txCount => _txCount;
-
- String get name => _name;
-
- int get balance => _balance;
-
- set txCount(int value) => _txCount = value;
-
- set balance(int value) => _balance = value;
-
- bool get isUsed => _isUsed;
-
- void setAsUsed() => _isUsed = true;
- void setNewName(String label) => _name = label;
-
- @override
- int get hashCode => address.hashCode;
-
- BitcoinAddressType type;
-
- String updateScriptHash(BasedUtxoNetwork network) {
+ String getScriptHash(BasedUtxoNetwork network) {
+ if (scriptHash != null) return scriptHash!;
scriptHash = sh.scriptHash(address, network: network);
return scriptHash!;
}
+ @override
String toJSON() => json.encode({
'address': address,
'index': index,
@@ -91,3 +109,57 @@ class BitcoinAddressRecord {
'scriptHash': scriptHash,
});
}
+
+class BitcoinSilentPaymentAddressRecord extends BaseBitcoinAddressRecord {
+ BitcoinSilentPaymentAddressRecord(
+ super.address, {
+ required super.index,
+ super.isHidden = false,
+ super.txCount = 0,
+ super.balance = 0,
+ super.name = '',
+ super.isUsed = false,
+ required this.silentPaymentTweak,
+ required super.network,
+ required super.type,
+ }) : super();
+
+ factory BitcoinSilentPaymentAddressRecord.fromJSON(String jsonSource,
+ {BasedUtxoNetwork? network}) {
+ final decoded = json.decode(jsonSource) as Map;
+
+ return BitcoinSilentPaymentAddressRecord(
+ 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,
+ network: (decoded['network'] as String?) == null
+ ? network
+ : BasedUtxoNetwork.fromName(decoded['network'] as String),
+ silentPaymentTweak: decoded['silent_payment_tweak'] as String?,
+ type: decoded['type'] != null && decoded['type'] != ''
+ ? BitcoinAddressType.values
+ .firstWhere((type) => type.toString() == decoded['type'] as String)
+ : SilentPaymentsAddresType.p2sp,
+ );
+ }
+
+ final String? silentPaymentTweak;
+
+ @override
+ String toJSON() => json.encode({
+ 'address': address,
+ 'index': index,
+ 'isHidden': isHidden,
+ 'isUsed': isUsed,
+ 'txCount': txCount,
+ 'name': name,
+ 'balance': balance,
+ 'type': type.toString(),
+ 'network': network?.value,
+ 'silent_payment_tweak': silentPaymentTweak,
+ });
+}
diff --git a/cw_bitcoin/lib/bitcoin_receive_page_option.dart b/cw_bitcoin/lib/bitcoin_receive_page_option.dart
index 2d2339a41..aa3d4a4cd 100644
--- a/cw_bitcoin/lib/bitcoin_receive_page_option.dart
+++ b/cw_bitcoin/lib/bitcoin_receive_page_option.dart
@@ -8,6 +8,8 @@ class BitcoinReceivePageOption implements ReceivePageOption {
static const p2wsh = BitcoinReceivePageOption._('Segwit (P2WSH)');
static const p2pkh = BitcoinReceivePageOption._('Legacy (P2PKH)');
+ static const silent_payments = BitcoinReceivePageOption._('Silent Payments');
+
const BitcoinReceivePageOption._(this.value);
final String value;
@@ -17,6 +19,7 @@ class BitcoinReceivePageOption implements ReceivePageOption {
}
static const all = [
+ BitcoinReceivePageOption.silent_payments,
BitcoinReceivePageOption.p2wpkh,
BitcoinReceivePageOption.p2tr,
BitcoinReceivePageOption.p2wsh,
@@ -24,6 +27,24 @@ class BitcoinReceivePageOption implements ReceivePageOption {
BitcoinReceivePageOption.p2pkh
];
+ BitcoinAddressType toType() {
+ switch (this) {
+ case BitcoinReceivePageOption.p2tr:
+ return SegwitAddresType.p2tr;
+ case BitcoinReceivePageOption.p2wsh:
+ return SegwitAddresType.p2wsh;
+ case BitcoinReceivePageOption.p2pkh:
+ return P2pkhAddressType.p2pkh;
+ case BitcoinReceivePageOption.p2sh:
+ return P2shAddressType.p2wpkhInP2sh;
+ case BitcoinReceivePageOption.silent_payments:
+ return SilentPaymentsAddresType.p2sp;
+ case BitcoinReceivePageOption.p2wpkh:
+ default:
+ return SegwitAddresType.p2wpkh;
+ }
+ }
+
factory BitcoinReceivePageOption.fromType(BitcoinAddressType type) {
switch (type) {
case SegwitAddresType.p2tr:
@@ -34,6 +55,8 @@ class BitcoinReceivePageOption implements ReceivePageOption {
return BitcoinReceivePageOption.p2pkh;
case P2shAddressType.p2wpkhInP2sh:
return BitcoinReceivePageOption.p2sh;
+ case SilentPaymentsAddresType.p2sp:
+ return BitcoinReceivePageOption.silent_payments;
case SegwitAddresType.p2wpkh:
default:
return BitcoinReceivePageOption.p2wpkh;
diff --git a/cw_bitcoin/lib/bitcoin_unspent.dart b/cw_bitcoin/lib/bitcoin_unspent.dart
index 52edea091..3691a7a22 100644
--- a/cw_bitcoin/lib/bitcoin_unspent.dart
+++ b/cw_bitcoin/lib/bitcoin_unspent.dart
@@ -2,13 +2,66 @@ import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_core/unspent_transaction_output.dart';
class BitcoinUnspent extends Unspent {
- BitcoinUnspent(BitcoinAddressRecord addressRecord, String hash, int value, int vout)
+ BitcoinUnspent(BaseBitcoinAddressRecord addressRecord, String hash, int value, int vout)
: bitcoinAddressRecord = addressRecord,
super(addressRecord.address, hash, value, vout, null);
- factory BitcoinUnspent.fromJSON(BitcoinAddressRecord address, Map json) =>
+ factory BitcoinUnspent.fromJSON(BaseBitcoinAddressRecord? address, Map json) =>
BitcoinUnspent(
- address, json['tx_hash'] as String, json['value'] as int, json['tx_pos'] as int);
+ address ?? BitcoinAddressRecord.fromJSON(json['address_record'].toString()),
+ json['tx_hash'] as String,
+ json['value'] as int,
+ json['tx_pos'] as int,
+ );
- final BitcoinAddressRecord bitcoinAddressRecord;
+ Map toJson() {
+ final json = {
+ 'address_record': bitcoinAddressRecord.toJSON(),
+ 'tx_hash': hash,
+ 'value': value,
+ 'tx_pos': vout,
+ };
+ return json;
+ }
+
+ final BaseBitcoinAddressRecord bitcoinAddressRecord;
+}
+
+class BitcoinSilentPaymentsUnspent extends BitcoinUnspent {
+ BitcoinSilentPaymentsUnspent(
+ BitcoinSilentPaymentAddressRecord addressRecord,
+ String hash,
+ int value,
+ int vout, {
+ required this.silentPaymentTweak,
+ required this.silentPaymentLabel,
+ }) : super(addressRecord, hash, value, vout);
+
+ @override
+ factory BitcoinSilentPaymentsUnspent.fromJSON(
+ BitcoinSilentPaymentAddressRecord? address, Map json) =>
+ BitcoinSilentPaymentsUnspent(
+ address ?? BitcoinSilentPaymentAddressRecord.fromJSON(json['address_record'].toString()),
+ json['tx_hash'] as String,
+ json['value'] as int,
+ json['tx_pos'] as int,
+ silentPaymentTweak: json['silent_payment_tweak'] as String?,
+ silentPaymentLabel: json['silent_payment_label'] as String?,
+ );
+
+ @override
+ Map toJson() {
+ final json = {
+ 'address_record': bitcoinAddressRecord.toJSON(),
+ 'tx_hash': hash,
+ 'value': value,
+ 'tx_pos': vout,
+ 'silent_payment_tweak': silentPaymentTweak,
+ 'silent_payment_label': silentPaymentLabel,
+ };
+ return json;
+ }
+
+ String? silentPaymentTweak;
+ String? silentPaymentLabel;
}
diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index b02116541..3954631e8 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -39,22 +39,28 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
Map? initialRegularAddressIndex,
Map? initialChangeAddressIndex,
String? passphrase,
+ List? initialSilentAddresses,
+ int initialSilentAddressIndex = 0,
+ bool? alwaysScan,
}) : super(
- mnemonic: mnemonic,
- passphrase: passphrase,
- xpub: xpub,
- password: password,
- walletInfo: walletInfo,
- unspentCoinsInfo: unspentCoinsInfo,
- networkType: networkParam == null
- ? bitcoin.bitcoin
- : networkParam == BitcoinNetwork.mainnet
+ mnemonic: mnemonic,
+ passphrase: passphrase,
+ xpub: xpub,
+ password: password,
+ walletInfo: walletInfo,
+ unspentCoinsInfo: unspentCoinsInfo,
+ networkType: networkParam == null
? bitcoin.bitcoin
- : bitcoin.testnet,
- initialAddresses: initialAddresses,
- initialBalance: initialBalance,
- seedBytes: seedBytes,
- currency: CryptoCurrency.btc) {
+ : networkParam == BitcoinNetwork.mainnet
+ ? bitcoin.bitcoin
+ : bitcoin.testnet,
+ initialAddresses: initialAddresses,
+ initialBalance: initialBalance,
+ seedBytes: seedBytes,
+ currency:
+ networkParam == BitcoinNetwork.testnet ? CryptoCurrency.tbtc : CryptoCurrency.btc,
+ alwaysScan: alwaysScan,
+ ) {
// in a standard BIP44 wallet, mainHd derivation path = m/84'/0'/0'/0 (account 0, index unspecified here)
// the sideHd derivation path = m/84'/0'/0'/1 (account 1, index unspecified here)
// String derivationPath = walletInfo.derivationInfo!.derivationPath!;
@@ -62,14 +68,18 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
// final hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType);
walletAddresses = BitcoinWalletAddresses(
walletInfo,
- electrumClient: electrumClient,
initialAddresses: initialAddresses,
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex,
+ initialSilentAddresses: initialSilentAddresses,
+ initialSilentAddressIndex: initialSilentAddressIndex,
mainHd: hd,
sideHd: accountHD.derive(1),
network: networkParam ?? network,
+ masterHd:
+ seedBytes != null ? bitcoin.HDWallet.fromSeed(seedBytes, network: networkType) : null,
);
+
autorun((_) {
this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress;
});
@@ -84,9 +94,11 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
String? addressPageType,
BasedUtxoNetwork? network,
List? initialAddresses,
+ List? initialSilentAddresses,
ElectrumBalance? initialBalance,
Map? initialRegularAddressIndex,
Map? initialChangeAddressIndex,
+ int initialSilentAddressIndex = 0,
}) async {
late Uint8List seedBytes;
@@ -109,6 +121,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo,
initialAddresses: initialAddresses,
+ initialSilentAddresses: initialSilentAddresses,
+ initialSilentAddressIndex: initialSilentAddressIndex,
initialBalance: initialBalance,
seedBytes: seedBytes,
initialRegularAddressIndex: initialRegularAddressIndex,
@@ -123,6 +137,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required WalletInfo walletInfo,
required Box unspentCoinsInfo,
required String password,
+ required bool alwaysScan,
}) async {
final network = walletInfo.network != null
? BasedUtxoNetwork.fromName(walletInfo.network!)
@@ -163,12 +178,15 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo,
initialAddresses: snp.addresses,
+ initialSilentAddresses: snp.silentAddresses,
+ initialSilentAddressIndex: snp.silentAddressIndex,
initialBalance: snp.balance,
seedBytes: seedBytes,
initialRegularAddressIndex: snp.regularAddressIndex,
initialChangeAddressIndex: snp.changeAddressIndex,
addressPageType: snp.addressPageType,
networkParam: network,
+ alwaysScan: alwaysScan,
);
}
@@ -179,7 +197,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
void setLedger(Ledger setLedger, LedgerDevice setLedgerDevice) {
_ledger = setLedger;
_ledgerDevice = setLedgerDevice;
- _bitcoinLedgerApp = BitcoinLedgerApp(_ledger!, derivationPath: walletInfo.derivationInfo!.derivationPath!);
+ _bitcoinLedgerApp =
+ BitcoinLedgerApp(_ledger!, derivationPath: walletInfo.derivationInfo!.derivationPath!);
}
@override
@@ -202,16 +221,17 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
final publicKeyAndDerivationPath = publicKeys[utxo.ownerDetails.address.pubKeyHash()]!;
psbtReadyInputs.add(PSBTReadyUtxoWithAddress(
- utxo: utxo.utxo,
- rawTx: rawTx,
- ownerDetails: utxo.ownerDetails,
- ownerDerivationPath: publicKeyAndDerivationPath.derivationPath,
- ownerMasterFingerprint: masterFingerprint,
- ownerPublicKey: publicKeyAndDerivationPath.publicKey,
+ utxo: utxo.utxo,
+ rawTx: rawTx,
+ ownerDetails: utxo.ownerDetails,
+ ownerDerivationPath: publicKeyAndDerivationPath.derivationPath,
+ ownerMasterFingerprint: masterFingerprint,
+ ownerPublicKey: publicKeyAndDerivationPath.publicKey,
));
}
- final psbt = PSBTTransactionBuild(inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF);
+ final psbt =
+ PSBTTransactionBuild(inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF);
final rawHex = await _bitcoinLedgerApp!.signPsbt(_ledgerDevice!, psbt: psbt.psbt);
return BtcTransaction.fromRaw(hex.encode(rawHex));
diff --git a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
index f12577492..486e69b11 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
@@ -15,10 +15,12 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
required super.mainHd,
required super.sideHd,
required super.network,
- required super.electrumClient,
super.initialAddresses,
super.initialRegularAddressIndex,
super.initialChangeAddressIndex,
+ super.initialSilentAddresses,
+ super.initialSilentAddressIndex = 0,
+ super.masterHd,
}) : super(walletInfo);
@override
diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart
index cf99324da..a9a6d96db 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart
@@ -19,10 +19,11 @@ class BitcoinWalletService extends WalletService<
BitcoinRestoreWalletFromSeedCredentials,
BitcoinRestoreWalletFromWIFCredentials,
BitcoinRestoreWalletFromHardware> {
- BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
+ BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan);
final Box walletInfoSource;
final Box unspentCoinsInfoSource;
+ final bool alwaysScan;
@override
WalletType getType() => WalletType.bitcoin;
@@ -55,20 +56,24 @@ class BitcoinWalletService extends WalletService<
.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
try {
final wallet = await BitcoinWalletBase.open(
- password: password,
- name: name,
- walletInfo: walletInfo,
- unspentCoinsInfo: unspentCoinsInfoSource);
+ password: password,
+ name: name,
+ walletInfo: walletInfo,
+ unspentCoinsInfo: unspentCoinsInfoSource,
+ alwaysScan: alwaysScan,
+ );
await wallet.init();
saveBackup(name);
return wallet;
} catch (_) {
await restoreWalletFilesFromBackup(name);
final wallet = await BitcoinWalletBase.open(
- password: password,
- name: name,
- walletInfo: walletInfo,
- unspentCoinsInfo: unspentCoinsInfoSource);
+ password: password,
+ name: name,
+ walletInfo: walletInfo,
+ unspentCoinsInfo: unspentCoinsInfoSource,
+ alwaysScan: alwaysScan,
+ );
await wallet.init();
return wallet;
}
@@ -87,10 +92,12 @@ class BitcoinWalletService extends WalletService<
final currentWalletInfo = walletInfoSource.values
.firstWhereOrNull((info) => info.id == WalletBase.idFor(currentName, getType()))!;
final currentWallet = await BitcoinWalletBase.open(
- password: password,
- name: currentName,
- walletInfo: currentWalletInfo,
- unspentCoinsInfo: unspentCoinsInfoSource);
+ password: password,
+ name: currentName,
+ walletInfo: currentWalletInfo,
+ unspentCoinsInfo: unspentCoinsInfoSource,
+ alwaysScan: alwaysScan,
+ );
await currentWallet.renameWalletFiles(newName);
await saveBackup(newName);
@@ -105,12 +112,13 @@ class BitcoinWalletService extends WalletService<
@override
Future restoreFromHardwareWallet(BitcoinRestoreWalletFromHardware credentials,
{bool? isTestnet}) async {
-
final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet;
credentials.walletInfo?.network = network.value;
- credentials.walletInfo?.derivationInfo?.derivationPath = credentials.hwAccountData.derivationPath;
+ credentials.walletInfo?.derivationInfo?.derivationPath =
+ credentials.hwAccountData.derivationPath;
- final wallet = await BitcoinWallet(password: credentials.password!,
+ final wallet = await BitcoinWallet(
+ password: credentials.password!,
xpub: credentials.hwAccountData.xpub,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
@@ -123,7 +131,7 @@ class BitcoinWalletService extends WalletService<
@override
Future restoreFromKeys(BitcoinRestoreWalletFromWIFCredentials credentials,
- {bool? isTestnet}) async =>
+ {bool? isTestnet}) async =>
throw UnimplementedError();
@override
diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index 0553170cc..afd5e2440 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -41,23 +41,35 @@ class ElectrumClient {
bool get isConnected => _isConnected;
Socket? socket;
- void Function(bool)? onConnectionStatusChange;
+ void Function(bool?)? onConnectionStatusChange;
int _id;
final Map _tasks;
+ Map get tasks => _tasks;
final Map _errors;
bool _isConnected;
Timer? _aliveTimer;
String unterminatedString;
- Future connectToUri(Uri uri) async => await connect(host: uri.host, port: uri.port);
+ Uri? uri;
+ bool? useSSL;
- Future connect({required String host, required int port}) async {
+ Future connectToUri(Uri uri, {bool? useSSL}) async {
+ this.uri = uri;
+ this.useSSL = useSSL;
+ await connect(host: uri.host, port: uri.port, useSSL: useSSL);
+ }
+
+ Future connect({required String host, required int port, bool? useSSL}) async {
try {
await socket?.close();
} catch (_) {}
- socket = await SecureSocket.connect(host, port,
- timeout: connectionTimeout, onBadCertificate: (_) => true);
+ if (useSSL == false) {
+ socket = await Socket.connect(host, port, timeout: connectionTimeout);
+ } else {
+ socket = await SecureSocket.connect(host, port,
+ timeout: connectionTimeout, onBadCertificate: (_) => true);
+ }
_setIsConnected(true);
socket!.listen((Uint8List event) {
@@ -79,7 +91,7 @@ class ElectrumClient {
_setIsConnected(false);
}, onDone: () {
unterminatedString = '';
- _setIsConnected(false);
+ _setIsConnected(null);
});
keepAlive();
}
@@ -134,11 +146,12 @@ class ElectrumClient {
await callWithTimeout(method: 'server.ping');
_setIsConnected(true);
} on RequestFailedTimeoutException catch (_) {
- _setIsConnected(false);
+ _setIsConnected(null);
}
}
- Future> version() => call(method: 'server.version').then((dynamic result) {
+ Future> version() =>
+ call(method: 'server.version', params: ["", "1.4"]).then((dynamic result) {
if (result is List) {
return result.map((dynamic val) => val.toString()).toList();
}
@@ -266,6 +279,18 @@ class ElectrumClient {
Future