From 6baa0afff730f05412c553c96d6dfecc7cf82cc4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 10 Jan 2023 10:05:22 -0600 Subject: [PATCH 001/123] update dogecoin test --- test/services/coins/dogecoin/dogecoin_wallet_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.dart index e04eb5cdd..ac863bd2a 100644 --- a/test/services/coins/dogecoin/dogecoin_wallet_test.dart +++ b/test/services/coins/dogecoin/dogecoin_wallet_test.dart @@ -28,7 +28,7 @@ import 'dogecoin_wallet_test_parameters.dart'; void main() { group("dogecoin constants", () { test("dogecoin minimum confirmations", () async { - expect(MINIMUM_CONFIRMATIONS, 3); + expect(MINIMUM_CONFIRMATIONS, 1); }); test("dogecoin dust limit", () async { expect(DUST_LIMIT, 1000000); From 5c66b0380b4564b4773c70e6ab94e49850aad318 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Jan 2023 12:16:27 -0600 Subject: [PATCH 002/123] move standard electrum x transaction parsing function into a mixin --- .../coins/bitcoin/bitcoin_wallet.dart | 5 +- lib/services/coins/coin_paynym_extension.dart | 195 ----------------- .../coins/dogecoin/dogecoin_wallet.dart | 5 +- .../coins/litecoin/litecoin_wallet.dart | 5 +- .../coins/namecoin/namecoin_wallet.dart | 5 +- lib/services/mixins/electrum_x_parsing.dart | 202 ++++++++++++++++++ 6 files changed, 214 insertions(+), 203 deletions(-) create mode 100644 lib/services/mixins/electrum_x_parsing.dart diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index b3ea2485f..4afec573b 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -16,13 +16,13 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -138,7 +138,8 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { return getBip32Root(args.item1, args.item2); } -class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { +class BitcoinWallet extends CoinServiceAPI + with WalletCache, WalletDB, ElectrumXParsing { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index a5e8a07d5..7cebca9ca 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -6,14 +6,12 @@ import 'package:bip47/src/util.dart'; import 'package:bitcoindart/bitcoindart.dart' as btc_dart; import 'package:bitcoindart/src/utils/constants/op.dart' as op; import 'package:bitcoindart/src/utils/script.dart' as bscript; -import 'package:decimal/decimal.dart'; import 'package:isar/isar.dart'; import 'package:pointycastle/digests/sha256.dart'; import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/utilities/address_utils.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:tuple/tuple.dart'; @@ -561,196 +559,3 @@ extension PayNym on DogecoinWallet { ); } } - -Future<Tuple4<Transaction, List<Output>, List<Input>, Address>> - parseTransaction( - Map<String, dynamic> txData, - dynamic electrumxClient, - List<Address> myAddresses, - Coin coin, - int minConfirms, - String walletId, -) async { - Set<String> receivingAddresses = myAddresses - .where((e) => e.subType == AddressSubType.receiving) - .map((e) => e.value) - .toSet(); - Set<String> changeAddresses = myAddresses - .where((e) => e.subType == AddressSubType.change) - .map((e) => e.value) - .toSet(); - - Set<String> inputAddresses = {}; - Set<String> outputAddresses = {}; - - int totalInputValue = 0; - int totalOutputValue = 0; - - int amountSentFromWallet = 0; - int amountReceivedInWallet = 0; - int changeAmount = 0; - - // parse inputs - for (final input in txData["vin"] as List) { - final prevTxid = input["txid"] as String; - final prevOut = input["vout"] as int; - - // fetch input tx to get address - final inputTx = await electrumxClient.getTransaction( - txHash: prevTxid, - coin: coin, - ); - - for (final output in inputTx["vout"] as List) { - // check matching output - if (prevOut == output["n"]) { - // get value - final value = Format.decimalAmountToSatoshis( - Decimal.parse(output["value"].toString()), - coin, - ); - - // add value to total - totalInputValue += value; - - // get input(prevOut) address - final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]?["address"] as String?; - - if (address != null) { - inputAddresses.add(address); - - // if input was from my wallet, add value to amount sent - if (receivingAddresses.contains(address) || - changeAddresses.contains(address)) { - amountSentFromWallet += value; - } - } - } - } - } - - // parse outputs - for (final output in txData["vout"] as List) { - // get value - final value = Format.decimalAmountToSatoshis( - Decimal.parse(output["value"].toString()), - coin, - ); - - // add value to total - totalOutputValue += value; - - // get output address - final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]?["address"] as String?; - if (address != null) { - outputAddresses.add(address); - - // if output was to my wallet, add value to amount received - if (receivingAddresses.contains(address)) { - amountReceivedInWallet += value; - } else if (changeAddresses.contains(address)) { - changeAmount += value; - } - } - } - - final mySentFromAddresses = [ - ...receivingAddresses.intersection(inputAddresses), - ...changeAddresses.intersection(inputAddresses) - ]; - final myReceivedOnAddresses = - receivingAddresses.intersection(outputAddresses); - final myChangeReceivedOnAddresses = - changeAddresses.intersection(outputAddresses); - - final fee = totalInputValue - totalOutputValue; - - // this is the address initially used to fetch the txid - Address transactionAddress = txData["address"] as Address; - - TransactionType type; - int amount; - if (mySentFromAddresses.isNotEmpty && myReceivedOnAddresses.isNotEmpty) { - // tx is sent to self - type = TransactionType.sentToSelf; - - // should be 0 - amount = amountSentFromWallet - amountReceivedInWallet - fee - changeAmount; - } else if (mySentFromAddresses.isNotEmpty) { - // outgoing tx - type = TransactionType.outgoing; - amount = amountSentFromWallet - changeAmount - fee; - - final possible = - outputAddresses.difference(myChangeReceivedOnAddresses).first; - - if (transactionAddress.value != possible) { - transactionAddress = Address( - walletId: walletId, - value: possible, - derivationIndex: -1, - subType: AddressSubType.nonWallet, - type: AddressType.nonWallet, - publicKey: [], - ); - } - } else { - // incoming tx - type = TransactionType.incoming; - amount = amountReceivedInWallet; - } - - final tx = Transaction( - walletId: walletId, - txid: txData["txid"] as String, - timestamp: txData["blocktime"] as int? ?? - (DateTime.now().millisecondsSinceEpoch ~/ 1000), - type: type, - subType: TransactionSubType.none, - amount: amount, - fee: fee, - height: txData["height"] as int?, - isCancelled: false, - isLelantus: false, - slateId: null, - otherData: null, - ); - - List<Output> outs = []; - List<Input> ins = []; - - for (final json in txData["vin"] as List) { - bool isCoinBase = json['coinbase'] != null; - final input = Input( - walletId: walletId, - txid: json['txid'] as String, - vout: json['vout'] as int? ?? -1, - scriptSig: json['scriptSig']?['hex'] as String?, - scriptSigAsm: json['scriptSig']?['asm'] as String?, - isCoinbase: isCoinBase ? isCoinBase : json['is_coinbase'] as bool?, - sequence: json['sequence'] as int?, - innerRedeemScriptAsm: json['innerRedeemscriptAsm'] as String?, - ); - ins.add(input); - } - - for (final json in txData["vout"] as List) { - final output = Output( - walletId: walletId, - scriptPubKey: json['scriptPubKey']?['hex'] as String?, - scriptPubKeyAsm: json['scriptPubKey']?['asm'] as String?, - scriptPubKeyType: json['scriptPubKey']?['type'] as String?, - scriptPubKeyAddress: json["scriptPubKey"]?["addresses"]?[0] as String? ?? - json['scriptPubKey']['type'] as String, - value: Format.decimalAmountToSatoshis( - Decimal.parse(json["value"].toString()), - coin, - ), - ); - outs.add(output); - } - - return Tuple4(tx, outs, ins, transactionAddress); -} diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 9fc5d2f04..c878101b6 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -17,13 +17,13 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -125,7 +125,8 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { return getBip32Root(args.item1, args.item2); } -class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { +class DogecoinWallet extends CoinServiceAPI + with WalletCache, WalletDB, ElectrumXParsing { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); final _prefs = Prefs.instance; diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index 25e963b4b..44383443f 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -17,13 +17,13 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -138,7 +138,8 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { return getBip32Root(args.item1, args.item2); } -class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { +class LitecoinWallet extends CoinServiceAPI + with WalletCache, WalletDB, ElectrumXParsing { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 34728bcc3..8af9d8a59 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -17,13 +17,13 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -135,7 +135,8 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { return getBip32Root(args.item1, args.item2); } -class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { +class NamecoinWallet extends CoinServiceAPI + with WalletCache, WalletDB, ElectrumXParsing { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart new file mode 100644 index 000000000..9a2c950d6 --- /dev/null +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -0,0 +1,202 @@ +import 'package:decimal/decimal.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:tuple/tuple.dart'; + +mixin ElectrumXParsing { + Future<Tuple4<Transaction, List<Output>, List<Input>, Address>> + parseTransaction( + Map<String, dynamic> txData, + dynamic electrumxClient, + List<Address> myAddresses, + Coin coin, + int minConfirms, + String walletId, + ) async { + Set<String> receivingAddresses = myAddresses + .where((e) => e.subType == AddressSubType.receiving) + .map((e) => e.value) + .toSet(); + Set<String> changeAddresses = myAddresses + .where((e) => e.subType == AddressSubType.change) + .map((e) => e.value) + .toSet(); + + Set<String> inputAddresses = {}; + Set<String> outputAddresses = {}; + + int totalInputValue = 0; + int totalOutputValue = 0; + + int amountSentFromWallet = 0; + int amountReceivedInWallet = 0; + int changeAmount = 0; + + // parse inputs + for (final input in txData["vin"] as List) { + final prevTxid = input["txid"] as String; + final prevOut = input["vout"] as int; + + // fetch input tx to get address + final inputTx = await electrumxClient.getTransaction( + txHash: prevTxid, + coin: coin, + ); + + for (final output in inputTx["vout"] as List) { + // check matching output + if (prevOut == output["n"]) { + // get value + final value = Format.decimalAmountToSatoshis( + Decimal.parse(output["value"].toString()), + coin, + ); + + // add value to total + totalInputValue += value; + + // get input(prevOut) address + final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? + output["scriptPubKey"]?["address"] as String?; + + if (address != null) { + inputAddresses.add(address); + + // if input was from my wallet, add value to amount sent + if (receivingAddresses.contains(address) || + changeAddresses.contains(address)) { + amountSentFromWallet += value; + } + } + } + } + } + + // parse outputs + for (final output in txData["vout"] as List) { + // get value + final value = Format.decimalAmountToSatoshis( + Decimal.parse(output["value"].toString()), + coin, + ); + + // add value to total + totalOutputValue += value; + + // get output address + final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? + output["scriptPubKey"]?["address"] as String?; + if (address != null) { + outputAddresses.add(address); + + // if output was to my wallet, add value to amount received + if (receivingAddresses.contains(address)) { + amountReceivedInWallet += value; + } else if (changeAddresses.contains(address)) { + changeAmount += value; + } + } + } + + final mySentFromAddresses = [ + ...receivingAddresses.intersection(inputAddresses), + ...changeAddresses.intersection(inputAddresses) + ]; + final myReceivedOnAddresses = + receivingAddresses.intersection(outputAddresses); + final myChangeReceivedOnAddresses = + changeAddresses.intersection(outputAddresses); + + final fee = totalInputValue - totalOutputValue; + + // this is the address initially used to fetch the txid + Address transactionAddress = txData["address"] as Address; + + TransactionType type; + int amount; + if (mySentFromAddresses.isNotEmpty && myReceivedOnAddresses.isNotEmpty) { + // tx is sent to self + type = TransactionType.sentToSelf; + + // should be 0 + amount = + amountSentFromWallet - amountReceivedInWallet - fee - changeAmount; + } else if (mySentFromAddresses.isNotEmpty) { + // outgoing tx + type = TransactionType.outgoing; + amount = amountSentFromWallet - changeAmount - fee; + + final possible = + outputAddresses.difference(myChangeReceivedOnAddresses).first; + + if (transactionAddress.value != possible) { + transactionAddress = Address( + walletId: walletId, + value: possible, + derivationIndex: -1, + subType: AddressSubType.nonWallet, + type: AddressType.nonWallet, + publicKey: [], + ); + } + } else { + // incoming tx + type = TransactionType.incoming; + amount = amountReceivedInWallet; + } + + final tx = Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: txData["blocktime"] as int? ?? + (DateTime.now().millisecondsSinceEpoch ~/ 1000), + type: type, + subType: TransactionSubType.none, + amount: amount, + fee: fee, + height: txData["height"] as int?, + isCancelled: false, + isLelantus: false, + slateId: null, + otherData: null, + ); + + List<Output> outs = []; + List<Input> ins = []; + + for (final json in txData["vin"] as List) { + bool isCoinBase = json['coinbase'] != null; + final input = Input( + walletId: walletId, + txid: json['txid'] as String, + vout: json['vout'] as int? ?? -1, + scriptSig: json['scriptSig']?['hex'] as String?, + scriptSigAsm: json['scriptSig']?['asm'] as String?, + isCoinbase: isCoinBase ? isCoinBase : json['is_coinbase'] as bool?, + sequence: json['sequence'] as int?, + innerRedeemScriptAsm: json['innerRedeemscriptAsm'] as String?, + ); + ins.add(input); + } + + for (final json in txData["vout"] as List) { + final output = Output( + walletId: walletId, + scriptPubKey: json['scriptPubKey']?['hex'] as String?, + scriptPubKeyAsm: json['scriptPubKey']?['asm'] as String?, + scriptPubKeyType: json['scriptPubKey']?['type'] as String?, + scriptPubKeyAddress: + json["scriptPubKey"]?["addresses"]?[0] as String? ?? + json['scriptPubKey']['type'] as String, + value: Format.decimalAmountToSatoshis( + Decimal.parse(json["value"].toString()), + coin, + ), + ); + outs.add(output); + } + + return Tuple4(tx, outs, ins, transactionAddress); + } +} From c1182f61bc3c37a00b4b0998ead7682fbc957766 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Jan 2023 12:25:32 -0600 Subject: [PATCH 003/123] start centralizing custom exceptions --- lib/exceptions/address/address_exception.dart | 5 +++++ lib/exceptions/sw_exception.dart | 11 +++++++++++ .../insufficient_balance_exception.dart | 5 +++++ .../wallet/paynym_send_exception.dart | 5 +++++ lib/models/isar/models/address/address.dart | 6 +----- .../paynym/dialogs/paynym_details_popup.dart | 1 + .../subwidgets/desktop_paynym_details.dart | 1 + lib/services/coins/coin_paynym_extension.dart | 19 ++----------------- 8 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 lib/exceptions/address/address_exception.dart create mode 100644 lib/exceptions/sw_exception.dart create mode 100644 lib/exceptions/wallet/insufficient_balance_exception.dart create mode 100644 lib/exceptions/wallet/paynym_send_exception.dart diff --git a/lib/exceptions/address/address_exception.dart b/lib/exceptions/address/address_exception.dart new file mode 100644 index 000000000..3331bef99 --- /dev/null +++ b/lib/exceptions/address/address_exception.dart @@ -0,0 +1,5 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class AddressException extends SWException { + AddressException(super.message); +} diff --git a/lib/exceptions/sw_exception.dart b/lib/exceptions/sw_exception.dart new file mode 100644 index 000000000..34ab664f2 --- /dev/null +++ b/lib/exceptions/sw_exception.dart @@ -0,0 +1,11 @@ +// generic stack wallet exception which all other custom exceptions should +// extend from + +class SWException with Exception { + SWException(this.message); + + final String message; + + @override + toString() => message; +} diff --git a/lib/exceptions/wallet/insufficient_balance_exception.dart b/lib/exceptions/wallet/insufficient_balance_exception.dart new file mode 100644 index 000000000..219ef6a76 --- /dev/null +++ b/lib/exceptions/wallet/insufficient_balance_exception.dart @@ -0,0 +1,5 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class InsufficientBalanceException extends SWException { + InsufficientBalanceException(super.message); +} diff --git a/lib/exceptions/wallet/paynym_send_exception.dart b/lib/exceptions/wallet/paynym_send_exception.dart new file mode 100644 index 000000000..9980e6790 --- /dev/null +++ b/lib/exceptions/wallet/paynym_send_exception.dart @@ -0,0 +1,5 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class PaynymSendException extends SWException { + PaynymSendException(super.message); +} diff --git a/lib/models/isar/models/address/address.dart b/lib/models/isar/models/address/address.dart index df6d06fa7..c3e885f3e 100644 --- a/lib/models/isar/models/address/address.dart +++ b/lib/models/isar/models/address/address.dart @@ -1,14 +1,10 @@ import 'package:isar/isar.dart'; +import 'package:stackwallet/exceptions/address/address_exception.dart'; import 'package:stackwallet/models/isar/models/address/crypto_currency_address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; part 'address.g.dart'; -class AddressException extends SWException { - AddressException(super.message); -} - @Collection(accessor: "addresses") class Address extends CryptoCurrencyAddress { Address({ diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index 72c4a2f46..350b02ead 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:qr_flutter/qr_flutter.dart'; +import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart'; diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index d51a0fecd..ee4996a9d 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:qr_flutter/qr_flutter.dart'; +import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart'; diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index 7cebca9ca..d8f5c535e 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -8,6 +8,8 @@ import 'package:bitcoindart/src/utils/constants/op.dart' as op; import 'package:bitcoindart/src/utils/script.dart' as bscript; import 'package:isar/isar.dart'; import 'package:pointycastle/digests/sha256.dart'; +import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; +import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; @@ -16,23 +18,6 @@ import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:tuple/tuple.dart'; -class SWException with Exception { - SWException(this.message); - - final String message; - - @override - toString() => message; -} - -class InsufficientBalanceException extends SWException { - InsufficientBalanceException(super.message); -} - -class PaynymSendException extends SWException { - PaynymSendException(super.message); -} - extension PayNym on DogecoinWallet { // fetch or generate this wallet's bip47 payment code Future<PaymentCode> getPaymentCode() async { From 6790f702c2b6b10d268944d3135dc3ba71cefe6d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 09:37:14 -0600 Subject: [PATCH 004/123] migrate bugfix --- lib/utilities/db_version_migration.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utilities/db_version_migration.dart b/lib/utilities/db_version_migration.dart index eab9a8966..21378c8b5 100644 --- a/lib/utilities/db_version_migration.dart +++ b/lib/utilities/db_version_migration.dart @@ -503,7 +503,7 @@ class DbVersionMigrator with WalletDB { type: isar_models.AddressType.unknown, subType: type == isar_models.TransactionType.incoming ? isar_models.AddressSubType.receiving - : isar_models.AddressSubType.change, + : isar_models.AddressSubType.unknown, ); } } From f3325807e0f994c89e2f6f04377cfb8687d602b1 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 10:32:53 -0600 Subject: [PATCH 005/123] null address fix --- .../coins/bitcoin/bitcoin_wallet.dart | 52 +++++++++--------- .../coins/bitcoincash/bitcoincash_wallet.dart | 52 +++++++++--------- .../coins/dogecoin/dogecoin_wallet.dart | 52 +++++++++--------- lib/services/coins/firo/firo_wallet.dart | 52 +++++++++--------- .../coins/litecoin/litecoin_wallet.dart | 52 +++++++++--------- lib/services/coins/monero/monero_wallet.dart | 2 + .../coins/namecoin/namecoin_wallet.dart | 53 ++++++++++--------- .../coins/particl/particl_wallet.dart | 52 +++++++++--------- .../coins/wownero/wownero_wallet.dart | 9 ++-- 9 files changed, 189 insertions(+), 187 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 9e8702ea3..d0b114829 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -186,24 +186,28 @@ class BitcoinWallet extends CoinServiceAPI Future<String> get currentReceivingAddress async => (await _currentReceivingAddress).value; - Future<isar_models.Address> get _currentReceivingAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2wpkh) - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentReceivingAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2wpkh) + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(0, 0, DerivePathType.bip84); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; - Future<isar_models.Address> get _currentChangeAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2wpkh) - .subTypeEqualTo(isar_models.AddressSubType.change) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentChangeAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2wpkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0, DerivePathType.bip84); @override Future<void> exit() async { @@ -1164,6 +1168,8 @@ class BitcoinWallet extends CoinServiceAPI } await _prefs.init(); + await _checkCurrentChangeAddressesForTransactions(); + await _checkCurrentReceivingAddressesForTransactions(); } // hack to add tx to txData before refresh completes @@ -1857,7 +1863,7 @@ class BitcoinWallet extends CoinServiceAPI 'Number of txs for current receiving address $currentReceiving: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentReceiving.derivationIndex < 0) { // First increment the receiving index final newReceivingIndex = currentReceiving.derivationIndex + 1; @@ -1876,12 +1882,9 @@ class BitcoinWallet extends CoinServiceAPI } else { // we need to update the address await db.updateAddress(existing, newReceivingAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkReceivingAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkReceivingAddressForTransactions(); } } catch (e, s) { Logging.instance.log( @@ -1899,7 +1902,7 @@ class BitcoinWallet extends CoinServiceAPI 'Number of txs for current change address $currentChange: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentChange.derivationIndex < 0) { // First increment the change index final newChangeIndex = currentChange.derivationIndex + 1; @@ -1918,12 +1921,9 @@ class BitcoinWallet extends CoinServiceAPI } else { // we need to update the address await db.updateAddress(existing, newChangeAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkChangeAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkChangeAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 1a6587e6b..70e3a5d55 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -162,24 +162,28 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { Future<String> get currentReceivingAddress async => (await _currentReceivingAddress).value; - Future<isar_models.Address> get _currentReceivingAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2pkh) - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentReceivingAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(0, 0, DerivePathType.bip44); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; - Future<isar_models.Address> get _currentChangeAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2pkh) - .subTypeEqualTo(isar_models.AddressSubType.change) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentChangeAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0, DerivePathType.bip44); @override Future<void> exit() async { @@ -1093,6 +1097,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } await _prefs.init(); + await _checkCurrentChangeAddressesForTransactions(); + await _checkCurrentReceivingAddressesForTransactions(); } // hack to add tx to txData before refresh completes @@ -1740,7 +1746,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { 'Number of txs for current receiving address $currentReceiving: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentReceiving.derivationIndex < 0) { // First increment the receiving index final newReceivingIndex = currentReceiving.derivationIndex + 1; @@ -1759,12 +1765,9 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } else { // we need to update the address await db.updateAddress(existing, newReceivingAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkReceivingAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkReceivingAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( @@ -1787,7 +1790,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { 'Number of txs for current change address $currentChange: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentChange.derivationIndex < 0) { // First increment the change index final newChangeIndex = currentChange.derivationIndex + 1; @@ -1806,12 +1809,9 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } else { // we need to update the address await db.updateAddress(existing, newChangeAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkChangeAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkChangeAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 63568cc59..1c083d3bd 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -161,25 +161,29 @@ class DogecoinWallet extends CoinServiceAPI Future<String> get currentReceivingAddress async => (await _currentReceivingAddress).value; - Future<isar_models.Address> get _currentReceivingAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2pkh) - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentReceivingAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(0, 0, DerivePathType.bip44); // @override Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; - Future<isar_models.Address> get _currentChangeAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2pkh) - .subTypeEqualTo(isar_models.AddressSubType.change) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentChangeAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0, DerivePathType.bip44); @override Future<void> exit() async { @@ -999,6 +1003,8 @@ class DogecoinWallet extends CoinServiceAPI } await _prefs.init(); + await _checkCurrentChangeAddressesForTransactions(); + await _checkCurrentReceivingAddressesForTransactions(); } // hack to add tx to txData before refresh completes @@ -1645,7 +1651,7 @@ class DogecoinWallet extends CoinServiceAPI 'Number of txs for current receiving address $currentReceiving: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentReceiving.derivationIndex < 0) { // First increment the receiving index final newReceivingIndex = currentReceiving.derivationIndex + 1; @@ -1664,12 +1670,9 @@ class DogecoinWallet extends CoinServiceAPI } else { // we need to update the address await db.updateAddress(existing, newReceivingAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkReceivingAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkReceivingAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( @@ -1692,7 +1695,7 @@ class DogecoinWallet extends CoinServiceAPI 'Number of txs for current change address $currentChange: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentChange.derivationIndex < 0) { // First increment the change index final newChangeIndex = currentChange.derivationIndex + 1; @@ -1711,12 +1714,9 @@ class DogecoinWallet extends CoinServiceAPI } else { // we need to update the address await db.updateAddress(existing, newChangeAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await checkChangeAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await checkChangeAddressForTransactions(); } } catch (e, s) { Logging.instance.log( diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 0962e6fdc..ec63db186 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -871,24 +871,28 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { Future<String> get currentReceivingAddress async => (await _currentReceivingAddress).value; - Future<isar_models.Address> get _currentReceivingAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2pkh) - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentReceivingAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(0, 0); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; - Future<isar_models.Address> get _currentChangeAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2pkh) - .subTypeEqualTo(isar_models.AddressSubType.change) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentChangeAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0); late String _walletName; @override @@ -1831,6 +1835,8 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { "Attempted to initialize an existing wallet using an unknown wallet ID!"); } await _prefs.init(); + await checkChangeAddressForTransactions(); + await checkReceivingAddressForTransactions(); } Future<bool> refreshIfThereIsNewData() async { @@ -3144,7 +3150,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { 'Number of txs for current receiving address $currentReceiving: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentReceiving.derivationIndex < 0) { // First increment the receiving index final newReceivingIndex = currentReceiving.derivationIndex + 1; @@ -3165,12 +3171,9 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { } else { // we need to update the address await db.updateAddress(existing, newReceivingAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await checkReceivingAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await checkReceivingAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( @@ -3194,7 +3197,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { 'Number of txs for current change address: $currentChange: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentChange.derivationIndex < 0) { // First increment the change index final newChangeIndex = currentChange.derivationIndex + 1; @@ -3215,12 +3218,9 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { } else { // we need to update the address await db.updateAddress(existing, newChangeAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await checkChangeAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await checkChangeAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index d0c922afa..fe1fdf13c 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -186,24 +186,28 @@ class LitecoinWallet extends CoinServiceAPI Future<String> get currentReceivingAddress async => (await _currentReceivingAddress).value; - Future<isar_models.Address> get _currentReceivingAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2wpkh) - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentReceivingAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2wpkh) + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(0, 0, DerivePathType.bip84); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; - Future<isar_models.Address> get _currentChangeAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2wpkh) - .subTypeEqualTo(isar_models.AddressSubType.change) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentChangeAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2wpkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0, DerivePathType.bip84); @override Future<void> exit() async { @@ -1182,6 +1186,8 @@ class LitecoinWallet extends CoinServiceAPI "Attempted to initialize an existing wallet using an unknown wallet ID!"); } await _prefs.init(); + await _checkCurrentChangeAddressesForTransactions(); + await _checkCurrentReceivingAddressesForTransactions(); } // hack to add tx to txData before refresh completes @@ -1880,7 +1886,7 @@ class LitecoinWallet extends CoinServiceAPI 'Number of txs for current receiving address $currentReceiving: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentReceiving.derivationIndex < 0) { // First increment the receiving index final newReceivingIndex = currentReceiving.derivationIndex + 1; @@ -1899,12 +1905,9 @@ class LitecoinWallet extends CoinServiceAPI } else { // we need to update the address await db.updateAddress(existing, newReceivingAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkReceivingAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkReceivingAddressForTransactions(); } } catch (e, s) { Logging.instance.log( @@ -1922,7 +1925,7 @@ class LitecoinWallet extends CoinServiceAPI 'Number of txs for current change address $currentChange: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentChange.derivationIndex < 0) { // First increment the change index final newChangeIndex = currentChange.derivationIndex + 1; @@ -1941,12 +1944,9 @@ class LitecoinWallet extends CoinServiceAPI } else { // we need to update the address await db.updateAddress(existing, newChangeAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkChangeAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkChangeAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart index ee3807163..d46595ec4 100644 --- a/lib/services/coins/monero/monero_wallet.dart +++ b/lib/services/coins/monero/monero_wallet.dart @@ -288,6 +288,8 @@ class MoneroWallet extends CoinServiceAPI with WalletCache, WalletDB { } walletBase = (await walletService!.openWallet(_walletId, password)) as MoneroWalletBase; + + await _checkCurrentReceivingAddressesForTransactions(); // walletBase!.onNewBlock = onNewBlock; // walletBase!.onNewTransaction = onNewTransaction; // walletBase!.syncStatusChanged = syncStatusChanged; diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index e9ef15b90..cae6cf29a 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -181,24 +181,28 @@ class NamecoinWallet extends CoinServiceAPI Future<String> get currentReceivingAddress async => (await _currentReceivingAddress).value; - Future<isar_models.Address> get _currentReceivingAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2wpkh) - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentReceivingAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2wpkh) + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(0, 0, DerivePathType.bip84); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; - Future<isar_models.Address> get _currentChangeAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2wpkh) - .subTypeEqualTo(isar_models.AddressSubType.change) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentChangeAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2wpkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0, DerivePathType.bip84); @override Future<void> exit() async { @@ -1171,6 +1175,8 @@ class NamecoinWallet extends CoinServiceAPI "Attempted to initialize an existing wallet using an unknown wallet ID!"); } await _prefs.init(); + await _checkCurrentChangeAddressesForTransactions(); + await _checkCurrentReceivingAddressesForTransactions(); } // hack to add tx to txData before refresh completes @@ -1862,7 +1868,7 @@ class NamecoinWallet extends CoinServiceAPI 'Number of txs for current receiving address $currentReceiving: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentReceiving.derivationIndex < 0) { // First increment the receiving index final newReceivingIndex = currentReceiving.derivationIndex + 1; @@ -1881,12 +1887,9 @@ class NamecoinWallet extends CoinServiceAPI } else { // we need to update the address await db.updateAddress(existing, newReceivingAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkReceivingAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkReceivingAddressForTransactions(); } } catch (e, s) { Logging.instance.log( @@ -1904,7 +1907,7 @@ class NamecoinWallet extends CoinServiceAPI 'Number of txs for current change address $currentChange: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentChange.derivationIndex < 0) { // First increment the change index final newChangeIndex = currentChange.derivationIndex + 1; @@ -1923,12 +1926,10 @@ class NamecoinWallet extends CoinServiceAPI } else { // we need to update the address await db.updateAddress(existing, newChangeAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkChangeAddressForTransactions(); } + + // keep checking until address with no tx history is set as current + await _checkChangeAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index e705a6178..d19fdf769 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -176,24 +176,28 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { Future<String> get currentReceivingAddress async => (await _currentReceivingAddress).value; - Future<isar_models.Address> get _currentReceivingAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2wpkh) - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentReceivingAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2wpkh) + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(0, 0, DerivePathType.bip84); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; - Future<isar_models.Address> get _currentChangeAddress async => (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2wpkh) - .subTypeEqualTo(isar_models.AddressSubType.change) - .sortByDerivationIndexDesc() - .findFirst())!; + Future<isar_models.Address> get _currentChangeAddress async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2wpkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0, DerivePathType.bip84); @override Future<void> exit() async { @@ -1100,6 +1104,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { "Attempted to initialize an existing wallet using an unknown wallet ID!"); } await _prefs.init(); + await _checkCurrentChangeAddressesForTransactions(); + await _checkCurrentReceivingAddressesForTransactions(); } // TODO make sure this copied implementation from bitcoin_wallet.dart applies for particl just as well--or import it @@ -1749,7 +1755,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { 'Number of txs for current receiving address $currentReceiving: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentReceiving.derivationIndex < 0) { // First increment the receiving index final newReceivingIndex = currentReceiving.derivationIndex + 1; @@ -1768,12 +1774,9 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { } else { // we need to update the address await db.updateAddress(existing, newReceivingAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkReceivingAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkReceivingAddressForTransactions(); } } catch (e, s) { Logging.instance.log( @@ -1791,7 +1794,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { 'Number of txs for current change address $currentChange: $txCount', level: LogLevel.Info); - if (txCount >= 1) { + if (txCount >= 1 || currentChange.derivationIndex < 0) { // First increment the change index final newChangeIndex = currentChange.derivationIndex + 1; @@ -1810,12 +1813,9 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { } else { // we need to update the address await db.updateAddress(existing, newChangeAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkChangeAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkChangeAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart index d471208cd..b1afa561d 100644 --- a/lib/services/coins/wownero/wownero_wallet.dart +++ b/lib/services/coins/wownero/wownero_wallet.dart @@ -306,6 +306,8 @@ class WowneroWallet extends CoinServiceAPI with WalletCache, WalletDB { walletBase = (await walletService?.openWallet(_walletId, password!)) as WowneroWalletBase; + await _checkCurrentReceivingAddressesForTransactions(); + Logging.instance.log( "Opened existing ${coin.prettyName} wallet $walletName", level: LogLevel.Info, @@ -1245,12 +1247,9 @@ class WowneroWallet extends CoinServiceAPI with WalletCache, WalletDB { } else { // we need to update the address await db.updateAddress(existing, newReceivingAddress); - - // since we updated an existing address there is a chance it has - // some tx history. To prevent address reuse we will call check again - // recursively - await _checkReceivingAddressForTransactions(); } + // keep checking until address with no tx history is set as current + await _checkReceivingAddressForTransactions(); } } on SocketException catch (se, s) { Logging.instance.log( From abf803afed92901a52771cc1ca03b0c17fa9c504 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 10:33:36 -0600 Subject: [PATCH 006/123] increment build number --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index a4ba77948..134132e5f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.30+104 +version: 1.5.30+105 environment: sdk: ">=2.17.0 <3.0.0" From 69dfbb5873561ba267c9a33754def1af7034b11a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 12:19:13 -0600 Subject: [PATCH 007/123] paynym clean up to use isar transaction and address upgrades --- .../paynym/dialogs/paynym_details_popup.dart | 10 +- .../subwidgets/desktop_paynym_details.dart | 10 +- .../send_view/confirm_transaction_view.dart | 2 +- lib/services/coins/coin_paynym_extension.dart | 230 ++----- .../coins/dogecoin/dogecoin_wallet.dart | 4 +- lib/services/mixins/electrum_x_parsing.dart | 12 +- lib/services/mixins/paynym_support.dart | 569 ++++++++++++++++++ lib/utilities/bip32_utils.dart | 32 + 8 files changed, 682 insertions(+), 187 deletions(-) create mode 100644 lib/services/mixins/paynym_support.dart create mode 100644 lib/utilities/bip32_utils.dart diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index 350b02ead..4190aab8d 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -63,13 +63,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { .getManager(widget.walletId) .wallet as DogecoinWallet; - // sanity check to prevent second notifcation tx - if (wallet.hasConnectedConfirmed(widget.accountLite.code)) { - canPop = true; - Navigator.of(context).pop(); - // TODO show info popup - return; - } else if (wallet.hasConnected(widget.accountLite.code)) { + if (wallet.hasConnected(widget.accountLite.code)) { canPop = true; Navigator.of(context).pop(); // TODO show info popup @@ -81,7 +75,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { Map<String, dynamic> preparedTx; try { - preparedTx = await wallet.buildNotificationTx( + preparedTx = await wallet.prepareNotificationTx( selectedTxFeeRate: rates.medium, targetPaymentCodeString: widget.accountLite.code, ); diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index ee4996a9d..4e69a7586 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -63,13 +63,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { .getManager(widget.walletId) .wallet as DogecoinWallet; - // sanity check to prevent second notification tx - if (wallet.hasConnectedConfirmed(widget.accountLite.code)) { - canPop = true; - Navigator.of(context, rootNavigator: true).pop(); - // TODO show info popup - return; - } else if (wallet.hasConnected(widget.accountLite.code)) { + if (wallet.hasConnected(widget.accountLite.code)) { canPop = true; Navigator.of(context, rootNavigator: true).pop(); // TODO show info popup @@ -81,7 +75,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { Map<String, dynamic> preparedTx; try { - preparedTx = await wallet.buildNotificationTx( + preparedTx = await wallet.prepareNotificationTx( selectedTxFeeRate: rates.medium, targetPaymentCodeString: widget.accountLite.code, ); diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index 1164e0418..3ed4de63c 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -93,7 +93,7 @@ class _ConfirmTransactionViewState String txid; if (widget.isPaynymNotificationTransaction) { txid = await (manager.wallet as DogecoinWallet) - .confirmNotificationTx(preparedTx: transactionInfo); + .broadcastNotificationTx(preparedTx: transactionInfo); } else if (widget.isPaynymTransaction) { // throw UnimplementedError("paynym send not implemented yet"); diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index d8f5c535e..2ad0e4475 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:typed_data'; +import 'package:bip32/bip32.dart' as bip32; import 'package:bip47/bip47.dart'; import 'package:bip47/src/util.dart'; import 'package:bitcoindart/bitcoindart.dart' as btc_dart; @@ -10,38 +11,57 @@ import 'package:isar/isar.dart'; import 'package:pointycastle/digests/sha256.dart'; import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; -import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/utilities/address_utils.dart'; +import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:tuple/tuple.dart'; +const kPaynymDerivePath = "m/47'/0'/0'"; + extension PayNym on DogecoinWallet { + // generate bip32 payment code root + Future<bip32.BIP32> getRootNode({required List<String> mnemonic}) async { + final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); + return root; + } + // fetch or generate this wallet's bip47 payment code Future<PaymentCode> getPaymentCode() async { - final paymentCodeString = DB.instance - .get<dynamic>(boxName: walletId, key: "paymentCodeString") as String?; + final address = await db + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymNotification) + .findFirst(); PaymentCode paymentCode; - if (paymentCodeString == null) { - final node = getBip32Root((await mnemonic).join(" "), network) - .derivePath("m/47'/0'/0'"); + if (address == null) { + final root = await getRootNode(mnemonic: await mnemonic); + final node = root.derivePath(kPaynymDerivePath); paymentCode = PaymentCode.initFromPubKey(node.publicKey, node.chainCode, network); - await DB.instance.put<dynamic>( - boxName: walletId, - key: "paymentCodeString", - value: paymentCode.toString()); + + await db.putAddress( + Address( + walletId: walletId, + value: paymentCode.notificationAddress(), + publicKey: paymentCode.getPubKey(), + derivationIndex: 0, + type: AddressType.p2pkh, // todo change this for btc + subType: AddressSubType.paynymNotification, + otherData: paymentCode.toString(), + ), + ); } else { - paymentCode = PaymentCode.fromPaymentCode(paymentCodeString, network); + paymentCode = PaymentCode.fromPaymentCode(address.otherData!, network); } return paymentCode; } Future<Uint8List> signWithNotificationKey(Uint8List data) async { - final node = getBip32Root((await mnemonic).join(" "), network) - .derivePath("m/47'/0'/0'"); + final root = await getRootNode(mnemonic: await mnemonic); + final node = root.derivePath(kPaynymDerivePath); final pair = btc_dart.ECPair.fromPrivateKey(node.privateKey!, network: network); final signed = pair.sign(SHA256Digest().process(data)); @@ -52,92 +72,17 @@ extension PayNym on DogecoinWallet { final bytes = await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); return Format.uint8listToString(bytes); - // final bytes = - // await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); - // return Format.uint8listToString(bytes); - } - - /// Update cached lists of notification transaction IDs. - /// Returns true if there are new notification transactions found since last - /// checked. - Future<bool> checkForNotificationTransactions() async { - final myPCode = await getPaymentCode(); - - final transactionIds = await electrumXClient.getHistory( - scripthash: AddressUtils.convertToScriptHash( - myPCode.notificationAddress(), - network, - ), - ); - - final confirmedNotificationTransactionIds = DB.instance.get<dynamic>( - boxName: walletId, - key: "confirmedNotificationTransactionIds", - ) as Set? ?? - {}; - - final unconfirmedNotificationTransactionIds = DB.instance.get<dynamic>( - boxName: walletId, - key: "unconfirmedNotificationTransactionIds", - ) as Set? ?? - {}; - - // since we are only checking for newly found transactions here we can use the sum - final totalCount = confirmedNotificationTransactionIds.length + - unconfirmedNotificationTransactionIds.length; - - for (final entry in transactionIds) { - final txid = entry["tx_hash"] as String; - - final tx = await cachedElectrumXClient.getTransaction( - txHash: txid, - coin: coin, - ); - - // check if tx is confirmed - if ((tx["confirmations"] as int? ?? 0) > MINIMUM_CONFIRMATIONS) { - // remove it from unconfirmed set - unconfirmedNotificationTransactionIds.remove(txid); - - // add it to confirmed set - confirmedNotificationTransactionIds.add(txid); - } else { - // otherwise add it to the unconfirmed set - unconfirmedNotificationTransactionIds.add(txid); - } - } - - final newTotalCount = confirmedNotificationTransactionIds.length + - unconfirmedNotificationTransactionIds.length; - - return newTotalCount > totalCount; - } - - /// return the notification tx sent from my wallet if it exists - Future<Transaction?> hasSentNotificationTx(PaymentCode pCode) async { - final tx = await db - .getTransactions(walletId) - .filter() - .address((q) => q.valueEqualTo(pCode.notificationAddress())) - .findFirst(); - return tx; } void preparePaymentCodeSend(PaymentCode pCode) async { - final notifTx = await hasSentNotificationTx(pCode); - final currentHeight = await chainHeight; - - if (notifTx == null) { + if (!hasConnected(pCode.notificationAddress())) { throw PaynymSendException("No notification transaction sent to $pCode"); - } else if (!notifTx.isConfirmed(currentHeight, MINIMUM_CONFIRMATIONS)) { - throw PaynymSendException( - "Notification transaction sent to $pCode has not confirmed yet"); } else { - final node = getBip32Root((await mnemonic).join(" "), network) - .derivePath("m/47'/0'/0'"); + final root = await getRootNode(mnemonic: await mnemonic); + final node = root.derivePath(kPaynymDerivePath); final sendToAddress = await nextUnusedSendAddressFrom( - pCode, - node.derive(0).privateKey!, + pCode: pCode, + privateKey: node.derive(0).privateKey!, ); // todo: Actual transaction build @@ -146,22 +91,21 @@ extension PayNym on DogecoinWallet { /// get the next unused address to send to given the receiver's payment code /// and your own private key - Future<String> nextUnusedSendAddressFrom( - PaymentCode pCode, - Uint8List privateKey, - ) async { + Future<String> nextUnusedSendAddressFrom({ + required PaymentCode pCode, + required Uint8List privateKey, + int startIndex = 0, + }) async { // https://en.bitcoin.it/wiki/BIP_0047#Path_levels const maxCount = 2147483647; final paymentAddress = PaymentAddress.initWithPrivateKey( privateKey, pCode, - 0, // initial index to check + startIndex, // initial index to check ); - for (paymentAddress.index = 0; - paymentAddress.index <= maxCount; - paymentAddress.index++) { + for (; paymentAddress.index <= maxCount; paymentAddress.index++) { final address = paymentAddress.getSendAddress(); final transactionIds = await electrumXClient.getHistory( @@ -208,7 +152,7 @@ extension PayNym on DogecoinWallet { return result; } - Future<Map<String, dynamic>> buildNotificationTx({ + Future<Map<String, dynamic>> prepareNotificationTx({ required int selectedTxFeeRate, required String targetPaymentCodeString, int additionalOutputs = 0, @@ -370,7 +314,7 @@ extension PayNym on DogecoinWallet { // if we get here we do not have enough funds to cover the tx total so we // check if we have any more available outputs and try again if (spendableOutputs.length > outputsBeingUsed) { - return buildNotificationTx( + return prepareNotificationTx( selectedTxFeeRate: selectedTxFeeRate, targetPaymentCodeString: targetPaymentCodeString, additionalOutputs: additionalOutputs + 1, @@ -462,7 +406,7 @@ extension PayNym on DogecoinWallet { return Tuple2(builtTx.toHex(), builtTx.virtualSize()); } - Future<String> confirmNotificationTx( + Future<String> broadcastNotificationTx( {required Map<String, dynamic> preparedTx}) async { try { Logging.instance.log("confirmNotificationTx txData: $preparedTx", @@ -471,11 +415,16 @@ extension PayNym on DogecoinWallet { rawTx: preparedTx["hex"] as String); Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); - await updatePaynymNotificationInfo( - txid: txHash, - confirmed: false, - paymentCodeString: preparedTx["address"] as String, - ); + // TODO: only refresh transaction data + try { + await refresh(); + } catch (e) { + Logging.instance.log( + "refresh() failed in confirmNotificationTx ($walletName::$walletId): $e", + level: LogLevel.Error, + ); + } + return txHash; } catch (e, s) { Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", @@ -484,63 +433,12 @@ extension PayNym on DogecoinWallet { } } - // Future<bool> hasConfirmedNotificationTxSentTo( - // String paymentCodeString) async { - // final targetPaymentCode = - // PaymentCode.fromPaymentCode(paymentCodeString, network); - // final targetNotificationAddress = targetPaymentCode.notificationAddress(); - // - // final myTxHistory = (await transactionData) - // .getAllTransactions() - // .entries - // .map((e) => e.value) - // .where((e) => - // e.txType == "Sent" && e.address == targetNotificationAddress); - // - // return myTxHistory.isNotEmpty; - // } - bool hasConnected(String paymentCodeString) { - return getPaynymNotificationTxInfo() - .values - .where((e) => e["paymentCodeString"] == paymentCodeString) - .isNotEmpty; - } - - bool hasConnectedConfirmed(String paymentCodeString) { - return getPaynymNotificationTxInfo() - .values - .where((e) => - e["paymentCodeString"] == paymentCodeString && - e["confirmed"] == true) - .isNotEmpty; - } - - // fetch paynym notification tx meta data - Map<String, dynamic> getPaynymNotificationTxInfo() { - final map = DB.instance.get<dynamic>( - boxName: walletId, key: "paynymNotificationTxInfo") as Map? ?? - {}; - - return Map<String, dynamic>.from(map); - } - - // add/update paynym notification tx meta data entry - Future<void> updatePaynymNotificationInfo({ - required String txid, - required bool confirmed, - required String paymentCodeString, - }) async { - final data = getPaynymNotificationTxInfo(); - data[txid] = { - "txid": txid, - "confirmed": confirmed, - "paymentCodeString": paymentCodeString, - }; - await DB.instance.put<dynamic>( - boxName: walletId, - key: "paynymNotificationTxInfo", - value: data, - ); + return db + .getTransactions(walletId) + .filter() + .address((q) => q.valueEqualTo(paymentCodeString)) + .countSync() > + 0; } } diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 1c083d3bd..7d0fdea6f 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -2776,7 +2776,7 @@ class DogecoinWallet extends CoinServiceAPI // Dogecoin Network final dogecoin = NetworkType( messagePrefix: '\x18Dogecoin Signed Message:\n', - bech32: 'bc', + // bech32: 'bc', bip32: Bip32Type(public: 0x02facafd, private: 0x02fac398), pubKeyHash: 0x1e, scriptHash: 0x16, @@ -2784,7 +2784,7 @@ final dogecoin = NetworkType( final dogecointestnet = NetworkType( messagePrefix: '\x18Dogecoin Signed Message:\n', - bech32: 'tb', + // bech32: 'tb', bip32: Bip32Type(public: 0x043587cf, private: 0x04358394), pubKeyHash: 0x71, scriptHash: 0xc4, diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index 9a2c950d6..b8e40bb52 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -15,7 +15,9 @@ mixin ElectrumXParsing { String walletId, ) async { Set<String> receivingAddresses = myAddresses - .where((e) => e.subType == AddressSubType.receiving) + .where((e) => + e.subType == AddressSubType.receiving || + e.subType == AddressSubType.paynymNotification) .map((e) => e.value) .toSet(); Set<String> changeAddresses = myAddresses @@ -146,13 +148,19 @@ mixin ElectrumXParsing { amount = amountReceivedInWallet; } + bool isNotificationTx = coin.hasPaynymSupport && + type == TransactionType.incoming && + transactionAddress.subType == AddressSubType.paynymNotification; + final tx = Transaction( walletId: walletId, txid: txData["txid"] as String, timestamp: txData["blocktime"] as int? ?? (DateTime.now().millisecondsSinceEpoch ~/ 1000), type: type, - subType: TransactionSubType.none, + subType: isNotificationTx + ? TransactionSubType.bip47Notification + : TransactionSubType.none, amount: amount, fee: fee, height: txData["height"] as int?, diff --git a/lib/services/mixins/paynym_support.dart b/lib/services/mixins/paynym_support.dart new file mode 100644 index 000000000..3bea5aee6 --- /dev/null +++ b/lib/services/mixins/paynym_support.dart @@ -0,0 +1,569 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:bip32/bip32.dart' as bip32; +import 'package:bip47/bip47.dart'; +import 'package:bip47/src/util.dart'; +import 'package:bitcoindart/bitcoindart.dart' as btc_dart; +import 'package:bitcoindart/src/utils/constants/op.dart' as op; +import 'package:bitcoindart/src/utils/script.dart' as bscript; +import 'package:isar/isar.dart'; +import 'package:pointycastle/digests/sha256.dart'; +import 'package:stackwallet/db/main_db.dart'; +import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; +import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/utilities/address_utils.dart'; +import 'package:stackwallet/utilities/bip32_utils.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/logger.dart'; +import 'package:tuple/tuple.dart'; +import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; + +mixin PaynymSupport { + late final btc_dart.NetworkType network; + late final MainDB db; + late final Coin coin; + late final String walletId; + void initPaynymSupport({ + required btc_dart.NetworkType network, + required MainDB db, + required Coin coin, + required String walletId, + }) { + this.network = network; + this.db = db; + this.coin = coin; + this.walletId = walletId; + } + + // generate bip32 payment code root + Future<bip32.BIP32> getRootNode({required List<String> mnemonic}) async { + final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); + return root; + } + + // fetch or generate this wallet's bip47 payment code + Future<PaymentCode> getPaymentCode({ + required List<String> mnemonic, + }) async { + // TODO: cache elsewhere + // final paymentCodeString = DB.instance + // .get<dynamic>(boxName: walletId, key: "paymentCodeString") as String?; + PaymentCode paymentCode; + // if (paymentCodeString == null) { + final root = await getRootNode(mnemonic: mnemonic); + final node = root.derivePath("m/47'/0'/0'"); + paymentCode = + PaymentCode.initFromPubKey(node.publicKey, node.chainCode, network); + // await DB.instance.put<dynamic>( + // boxName: walletId, + // key: "paymentCodeString", + // value: paymentCode.toString()); + // } else { + // paymentCode = PaymentCode.fromPaymentCode(paymentCodeString, network); + // } + return paymentCode; + } + + Future<Uint8List> signWithNotificationKey({ + required Uint8List data, + required List<String> mnemonic, + }) async { + final root = await getRootNode( + mnemonic: mnemonic, + ); + final node = root.derivePath("m/47'/0'/0'"); + final pair = btc_dart.ECPair.fromPrivateKey(node.privateKey!, network: network); + final signed = pair.sign(SHA256Digest().process(data)); + return signed; + } + + Future<String> signStringWithNotificationKey({ + required String data, + required List<String> mnemonic, + }) async { + final bytes = await signWithNotificationKey( + data: Uint8List.fromList(utf8.encode(data)), + mnemonic: mnemonic, + ); + return Format.uint8listToString(bytes); + // final bytes = + // await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); + // return Format.uint8listToString(bytes); + } + + /// Update cached lists of notification transaction IDs. + /// Returns true if there are new notification transactions found since last + /// checked. + Future<bool> checkForNotificationTransactions({ + required Coin coin, + required PaymentCode paymentCode, + required ElectrumX electrumXClient, + required CachedElectrumX cachedElectrumXClient, + required int currentChainHeight, + }) async { + final notificationAddress = paymentCode.notificationAddress(); + + final receivedNotificationTransactions = await db + .getTransactions(walletId) + .filter() + .address((q) => q.valueEqualTo(notificationAddress)) + .findAll(); + + + final unconfirmedTransactions = receivedNotificationTransactions.where( + (e) => !e.isConfirmed( + currentChainHeight, + coin.requiredConfirmations, + ), + ); + + final totalStoredCount = receivedNotificationTransactions.length; + final storedUnconfirmedCount = unconfirmedTransactions.length; + + // for (final txid in transactionIds) { + // final tx = await cachedElectrumXClient.getTransaction( + // txHash: txid, + // coin: coin, + // ); + // + // // check if tx is confirmed + // if ((tx["confirmations"] as int? ?? 0) > coin.requiredConfirmations) { + // // remove it from unconfirmed set + // unconfirmedNotificationTransactionIds.remove(txid); + // + // // add it to confirmed set + // confirmedNotificationTransactionIds.add(txid); + // } else { + // // otherwise add it to the unconfirmed set + // unconfirmedNotificationTransactionIds.add(txid); + // } + // } + // + // final newTotalCount = confirmedNotificationTransactionIds.length + + // unconfirmedNotificationTransactionIds.length; + // + // return newTotalCount > totalCount; + return false; + } + + // bool hasConnected(String paymentCodeString) { + // return getPaynymNotificationTxInfo() + // .values + // .where((e) => e["paymentCodeString"] == paymentCodeString) + // .isNotEmpty; + // } + // + // bool hasConnectedConfirmed(String paymentCodeString) { + // return getPaynymNotificationTxInfo() + // .values + // .where((e) => + // e["paymentCodeString"] == paymentCodeString && + // e["confirmed"] == true) + // .isNotEmpty; + // } + // + // // fetch paynym notification tx meta data + // Map<String, dynamic> getPaynymNotificationTxInfo() { + // final map = DB.instance.get<dynamic>( + // boxName: walletId, key: "paynymNotificationTxInfo") as Map? ?? + // {}; + // + // return Map<String, dynamic>.from(map); + // } + + // // add/update paynym notification tx meta data entry + // Future<void> updatePaynymNotificationInfo({ + // required String txid, + // required bool confirmed, + // required String paymentCodeString, + // }) async { + // final data = getPaynymNotificationTxInfo(); + // data[txid] = { + // "txid": txid, + // "confirmed": confirmed, + // "paymentCodeString": paymentCodeString, + // }; + // await DB.instance.put<dynamic>( + // boxName: walletId, + // key: "paynymNotificationTxInfo", + // value: data, + // ); + // } + + Future<Transaction?> hasSentNotificationTx(PaymentCode pCode) async { + final tx = await db + .getTransactions(walletId) + .filter() + .address((q) => q.valueEqualTo(pCode.notificationAddress())).countSync() + .findFirst(); + return tx; + } + + void preparePaymentCodeSend(PaymentCode pCode) async { + final notifTx = await hasSentNotificationTx(pCode); + final currentHeight = await chainHeight; + + if (notifTx == null) { + throw PaynymSendException("No notification transaction sent to $pCode"); + } else if (!notifTx.isConfirmed(currentHeight, MINIMUM_CONFIRMATIONS)) { + throw PaynymSendException( + "Notification transaction sent to $pCode has not confirmed yet"); + } else { + final node = getBip32Root((await mnemonic).join(" "), network) + .derivePath("m/47'/0'/0'"); + final sendToAddress = await nextUnusedSendAddressFrom( + pCode, + node.derive(0).privateKey!, + ); + + // todo: Actual transaction build + } + } + + /// get the next unused address to send to given the receiver's payment code + /// and your own private key + Future<String> nextUnusedSendAddressFrom( + PaymentCode pCode, + Uint8List privateKey, + ) async { + // https://en.bitcoin.it/wiki/BIP_0047#Path_levels + const maxCount = 2147483647; + + final paymentAddress = PaymentAddress.initWithPrivateKey( + privateKey, + pCode, + 0, // initial index to check + ); + + for ( ; + paymentAddress.index <= maxCount; + paymentAddress.index++) { + final address = paymentAddress.getSendAddress(); + + final transactionIds = await electrumXClient.getHistory( + scripthash: AddressUtils.convertToScriptHash( + address, + network, + ), + ); + + if (transactionIds.isEmpty) { + return address; + } + } + + throw PaynymSendException("Exhausted unused send addresses!"); + } + + /// get your receiving addresses given the sender's payment code and your own + /// private key + List<String> deriveReceivingAddressesFor( + PaymentCode pCode, + Uint8List privateKey, + int count, + ) { + // https://en.bitcoin.it/wiki/BIP_0047#Path_levels + const maxCount = 2147483647; + assert(count <= maxCount); + + final paymentAddress = PaymentAddress.initWithPrivateKey( + privateKey, + pCode, + 0, // initial index + ); + + final List<String> result = []; + for (paymentAddress.index = 0; + paymentAddress.index < count; + paymentAddress.index++) { + final address = paymentAddress.getReceiveAddress(); + + result.add(address); + } + + return result; + } + + Future<Map<String, dynamic>> buildNotificationTx({ + required int selectedTxFeeRate, + required String targetPaymentCodeString, + required PaymentCode myPaymentCode, + int additionalOutputs = 0, + required List<UTXO> utxos, + required int dustLimit, + required int chainHeight, + required Future<Map<String, dynamic>> Function( + List< UTXO> + ) fetchBuildTxData, + }) async { + final amountToSend = dustLimit; + final List<UTXO> availableOutputs = utxos ; + final List<UTXO> spendableOutputs = []; + int spendableSatoshiValue = 0; + + // Build list of spendable outputs and totaling their satoshi amount + for (var i = 0; i < availableOutputs.length; i++) { + if (availableOutputs[i].isBlocked == false && + availableOutputs[i] + .isConfirmed( chainHeight, coin.requiredConfirmations) == + true) { + spendableOutputs.add(availableOutputs[i]); + spendableSatoshiValue += availableOutputs[i].value; + } + } + + if (spendableSatoshiValue < amountToSend) { + // insufficient balance + throw InsufficientBalanceException( + "Spendable balance is less than the minimum required for a notification transaction."); + } else if (spendableSatoshiValue == amountToSend) { + // insufficient balance due to missing amount to cover fee + throw InsufficientBalanceException( + "Remaining balance does not cover the network fee."); + } + + // sort spendable by age (oldest first) + spendableOutputs.sort((a, b) => b.blockTime!.compareTo(a.blockTime!)); + + int satoshisBeingUsed = 0; + int outputsBeingUsed = 0; + List<UTXO> utxoObjectsToUse = []; + + for (int i = 0; + satoshisBeingUsed < amountToSend && i < spendableOutputs.length; + i++) { + utxoObjectsToUse.add(spendableOutputs[i]); + satoshisBeingUsed += spendableOutputs[i].value; + outputsBeingUsed += 1; + } + + // add additional outputs if required + for (int i = 0; + i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; + i++) { + utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); + satoshisBeingUsed += spendableOutputs[outputsBeingUsed].value; + outputsBeingUsed += 1; + } + + // gather required signing data + final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse); + + final int vSizeForNoChange = (await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0, myPaymentCode: myPaymentCode, dustLimit: dustLimit, changeAddress: )) + .item2; + + final int vSizeForWithChange = (await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: satoshisBeingUsed - amountToSend, myPaymentCode: myPaymentCode, dustLimit: dustLimit, changeAddress: ch,)) + .item2; + + // Assume 2 outputs, for recipient and payment code script + int feeForNoChange = estimateTxFee( + vSize: vSizeForNoChange, + feeRatePerKB: selectedTxFeeRate, + ); + + // Assume 3 outputs, for recipient, payment code script, and change + int feeForWithChange = estimateTxFee( + vSize: vSizeForWithChange, + feeRatePerKB: selectedTxFeeRate, + ); + + if (feeForNoChange < vSizeForNoChange * 1000) { + feeForNoChange = vSizeForNoChange * 1000; + } + if (feeForWithChange < vSizeForWithChange * 1000) { + feeForWithChange = vSizeForWithChange * 1000; + } + + if (satoshisBeingUsed - amountToSend > feeForNoChange + dustLimit) { + // try to add change output due to "left over" amount being greater than + // the estimated fee + the dust limit + int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; + + // check estimates are correct and build notification tx + if (changeAmount >= dustLimit && + satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { + final txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: changeAmount, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } else { + // something broke during fee estimation or the change amount is smaller + // than the dust limit. Try without change + final txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend; + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } + } else if (satoshisBeingUsed - amountToSend >= feeForNoChange) { + // since we already checked if we need to add a change output we can just + // build without change here + final txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0, myPaymentCode: null, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend; + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } else { + // if we get here we do not have enough funds to cover the tx total so we + // check if we have any more available outputs and try again + if (spendableOutputs.length > outputsBeingUsed) { + return buildNotificationTx( + selectedTxFeeRate: selectedTxFeeRate, + targetPaymentCodeString: targetPaymentCodeString, + additionalOutputs: additionalOutputs + 1, utxos: utxos, dustLimit: dustLimit, chainHeight: chainHeight, fetchBuildTxData: fetchBuildTxData, + ); + } else { + throw InsufficientBalanceException( + "Remaining balance does not cover the network fee."); + } + } + } + + // return tuple with string value equal to the raw tx hex and the int value + // equal to its vSize + Future<Tuple2<String, int>> _createNotificationTx({ + required String targetPaymentCodeString, + required PaymentCode myPaymentCode, + required List<UTXO> utxosToUse, + required Map<String, dynamic> utxoSigningData, + required int change, + required int dustLimit, + required Address changeAddress, + }) async { + final targetPaymentCode = + PaymentCode.fromPaymentCode(targetPaymentCodeString, network); + + final utxo = utxosToUse.first; + final txPoint = utxo.txid.fromHex.toList(); + final txPointIndex = utxo.vout; + + final rev = Uint8List(txPoint.length + 4); + Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); + final buffer = rev.buffer.asByteData(); + buffer.setUint32(txPoint.length, txPointIndex, Endian.little); + + final myKeyPair = utxoSigningData[utxo.txid]["keyPair"] as btc_dart.ECPair; + + final S = SecretPoint( + myKeyPair.privateKey!, + targetPaymentCode.notificationPublicKey(), + ); + + final blindingMask = PaymentCode.getMask(S.ecdhSecret(), rev); + + final blindedPaymentCode = PaymentCode.blind( + myPaymentCode.getPayload(), + blindingMask, + ); + + final opReturnScript = bscript.compile([ + (op.OPS["OP_RETURN"] as int), + blindedPaymentCode, + ]); + + // build a notification tx + final txb = btc_dart.TransactionBuilder(network: network); + txb.setVersion(1); + + txb.addInput( + utxo.txid, + txPointIndex, + ); + + txb.addOutput(targetPaymentCode.notificationAddress(), dustLimit); + txb.addOutput(opReturnScript, 0); + + // TODO: add possible change output and mark output as dangerous + if (change > 0) { + final String changeAddressString = changeAddress.value; + txb.addOutput(changeAddressString, change); + } + + txb.sign( + vin: 0, + keyPair: myKeyPair, + ); + + // sign rest of possible inputs + for (var i = 1; i < utxosToUse.length - 1; i++) { + final txid = utxosToUse[i].txid; + txb.sign( + vin: i, + keyPair: utxoSigningData[txid]["keyPair"] as ECPair, + // witnessValue: utxosToUse[i].value, + ); + } + + final builtTx = txb.build(); + + return Tuple2(builtTx.toHex(), builtTx.virtualSize()); + } + + Future<String> confirmSendNotificationTx( + {required Map<String, dynamic> preparedTx, required ElectrumX electrumXClient,}) async { + try { + Logging.instance.log("confirmNotificationTx txData: $preparedTx", + level: LogLevel.Info); + final txHash = await electrumXClient.broadcastTransaction( + rawTx: preparedTx["hex"] as String); + Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); + + + return txHash; + } catch (e, s) { + Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", + level: LogLevel.Error); + rethrow; + } + } + +} diff --git a/lib/utilities/bip32_utils.dart b/lib/utilities/bip32_utils.dart new file mode 100644 index 000000000..50549938f --- /dev/null +++ b/lib/utilities/bip32_utils.dart @@ -0,0 +1,32 @@ +import 'package:bip32/bip32.dart' as bip32; +import 'package:bip39/bip39.dart' as bip39; +import 'package:bitcoindart/bitcoindart.dart'; +import 'package:flutter/foundation.dart'; +import 'package:tuple/tuple.dart'; + +abstract class Bip32Utils { + static bip32.BIP32 getBip32RootSync(String mnemonic, NetworkType network) { + final seed = bip39.mnemonicToSeed(mnemonic); + final networkType = bip32.NetworkType( + wif: network.wif, + bip32: bip32.Bip32Type( + public: network.bip32.public, + private: network.bip32.private, + ), + ); + + final root = bip32.BIP32.fromSeed(seed, networkType); + return root; + } + + static Future<bip32.BIP32> getBip32Root( + String mnemonic, NetworkType network) async { + final root = await compute(_getBip32RootWrapper, Tuple2(mnemonic, network)); + return root; + } + + /// wrapper for compute() + static bip32.BIP32 _getBip32RootWrapper(Tuple2<String, NetworkType> args) { + return getBip32RootSync(args.item1, args.item2); + } +} From 5eb4b3bff5a57015d219f5ac3fd688f02fc40cbf Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 13:46:56 -0600 Subject: [PATCH 008/123] move tx creation after ins/outs and added another null check --- lib/services/mixins/electrum_x_parsing.dart | 39 +++++++++++---------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index b8e40bb52..49f28a50c 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -152,24 +152,6 @@ mixin ElectrumXParsing { type == TransactionType.incoming && transactionAddress.subType == AddressSubType.paynymNotification; - final tx = Transaction( - walletId: walletId, - txid: txData["txid"] as String, - timestamp: txData["blocktime"] as int? ?? - (DateTime.now().millisecondsSinceEpoch ~/ 1000), - type: type, - subType: isNotificationTx - ? TransactionSubType.bip47Notification - : TransactionSubType.none, - amount: amount, - fee: fee, - height: txData["height"] as int?, - isCancelled: false, - isLelantus: false, - slateId: null, - otherData: null, - ); - List<Output> outs = []; List<Input> ins = []; @@ -196,7 +178,8 @@ mixin ElectrumXParsing { scriptPubKeyType: json['scriptPubKey']?['type'] as String?, scriptPubKeyAddress: json["scriptPubKey"]?["addresses"]?[0] as String? ?? - json['scriptPubKey']['type'] as String, + json['scriptPubKey']?['type'] as String? ?? + "", value: Format.decimalAmountToSatoshis( Decimal.parse(json["value"].toString()), coin, @@ -205,6 +188,24 @@ mixin ElectrumXParsing { outs.add(output); } + final tx = Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: txData["blocktime"] as int? ?? + (DateTime.now().millisecondsSinceEpoch ~/ 1000), + type: type, + subType: isNotificationTx + ? TransactionSubType.bip47Notification + : TransactionSubType.none, + amount: amount, + fee: fee, + height: txData["height"] as int?, + isCancelled: false, + isLelantus: false, + slateId: null, + otherData: null, + ); + return Tuple4(tx, outs, ins, transactionAddress); } } From 8a7d669b62c1b93162104d85ac4af03a6a9cc633 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 15:39:05 -0600 Subject: [PATCH 009/123] async hasConnected ui update --- .../paynym/dialogs/paynym_details_popup.dart | 66 +++++++++++---- .../subwidgets/desktop_paynym_details.dart | 81 +++++++++++-------- 2 files changed, 98 insertions(+), 49 deletions(-) diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index 4190aab8d..5150d9bb2 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -44,6 +44,10 @@ class PaynymDetailsPopup extends ConsumerStatefulWidget { class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { bool _showInsufficientFundsInfo = false; + Future<void> _onSend() async { + // todo send + } + Future<void> _onConnectPressed() async { bool canPop = false; unawaited( @@ -63,7 +67,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { .getManager(widget.walletId) .wallet as DogecoinWallet; - if (wallet.hasConnected(widget.accountLite.code)) { + if (await wallet.hasConnected(widget.accountLite.code)) { canPop = true; Navigator.of(context).pop(); // TODO show info popup @@ -136,6 +140,9 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { @override Widget build(BuildContext context) { + final wallet = ref.watch(walletsChangeNotifierProvider.select( + (value) => value.getManager(widget.walletId).wallet as DogecoinWallet)); + return DesktopDialog( maxWidth: MediaQuery.of(context).size.width - 32, maxHeight: double.infinity, @@ -168,20 +175,49 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { ), ], ), - PrimaryButton( - label: "Connect", - buttonHeight: ButtonHeight.l, - icon: SvgPicture.asset( - Assets.svg.circlePlusFilled, - width: 10, - height: 10, - color: Theme.of(context) - .extension<StackColors>()! - .buttonTextPrimary, - ), - iconSpacing: 4, - width: 86, - onPressed: _onConnectPressed, + FutureBuilder( + future: wallet.hasConnected(widget.accountLite.code), + builder: (context, AsyncSnapshot<bool> snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + if (snapshot.data!) { + return PrimaryButton( + label: "Send", + buttonHeight: ButtonHeight.s, + icon: SvgPicture.asset( + Assets.svg.circleArrowUpRight, + width: 16, + height: 16, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + iconSpacing: 6, + onPressed: _onSend, + ); + } else { + return PrimaryButton( + label: "Connect", + buttonHeight: ButtonHeight.s, + icon: SvgPicture.asset( + Assets.svg.circlePlusFilled, + width: 16, + height: 16, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + iconSpacing: 6, + onPressed: _onConnectPressed, + ); + } + } else { + return const SizedBox( + height: 100, + child: LoadingIndicator(), + ); + } + }, ), ], ), diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index 4e69a7586..ac33ce475 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -63,7 +63,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { .getManager(widget.walletId) .wallet as DogecoinWallet; - if (wallet.hasConnected(widget.accountLite.code)) { + if (await wallet.hasConnected(widget.accountLite.code)) { canPop = true; Navigator.of(context, rootNavigator: true).pop(); // TODO show info popup @@ -187,40 +187,53 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { ), Row( children: [ - if (!wallet.hasConnected(widget.accountLite.code)) - Expanded( - child: PrimaryButton( - label: "Connect", - buttonHeight: ButtonHeight.s, - icon: SvgPicture.asset( - Assets.svg.circlePlusFilled, - width: 16, - height: 16, - color: Theme.of(context) - .extension<StackColors>()! - .buttonTextPrimary, - ), - iconSpacing: 6, - onPressed: _onConnectPressed, - ), - ), - if (wallet.hasConnected(widget.accountLite.code)) - Expanded( - child: PrimaryButton( - label: "Send", - buttonHeight: ButtonHeight.s, - icon: SvgPicture.asset( - Assets.svg.circleArrowUpRight, - width: 16, - height: 16, - color: Theme.of(context) - .extension<StackColors>()! - .buttonTextPrimary, - ), - iconSpacing: 6, - onPressed: _onSend, - ), + Expanded( + child: FutureBuilder( + future: wallet.hasConnected(widget.accountLite.code), + builder: (context, AsyncSnapshot<bool> snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.hasData) { + if (snapshot.data!) { + return PrimaryButton( + label: "Send", + buttonHeight: ButtonHeight.s, + icon: SvgPicture.asset( + Assets.svg.circleArrowUpRight, + width: 16, + height: 16, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + iconSpacing: 6, + onPressed: _onSend, + ); + } else { + return PrimaryButton( + label: "Connect", + buttonHeight: ButtonHeight.s, + icon: SvgPicture.asset( + Assets.svg.circlePlusFilled, + width: 16, + height: 16, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + iconSpacing: 6, + onPressed: _onConnectPressed, + ); + } + } else { + return const SizedBox( + height: 100, + child: LoadingIndicator(), + ); + } + }, ), + ), const SizedBox( width: 20, ), From 2259e15da88798ddf0c3f0c766e77aecace0d999 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 15:39:19 -0600 Subject: [PATCH 010/123] re enable paynym --- lib/utilities/enums/coin_enum.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart index 2f952651d..a517992de 100644 --- a/lib/utilities/enums/coin_enum.dart +++ b/lib/utilities/enums/coin_enum.dart @@ -190,8 +190,7 @@ extension CoinExt on Coin { case Coin.dogecoin: case Coin.dogecoinTestNet: - // return true; - return false; + return true; } } From 6498e1926cbaa3284acb8e2faf88808d547e6a29 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 15:42:39 -0600 Subject: [PATCH 011/123] size fixes --- .../paynym/dialogs/paynym_details_popup.dart | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index 5150d9bb2..295eff134 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -183,37 +183,39 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { if (snapshot.data!) { return PrimaryButton( label: "Send", - buttonHeight: ButtonHeight.s, + buttonHeight: ButtonHeight.l, icon: SvgPicture.asset( Assets.svg.circleArrowUpRight, - width: 16, - height: 16, + width: 10, + height: 10, color: Theme.of(context) .extension<StackColors>()! .buttonTextPrimary, ), - iconSpacing: 6, + iconSpacing: 4, + width: 86, onPressed: _onSend, ); } else { return PrimaryButton( label: "Connect", - buttonHeight: ButtonHeight.s, + buttonHeight: ButtonHeight.l, icon: SvgPicture.asset( Assets.svg.circlePlusFilled, - width: 16, - height: 16, + width: 10, + height: 10, color: Theme.of(context) .extension<StackColors>()! .buttonTextPrimary, ), - iconSpacing: 6, + iconSpacing: 4, + width: 86, onPressed: _onConnectPressed, ); } } else { return const SizedBox( - height: 100, + height: 32, child: LoadingIndicator(), ); } From 6253652c21cfe4d175e0ea2898585a1cdeb821c8 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Jan 2023 16:11:24 -0600 Subject: [PATCH 012/123] detect paynym notification transactions --- lib/services/coins/coin_paynym_extension.dart | 62 ++++++++++++++++--- .../coins/dogecoin/dogecoin_wallet.dart | 6 +- lib/services/mixins/electrum_x_parsing.dart | 23 ++++--- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index 2ad0e4475..b2ccfda9e 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -28,7 +28,7 @@ extension PayNym on DogecoinWallet { return root; } - // fetch or generate this wallet's bip47 payment code + /// fetch or generate this wallet's bip47 payment code Future<PaymentCode> getPaymentCode() async { final address = await db .getAddresses(walletId) @@ -75,7 +75,7 @@ extension PayNym on DogecoinWallet { } void preparePaymentCodeSend(PaymentCode pCode) async { - if (!hasConnected(pCode.notificationAddress())) { + if (!(await hasConnected(pCode.notificationAddress()))) { throw PaynymSendException("No notification transaction sent to $pCode"); } else { final root = await getRootNode(mnemonic: await mnemonic); @@ -433,12 +433,56 @@ extension PayNym on DogecoinWallet { } } - bool hasConnected(String paymentCodeString) { - return db - .getTransactions(walletId) - .filter() - .address((q) => q.valueEqualTo(paymentCodeString)) - .countSync() > - 0; + // TODO optimize + Future<bool> hasConnected(String paymentCodeString) async { + final myCode = await getPaymentCode(); + final myNotificationAddress = myCode.notificationAddress(); + + final txns = await db + .getTransactions(walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .findAll(); + + for (final tx in txns) { + if (tx.address.value?.value == myNotificationAddress) { + return true; + } + + final blindedCode = + tx.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1]; + + final designatedInput = tx.inputs.first; + + final txPoint = designatedInput.txid.fromHex.toList(); + final txPointIndex = designatedInput.vout; + + final rev = Uint8List(txPoint.length + 4); + Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); + final buffer = rev.buffer.asByteData(); + buffer.setUint32(txPoint.length, txPointIndex, Endian.little); + + final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex; + + final root = await getRootNode(mnemonic: await mnemonic); + final myPrivateKey = + root.derivePath(kPaynymDerivePath).derive(0).privateKey!; + + final S = SecretPoint(myPrivateKey, pubKey); + + final mask = PaymentCode.getMask(S.ecdhSecret(), rev); + + final unBlindedPayload = PaymentCode.blind(blindedCode.fromHex, mask); + + final unBlindedPaymentCode = + PaymentCode.initFromPayload(unBlindedPayload); + + if (paymentCodeString == unBlindedPaymentCode.toString()) { + return true; + } + } + + // otherwise return no + return false; } } diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 7d0fdea6f..c47ad8947 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -1162,10 +1162,8 @@ class DogecoinWallet extends CoinServiceAPI .not() .typeEqualTo(isar_models.AddressType.nonWallet) .and() - .group((q) => q - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .or() - .subTypeEqualTo(isar_models.AddressSubType.change)) + .not() + .subTypeEqualTo(isar_models.AddressSubType.nonWallet) .findAll(); return allAddresses; } diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index 49f28a50c..b9b815594 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -1,3 +1,4 @@ +import 'package:bip47/src/util.dart'; import 'package:decimal/decimal.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -148,10 +149,6 @@ mixin ElectrumXParsing { amount = amountReceivedInWallet; } - bool isNotificationTx = coin.hasPaynymSupport && - type == TransactionType.incoming && - transactionAddress.subType == AddressSubType.paynymNotification; - List<Output> outs = []; List<Input> ins = []; @@ -188,15 +185,27 @@ mixin ElectrumXParsing { outs.add(output); } + TransactionSubType txSubType = TransactionSubType.none; + if (coin.hasPaynymSupport && outs.length > 1) { + List<String>? scriptChunks = outs[1].scriptPubKeyAsm?.split(" "); + if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { + final blindedPaymentCode = scriptChunks![1]; + final bytes = blindedPaymentCode.fromHex; + + // https://en.bitcoin.it/wiki/BIP_0047#Sending + if (bytes.length == 80 && bytes.first == 1) { + txSubType = TransactionSubType.bip47Notification; + } + } + } + final tx = Transaction( walletId: walletId, txid: txData["txid"] as String, timestamp: txData["blocktime"] as int? ?? (DateTime.now().millisecondsSinceEpoch ~/ 1000), type: type, - subType: isNotificationTx - ? TransactionSubType.bip47Notification - : TransactionSubType.none, + subType: txSubType, amount: amount, fee: fee, height: txData["height"] as int?, From 83c0beb2ee03aa6a47c03b532997570226f77f15 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Jan 2023 15:29:45 -0600 Subject: [PATCH 013/123] disable libmonero tests in sw --- .../coins/monero/monero_wallet_test.dart | 449 +++++------ .../coins/wownero/wownero_wallet_test.dart | 727 +++++++++--------- 2 files changed, 591 insertions(+), 585 deletions(-) diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart index 4f45c4224..d33c1b460 100644 --- a/test/services/coins/monero/monero_wallet_test.dart +++ b/test/services/coins/monero/monero_wallet_test.dart @@ -1,228 +1,231 @@ import 'dart:core'; -import 'dart:io'; -import 'dart:math'; - -import 'package:cw_core/node.dart'; -import 'package:cw_core/unspent_coins_info.dart'; -import 'package:cw_core/wallet_base.dart'; -import 'package:cw_core/wallet_credentials.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:cw_core/wallet_service.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:cw_monero/monero_wallet.dart'; -import 'package:flutter_libmonero/core/key_service.dart'; -import 'package:flutter_libmonero/core/wallet_creation_service.dart'; -import 'package:flutter_libmonero/monero/monero.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:hive/hive.dart'; -import 'package:hive_test/hive_test.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:stackwallet/services/wallets.dart'; -import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; - -import 'monero_wallet_test_data.dart'; - -FakeSecureStorage? storage; -WalletService? walletService; -KeyService? keysStorage; -MoneroWalletBase? walletBase; -late WalletCreationService _walletCreationService; -dynamic _walletInfoSource; -Wallets? walletsService; - -String path = ''; - -String name = 'namee${Random().nextInt(10000000)}'; -int nettype = 0; -WalletType type = WalletType.monero; +// import 'dart:io'; +// import 'dart:math'; +// +// TODO: move these tests to libmonero +// TODO: use temp dir for wallets testing and not production location +// +// import 'package:cw_core/node.dart'; +// import 'package:cw_core/unspent_coins_info.dart'; +// import 'package:cw_core/wallet_base.dart'; +// import 'package:cw_core/wallet_credentials.dart'; +// import 'package:cw_core/wallet_info.dart'; +// import 'package:cw_core/wallet_service.dart'; +// import 'package:cw_core/wallet_type.dart'; +// import 'package:cw_monero/monero_wallet.dart'; +// import 'package:flutter_libmonero/core/key_service.dart'; +// import 'package:flutter_libmonero/core/wallet_creation_service.dart'; +// import 'package:flutter_libmonero/monero/monero.dart'; +// import 'package:flutter_test/flutter_test.dart'; +// import 'package:hive/hive.dart'; +// import 'package:hive_test/hive_test.dart'; +// import 'package:path_provider/path_provider.dart'; +// import 'package:stackwallet/services/wallets.dart'; +// import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; +// +// import 'monero_wallet_test_data.dart'; +// +// FakeSecureStorage? storage; +// WalletService? walletService; +// KeyService? keysStorage; +// MoneroWalletBase? walletBase; +// late WalletCreationService _walletCreationService; +// dynamic _walletInfoSource; +// Wallets? walletsService; +// +// String path = ''; +// +// String name = 'namee${Random().nextInt(10000000)}'; +// int nettype = 0; +// WalletType type = WalletType.monero; void main() async { - storage = FakeSecureStorage(); - keysStorage = KeyService(storage!); - WalletInfo walletInfo = WalletInfo.external( - id: '', - name: '', - type: type, - isRecovery: false, - restoreHeight: 0, - date: DateTime.now(), - path: '', - address: '', - dirPath: ''); - late WalletCredentials credentials; - - monero.onStartup(); - - bool hiveAdaptersRegistered = false; - - group("Mainnet tests", () { - setUp(() async { - await setUpTestHive(); - if (!hiveAdaptersRegistered) { - hiveAdaptersRegistered = true; - - Hive.registerAdapter(NodeAdapter()); - Hive.registerAdapter(WalletInfoAdapter()); - Hive.registerAdapter(WalletTypeAdapter()); - Hive.registerAdapter(UnspentCoinsInfoAdapter()); - - final wallets = await Hive.openBox<dynamic>('wallets'); - await wallets.put('currentWalletName', name); - - _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName); - walletService = monero - .createMoneroWalletService(_walletInfoSource as Box<WalletInfo>); - } - - try { - // if (name?.isEmpty ?? true) { - // name = await generateName(); - // } - final dirPath = await pathForWalletDir(name: name, type: type); - path = await pathForWallet(name: name, type: type); - credentials = - // // creating a new wallet - // monero.createMoneroNewWalletCredentials( - // name: name, language: "English"); - // restoring a previous wallet - monero.createMoneroRestoreWalletFromSeedCredentials( - name: name, height: 2580000, mnemonic: testMnemonic); - - walletInfo = WalletInfo.external( - id: WalletBase.idFor(name, type), - name: name, - type: type, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - address: "", - dirPath: dirPath); - credentials.walletInfo = walletInfo; - - _walletCreationService = WalletCreationService( - secureStorage: storage, - walletService: walletService, - keyService: keysStorage, - ); - _walletCreationService.changeWalletType(); - } catch (e, s) { - print(e); - print(s); - } - }); - - test("Test mainnet address generation from seed", () async { - final wallet = await - // _walletCreationService.create(credentials); - _walletCreationService.restoreFromSeed(credentials); - walletInfo.address = wallet.walletAddresses.address; - //print(walletInfo.address); - - await _walletInfoSource.add(walletInfo); - walletBase?.close(); - walletBase = wallet as MoneroWalletBase; - //print("${walletBase?.seed}"); - - expect(await walletBase!.validateAddress(walletInfo.address ?? ''), true); - - // print(walletBase); - // loggerPrint(walletBase.toString()); - // loggerPrint("name: ${walletBase!.name} seed: ${walletBase!.seed} id: " - // "${walletBase!.id} walletinfo: ${toStringForinfo(walletBase!.walletInfo)} type: ${walletBase!.type} balance: " - // "${walletBase!.balance.entries.first.value.available} currency: ${walletBase!.currency}"); - - expect(walletInfo.address, mainnetTestData[0][0]); - expect(walletBase!.getTransactionAddress(0, 0), mainnetTestData[0][0]); - expect(walletBase!.getTransactionAddress(0, 1), mainnetTestData[0][1]); - expect(walletBase!.getTransactionAddress(0, 2), mainnetTestData[0][2]); - expect(walletBase!.getTransactionAddress(1, 0), mainnetTestData[1][0]); - expect(walletBase!.getTransactionAddress(1, 1), mainnetTestData[1][1]); - expect(walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]); - - expect(walletBase!.validateAddress(''), false); - expect( - walletBase!.validateAddress( - '4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), - true); - expect( - walletBase!.validateAddress( - '4asdfkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gpjkl'), - false); - expect( - walletBase!.validateAddress( - '8AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), - false); - expect( - walletBase!.validateAddress( - '84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), - true); - expect( - walletBase!.validateAddress( - '8asdfuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenjkl'), - false); - expect( - walletBase!.validateAddress( - '44kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), - false); - }); - }); - /* - // Not needed; only folder created, wallet files not saved yet. TODO test saving and deleting wallet files and make sure to clean up leftover folder afterwards - group("Mainnet wallet deletion test", () { - test("Test mainnet wallet existence", () { - expect(monero_wallet_manager.isWalletExistSync(path: path), true); - }); - - test("Test mainnet wallet deletion", () { - // Remove wallet from wallet service - walletService?.remove(name); - walletsService?.removeWallet(walletId: name); - expect(monero_wallet_manager.isWalletExistSync(path: path), false); - }); - }); - - group("Mainnet node tests", () { - test("Test mainnet node connection", () async { - await walletBase?.connectToNode( - node: Node( - uri: "monero-stagenet.stackwallet.com:38081", - type: WalletType.moneroStageNet)); - await walletBase!.rescan( - height: - credentials.height); // Probably shouldn't be rescanning from 0... - await walletBase!.getNodeHeight(); - int height = await walletBase!.getNodeHeight(); - print('height: $height'); - bool connected = await walletBase!.isConnected(); - print('connected: $connected'); - - //expect... - }); - }); - */ - - // TODO test deletion of wallets ... and delete them + // storage = FakeSecureStorage(); + // keysStorage = KeyService(storage!); + // WalletInfo walletInfo = WalletInfo.external( + // id: '', + // name: '', + // type: type, + // isRecovery: false, + // restoreHeight: 0, + // date: DateTime.now(), + // path: '', + // address: '', + // dirPath: ''); + // late WalletCredentials credentials; + // + // monero.onStartup(); + // + // bool hiveAdaptersRegistered = false; + // + // group("Mainnet tests", () { + // setUp(() async { + // await setUpTestHive(); + // if (!hiveAdaptersRegistered) { + // hiveAdaptersRegistered = true; + // + // Hive.registerAdapter(NodeAdapter()); + // Hive.registerAdapter(WalletInfoAdapter()); + // Hive.registerAdapter(WalletTypeAdapter()); + // Hive.registerAdapter(UnspentCoinsInfoAdapter()); + // + // final wallets = await Hive.openBox<dynamic>('wallets'); + // await wallets.put('currentWalletName', name); + // + // _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName); + // walletService = monero + // .createMoneroWalletService(_walletInfoSource as Box<WalletInfo>); + // } + // + // try { + // // if (name?.isEmpty ?? true) { + // // name = await generateName(); + // // } + // final dirPath = await pathForWalletDir(name: name, type: type); + // path = await pathForWallet(name: name, type: type); + // credentials = + // // // creating a new wallet + // // monero.createMoneroNewWalletCredentials( + // // name: name, language: "English"); + // // restoring a previous wallet + // monero.createMoneroRestoreWalletFromSeedCredentials( + // name: name, height: 2580000, mnemonic: testMnemonic); + // + // walletInfo = WalletInfo.external( + // id: WalletBase.idFor(name, type), + // name: name, + // type: type, + // isRecovery: false, + // restoreHeight: credentials.height ?? 0, + // date: DateTime.now(), + // path: path, + // address: "", + // dirPath: dirPath); + // credentials.walletInfo = walletInfo; + // + // _walletCreationService = WalletCreationService( + // secureStorage: storage, + // walletService: walletService, + // keyService: keysStorage, + // ); + // _walletCreationService.changeWalletType(); + // } catch (e, s) { + // print(e); + // print(s); + // } + // }); + // + // test("Test mainnet address generation from seed", () async { + // final wallet = await + // // _walletCreationService.create(credentials); + // _walletCreationService.restoreFromSeed(credentials); + // walletInfo.address = wallet.walletAddresses.address; + // //print(walletInfo.address); + // + // await _walletInfoSource.add(walletInfo); + // walletBase?.close(); + // walletBase = wallet as MoneroWalletBase; + // //print("${walletBase?.seed}"); + // + // expect(await walletBase!.validateAddress(walletInfo.address ?? ''), true); + // + // // print(walletBase); + // // loggerPrint(walletBase.toString()); + // // loggerPrint("name: ${walletBase!.name} seed: ${walletBase!.seed} id: " + // // "${walletBase!.id} walletinfo: ${toStringForinfo(walletBase!.walletInfo)} type: ${walletBase!.type} balance: " + // // "${walletBase!.balance.entries.first.value.available} currency: ${walletBase!.currency}"); + // + // expect(walletInfo.address, mainnetTestData[0][0]); + // expect(walletBase!.getTransactionAddress(0, 0), mainnetTestData[0][0]); + // expect(walletBase!.getTransactionAddress(0, 1), mainnetTestData[0][1]); + // expect(walletBase!.getTransactionAddress(0, 2), mainnetTestData[0][2]); + // expect(walletBase!.getTransactionAddress(1, 0), mainnetTestData[1][0]); + // expect(walletBase!.getTransactionAddress(1, 1), mainnetTestData[1][1]); + // expect(walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]); + // + // expect(walletBase!.validateAddress(''), false); + // expect( + // walletBase!.validateAddress( + // '4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), + // true); + // expect( + // walletBase!.validateAddress( + // '4asdfkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gpjkl'), + // false); + // expect( + // walletBase!.validateAddress( + // '8AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), + // false); + // expect( + // walletBase!.validateAddress( + // '84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), + // true); + // expect( + // walletBase!.validateAddress( + // '8asdfuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenjkl'), + // false); + // expect( + // walletBase!.validateAddress( + // '44kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), + // false); + // }); + // }); + // /* + // // Not needed; only folder created, wallet files not saved yet. TODO test saving and deleting wallet files and make sure to clean up leftover folder afterwards + // group("Mainnet wallet deletion test", () { + // test("Test mainnet wallet existence", () { + // expect(monero_wallet_manager.isWalletExistSync(path: path), true); + // }); + // + // test("Test mainnet wallet deletion", () { + // // Remove wallet from wallet service + // walletService?.remove(name); + // walletsService?.removeWallet(walletId: name); + // expect(monero_wallet_manager.isWalletExistSync(path: path), false); + // }); + // }); + // + // group("Mainnet node tests", () { + // test("Test mainnet node connection", () async { + // await walletBase?.connectToNode( + // node: Node( + // uri: "monero-stagenet.stackwallet.com:38081", + // type: WalletType.moneroStageNet)); + // await walletBase!.rescan( + // height: + // credentials.height); // Probably shouldn't be rescanning from 0... + // await walletBase!.getNodeHeight(); + // int height = await walletBase!.getNodeHeight(); + // print('height: $height'); + // bool connected = await walletBase!.isConnected(); + // print('connected: $connected'); + // + // //expect... + // }); + // }); + // */ + // + // // TODO test deletion of wallets ... and delete them } -Future<String> pathForWalletDir( - {required String name, required WalletType type}) async { - Directory root = (await getApplicationDocumentsDirectory()); - if (Platform.isIOS) { - root = (await getLibraryDirectory()); - } - final prefix = walletTypeToString(type).toLowerCase(); - final walletsDir = Directory('${root.path}/wallets'); - final walletDire = Directory('${walletsDir.path}/$prefix/$name'); - - if (!walletDire.existsSync()) { - walletDire.createSync(recursive: true); - } - - return walletDire.path; -} - -Future<String> pathForWallet( - {required String name, required WalletType type}) async => - await pathForWalletDir(name: name, type: type) - .then((path) => '$path/$name'); +// Future<String> pathForWalletDir( +// {required String name, required WalletType type}) async { +// Directory root = (await getApplicationDocumentsDirectory()); +// if (Platform.isIOS) { +// root = (await getLibraryDirectory()); +// } +// final prefix = walletTypeToString(type).toLowerCase(); +// final walletsDir = Directory('${root.path}/wallets'); +// final walletDire = Directory('${walletsDir.path}/$prefix/$name'); +// +// if (!walletDire.existsSync()) { +// walletDire.createSync(recursive: true); +// } +// +// return walletDire.path; +// } +// +// Future<String> pathForWallet( +// {required String name, required WalletType type}) async => +// await pathForWalletDir(name: name, type: type) +// .then((path) => '$path/$name'); diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart index 42d9e0696..a14fbf3ad 100644 --- a/test/services/coins/wownero/wownero_wallet_test.dart +++ b/test/services/coins/wownero/wownero_wallet_test.dart @@ -1,367 +1,370 @@ import 'dart:core'; -import 'dart:io'; -import 'dart:math'; - -import 'package:cw_core/node.dart'; -import 'package:cw_core/unspent_coins_info.dart'; -import 'package:cw_core/wallet_base.dart'; -import 'package:cw_core/wallet_credentials.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:cw_core/wallet_service.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:cw_wownero/wownero_wallet.dart'; -import 'package:flutter_libmonero/core/key_service.dart'; -import 'package:flutter_libmonero/core/wallet_creation_service.dart'; -import 'package:flutter_libmonero/wownero/wownero.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:hive/hive.dart'; -import 'package:hive_test/hive_test.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; - -import 'wownero_wallet_test_data.dart'; - -FakeSecureStorage? storage; -WalletService? walletService; -KeyService? keysStorage; -WowneroWalletBase? walletBase; -late WalletCreationService _walletCreationService; -dynamic _walletInfoSource; - -String path = ''; - -String name = ''; -int nettype = 0; -WalletType type = WalletType.wownero; +// import 'dart:io'; +// import 'dart:math'; +// +// TODO: move these tests to libmonero +// TODO: use temp dir for wallets testing and not production location +// +// import 'package:cw_core/node.dart'; +// import 'package:cw_core/unspent_coins_info.dart'; +// import 'package:cw_core/wallet_base.dart'; +// import 'package:cw_core/wallet_credentials.dart'; +// import 'package:cw_core/wallet_info.dart'; +// import 'package:cw_core/wallet_service.dart'; +// import 'package:cw_core/wallet_type.dart'; +// import 'package:cw_wownero/wownero_wallet.dart'; +// import 'package:flutter_libmonero/core/key_service.dart'; +// import 'package:flutter_libmonero/core/wallet_creation_service.dart'; +// import 'package:flutter_libmonero/wownero/wownero.dart'; +// import 'package:flutter_test/flutter_test.dart'; +// import 'package:hive/hive.dart'; +// import 'package:hive_test/hive_test.dart'; +// import 'package:path_provider/path_provider.dart'; +// import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; +// +// import 'wownero_wallet_test_data.dart'; +// +// FakeSecureStorage? storage; +// WalletService? walletService; +// KeyService? keysStorage; +// WowneroWalletBase? walletBase; +// late WalletCreationService _walletCreationService; +// dynamic _walletInfoSource; +// +// String path = ''; +// +// String name = ''; +// int nettype = 0; +// WalletType type = WalletType.wownero; void main() async { - storage = FakeSecureStorage(); - keysStorage = KeyService(storage!); - WalletInfo walletInfo = WalletInfo.external( - id: '', - name: '', - type: type, - isRecovery: false, - restoreHeight: 0, - date: DateTime.now(), - path: '', - address: '', - dirPath: ''); - late WalletCredentials credentials; - - wownero.onStartup(); - - bool hiveAdaptersRegistered = false; - - group("Wownero 14 word seed generation", () { - setUp(() async { - await setUpTestHive(); - if (!hiveAdaptersRegistered) { - hiveAdaptersRegistered = true; - - Hive.registerAdapter(NodeAdapter()); - Hive.registerAdapter(WalletInfoAdapter()); - Hive.registerAdapter(WalletTypeAdapter()); - Hive.registerAdapter(UnspentCoinsInfoAdapter()); - - final wallets = await Hive.openBox<dynamic>('wallets'); - await wallets.put('currentWalletName', name); - - _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName); - walletService = wownero - .createWowneroWalletService(_walletInfoSource as Box<WalletInfo>); - } - - bool hasThrown = false; - try { - name = 'namee${Random().nextInt(10000000)}'; - final dirPath = await pathForWalletDir(name: name, type: type); - path = await pathForWallet(name: name, type: type); - credentials = wownero.createWowneroNewWalletCredentials( - name: name, - language: "English", - seedWordsLength: 14); // TODO catch failure - - walletInfo = WalletInfo.external( - id: WalletBase.idFor(name, type), - name: name, - type: type, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - address: "", - dirPath: dirPath); - credentials.walletInfo = walletInfo; - - _walletCreationService = WalletCreationService( - secureStorage: storage, - walletService: walletService, - keyService: keysStorage, - ); - _walletCreationService.changeWalletType(); - } catch (e, s) { - print(e); - print(s); - hasThrown = true; - } - expect(hasThrown, false); - }); - - test("Wownero 14 word seed address generation", () async { - final wallet = await _walletCreationService.create(credentials); - // TODO validate mnemonic - walletInfo.address = wallet.walletAddresses.address; - - bool hasThrown = false; - try { - await _walletInfoSource.add(walletInfo); - walletBase?.close(); - walletBase = wallet as WowneroWalletBase; - - expect( - await walletBase! - .validateAddress(wallet.walletAddresses.address ?? ''), - true); - } catch (_) { - hasThrown = true; - } - expect(hasThrown, false); - - // Address validation - expect(walletBase!.validateAddress(''), false); - expect( - walletBase!.validateAddress( - 'Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi'), - true); - expect( - walletBase!.validateAddress( - 'WasdfHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmjkl'), - false); - - walletBase?.close(); - walletBase = wallet as WowneroWalletBase; - }); - - // TODO delete left over wallet file with name: name - }); - - group("Wownero 14 word seed restoration", () { - setUp(() async { - bool hasThrown = false; - try { - name = 'namee${Random().nextInt(10000000)}'; - final dirPath = await pathForWalletDir(name: name, type: type); - path = await pathForWallet(name: name, type: type); - credentials = wownero.createWowneroRestoreWalletFromSeedCredentials( - name: name, - height: 465760, - mnemonic: testMnemonic14); // TODO catch failure - - walletInfo = WalletInfo.external( - id: WalletBase.idFor(name, type), - name: name, - type: type, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - address: "", - dirPath: dirPath); - credentials.walletInfo = walletInfo; - - _walletCreationService = WalletCreationService( - secureStorage: storage, - walletService: walletService, - keyService: keysStorage, - ); - _walletCreationService.changeWalletType(); - } catch (e, s) { - print(e); - print(s); - hasThrown = true; - } - expect(hasThrown, false); - }); - - test("Wownero 14 word seed address generation", () async { - final wallet = await _walletCreationService.restoreFromSeed(credentials); - walletInfo.address = wallet.walletAddresses.address; - - bool hasThrown = false; - try { - await _walletInfoSource.add(walletInfo); - walletBase?.close(); - walletBase = wallet as WowneroWalletBase; - - expect(walletInfo.address, mainnetTestData14[0][0]); - expect( - walletBase!.getTransactionAddress(0, 0), mainnetTestData14[0][0]); - expect( - walletBase!.getTransactionAddress(0, 1), mainnetTestData14[0][1]); - expect( - walletBase!.getTransactionAddress(0, 2), mainnetTestData14[0][2]); - expect( - walletBase!.getTransactionAddress(1, 0), mainnetTestData14[1][0]); - expect( - walletBase!.getTransactionAddress(1, 1), mainnetTestData14[1][1]); - expect( - walletBase!.getTransactionAddress(1, 2), mainnetTestData14[1][2]); - } catch (_) { - hasThrown = true; - } - expect(hasThrown, false); - - walletBase?.close(); - walletBase = wallet as WowneroWalletBase; - }); - - // TODO delete left over wallet file with name: name - }); - - group("Wownero 25 word seed generation", () { - setUp(() async { - bool hasThrown = false; - try { - name = 'namee${Random().nextInt(10000000)}'; - final dirPath = await pathForWalletDir(name: name, type: type); - path = await pathForWallet(name: name, type: type); - credentials = wownero.createWowneroNewWalletCredentials( - name: name, - language: "English", - seedWordsLength: 25); // TODO catch failure - - walletInfo = WalletInfo.external( - id: WalletBase.idFor(name, type), - name: name, - type: type, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - address: "", - dirPath: dirPath); - credentials.walletInfo = walletInfo; - - _walletCreationService = WalletCreationService( - secureStorage: storage, - walletService: walletService, - keyService: keysStorage, - ); - _walletCreationService.changeWalletType(); - } catch (e, s) { - print(e); - print(s); - hasThrown = true; - } - expect(hasThrown, false); - }); - - test("Wownero 25 word seed address generation", () async { - final wallet = await _walletCreationService.create(credentials); - // TODO validate mnemonic - walletInfo.address = wallet.walletAddresses.address; - - bool hasThrown = false; - try { - await _walletInfoSource.add(walletInfo); - walletBase?.close(); - walletBase = wallet as WowneroWalletBase; - - // TODO validate - //expect(walletInfo.address, mainnetTestData14[0][0]); - } catch (_) { - hasThrown = true; - } - expect(hasThrown, false); - - walletBase?.close(); - walletBase = wallet as WowneroWalletBase; - }); - - // TODO delete left over wallet file with name: name - }); - - group("Wownero 25 word seed restoration", () { - setUp(() async { - bool hasThrown = false; - try { - name = 'namee${Random().nextInt(10000000)}'; - final dirPath = await pathForWalletDir(name: name, type: type); - path = await pathForWallet(name: name, type: type); - credentials = wownero.createWowneroRestoreWalletFromSeedCredentials( - name: name, - height: 465760, - mnemonic: testMnemonic25); // TODO catch failure - - walletInfo = WalletInfo.external( - id: WalletBase.idFor(name, type), - name: name, - type: type, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - address: "", - dirPath: dirPath); - credentials.walletInfo = walletInfo; - - _walletCreationService = WalletCreationService( - secureStorage: storage, - walletService: walletService, - keyService: keysStorage, - ); - _walletCreationService.changeWalletType(); - } catch (e, s) { - print(e); - print(s); - hasThrown = true; - } - expect(hasThrown, false); - }); - - test("Wownero 25 word seed address generation", () async { - final wallet = await _walletCreationService.restoreFromSeed(credentials); - walletInfo.address = wallet.walletAddresses.address; - - bool hasThrown = false; - try { - await _walletInfoSource.add(walletInfo); - walletBase?.close(); - walletBase = wallet as WowneroWalletBase; - - expect(walletInfo.address, mainnetTestData25[0][0]); - } catch (_) { - hasThrown = true; - } - expect(hasThrown, false); - - walletBase?.close(); - walletBase = wallet as WowneroWalletBase; - }); - - // TODO delete left over wallet file with name: name - }); + // storage = FakeSecureStorage(); + // keysStorage = KeyService(storage!); + // WalletInfo walletInfo = WalletInfo.external( + // id: '', + // name: '', + // type: type, + // isRecovery: false, + // restoreHeight: 0, + // date: DateTime.now(), + // path: '', + // address: '', + // dirPath: ''); + // late WalletCredentials credentials; + // + // wownero.onStartup(); + // + // bool hiveAdaptersRegistered = false; + // + // group("Wownero 14 word seed generation", () { + // setUp(() async { + // await setUpTestHive(); + // if (!hiveAdaptersRegistered) { + // hiveAdaptersRegistered = true; + // + // Hive.registerAdapter(NodeAdapter()); + // Hive.registerAdapter(WalletInfoAdapter()); + // Hive.registerAdapter(WalletTypeAdapter()); + // Hive.registerAdapter(UnspentCoinsInfoAdapter()); + // + // final wallets = await Hive.openBox<dynamic>('wallets'); + // await wallets.put('currentWalletName', name); + // + // _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName); + // walletService = wownero + // .createWowneroWalletService(_walletInfoSource as Box<WalletInfo>); + // } + // + // bool hasThrown = false; + // try { + // name = 'namee${Random().nextInt(10000000)}'; + // final dirPath = await pathForWalletDir(name: name, type: type); + // path = await pathForWallet(name: name, type: type); + // credentials = wownero.createWowneroNewWalletCredentials( + // name: name, + // language: "English", + // seedWordsLength: 14); // TODO catch failure + // + // walletInfo = WalletInfo.external( + // id: WalletBase.idFor(name, type), + // name: name, + // type: type, + // isRecovery: false, + // restoreHeight: credentials.height ?? 0, + // date: DateTime.now(), + // path: path, + // address: "", + // dirPath: dirPath); + // credentials.walletInfo = walletInfo; + // + // _walletCreationService = WalletCreationService( + // secureStorage: storage, + // walletService: walletService, + // keyService: keysStorage, + // ); + // _walletCreationService.changeWalletType(); + // } catch (e, s) { + // print(e); + // print(s); + // hasThrown = true; + // } + // expect(hasThrown, false); + // }); + // + // test("Wownero 14 word seed address generation", () async { + // final wallet = await _walletCreationService.create(credentials); + // // TODO validate mnemonic + // walletInfo.address = wallet.walletAddresses.address; + // + // bool hasThrown = false; + // try { + // await _walletInfoSource.add(walletInfo); + // walletBase?.close(); + // walletBase = wallet as WowneroWalletBase; + // + // expect( + // await walletBase! + // .validateAddress(wallet.walletAddresses.address ?? ''), + // true); + // } catch (_) { + // hasThrown = true; + // } + // expect(hasThrown, false); + // + // // Address validation + // expect(walletBase!.validateAddress(''), false); + // expect( + // walletBase!.validateAddress( + // 'Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi'), + // true); + // expect( + // walletBase!.validateAddress( + // 'WasdfHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmjkl'), + // false); + // + // walletBase?.close(); + // walletBase = wallet as WowneroWalletBase; + // }); + // + // // TODO delete left over wallet file with name: name + // }); + // + // group("Wownero 14 word seed restoration", () { + // setUp(() async { + // bool hasThrown = false; + // try { + // name = 'namee${Random().nextInt(10000000)}'; + // final dirPath = await pathForWalletDir(name: name, type: type); + // path = await pathForWallet(name: name, type: type); + // credentials = wownero.createWowneroRestoreWalletFromSeedCredentials( + // name: name, + // height: 465760, + // mnemonic: testMnemonic14); // TODO catch failure + // + // walletInfo = WalletInfo.external( + // id: WalletBase.idFor(name, type), + // name: name, + // type: type, + // isRecovery: false, + // restoreHeight: credentials.height ?? 0, + // date: DateTime.now(), + // path: path, + // address: "", + // dirPath: dirPath); + // credentials.walletInfo = walletInfo; + // + // _walletCreationService = WalletCreationService( + // secureStorage: storage, + // walletService: walletService, + // keyService: keysStorage, + // ); + // _walletCreationService.changeWalletType(); + // } catch (e, s) { + // print(e); + // print(s); + // hasThrown = true; + // } + // expect(hasThrown, false); + // }); + // + // test("Wownero 14 word seed address generation", () async { + // final wallet = await _walletCreationService.restoreFromSeed(credentials); + // walletInfo.address = wallet.walletAddresses.address; + // + // bool hasThrown = false; + // try { + // await _walletInfoSource.add(walletInfo); + // walletBase?.close(); + // walletBase = wallet as WowneroWalletBase; + // + // expect(walletInfo.address, mainnetTestData14[0][0]); + // expect( + // walletBase!.getTransactionAddress(0, 0), mainnetTestData14[0][0]); + // expect( + // walletBase!.getTransactionAddress(0, 1), mainnetTestData14[0][1]); + // expect( + // walletBase!.getTransactionAddress(0, 2), mainnetTestData14[0][2]); + // expect( + // walletBase!.getTransactionAddress(1, 0), mainnetTestData14[1][0]); + // expect( + // walletBase!.getTransactionAddress(1, 1), mainnetTestData14[1][1]); + // expect( + // walletBase!.getTransactionAddress(1, 2), mainnetTestData14[1][2]); + // } catch (_) { + // hasThrown = true; + // } + // expect(hasThrown, false); + // + // walletBase?.close(); + // walletBase = wallet as WowneroWalletBase; + // }); + // + // // TODO delete left over wallet file with name: name + // }); + // + // group("Wownero 25 word seed generation", () { + // setUp(() async { + // bool hasThrown = false; + // try { + // name = 'namee${Random().nextInt(10000000)}'; + // final dirPath = await pathForWalletDir(name: name, type: type); + // path = await pathForWallet(name: name, type: type); + // credentials = wownero.createWowneroNewWalletCredentials( + // name: name, + // language: "English", + // seedWordsLength: 25); // TODO catch failure + // + // walletInfo = WalletInfo.external( + // id: WalletBase.idFor(name, type), + // name: name, + // type: type, + // isRecovery: false, + // restoreHeight: credentials.height ?? 0, + // date: DateTime.now(), + // path: path, + // address: "", + // dirPath: dirPath); + // credentials.walletInfo = walletInfo; + // + // _walletCreationService = WalletCreationService( + // secureStorage: storage, + // walletService: walletService, + // keyService: keysStorage, + // ); + // _walletCreationService.changeWalletType(); + // } catch (e, s) { + // print(e); + // print(s); + // hasThrown = true; + // } + // expect(hasThrown, false); + // }); + // + // test("Wownero 25 word seed address generation", () async { + // final wallet = await _walletCreationService.create(credentials); + // // TODO validate mnemonic + // walletInfo.address = wallet.walletAddresses.address; + // + // bool hasThrown = false; + // try { + // await _walletInfoSource.add(walletInfo); + // walletBase?.close(); + // walletBase = wallet as WowneroWalletBase; + // + // // TODO validate + // //expect(walletInfo.address, mainnetTestData14[0][0]); + // } catch (_) { + // hasThrown = true; + // } + // expect(hasThrown, false); + // + // walletBase?.close(); + // walletBase = wallet as WowneroWalletBase; + // }); + // + // // TODO delete left over wallet file with name: name + // }); + // + // group("Wownero 25 word seed restoration", () { + // setUp(() async { + // bool hasThrown = false; + // try { + // name = 'namee${Random().nextInt(10000000)}'; + // final dirPath = await pathForWalletDir(name: name, type: type); + // path = await pathForWallet(name: name, type: type); + // credentials = wownero.createWowneroRestoreWalletFromSeedCredentials( + // name: name, + // height: 465760, + // mnemonic: testMnemonic25); // TODO catch failure + // + // walletInfo = WalletInfo.external( + // id: WalletBase.idFor(name, type), + // name: name, + // type: type, + // isRecovery: false, + // restoreHeight: credentials.height ?? 0, + // date: DateTime.now(), + // path: path, + // address: "", + // dirPath: dirPath); + // credentials.walletInfo = walletInfo; + // + // _walletCreationService = WalletCreationService( + // secureStorage: storage, + // walletService: walletService, + // keyService: keysStorage, + // ); + // _walletCreationService.changeWalletType(); + // } catch (e, s) { + // print(e); + // print(s); + // hasThrown = true; + // } + // expect(hasThrown, false); + // }); + // + // test("Wownero 25 word seed address generation", () async { + // final wallet = await _walletCreationService.restoreFromSeed(credentials); + // walletInfo.address = wallet.walletAddresses.address; + // + // bool hasThrown = false; + // try { + // await _walletInfoSource.add(walletInfo); + // walletBase?.close(); + // walletBase = wallet as WowneroWalletBase; + // + // expect(walletInfo.address, mainnetTestData25[0][0]); + // } catch (_) { + // hasThrown = true; + // } + // expect(hasThrown, false); + // + // walletBase?.close(); + // walletBase = wallet as WowneroWalletBase; + // }); + // + // // TODO delete left over wallet file with name: name + // }); } -Future<String> pathForWalletDir( - {required String name, required WalletType type}) async { - Directory root = (await getApplicationDocumentsDirectory()); - if (Platform.isIOS) { - root = (await getLibraryDirectory()); - } - final prefix = walletTypeToString(type).toLowerCase(); - final walletsDir = Directory('${root.path}/wallets'); - final walletDire = Directory('${walletsDir.path}/$prefix/$name'); - - if (!walletDire.existsSync()) { - walletDire.createSync(recursive: true); - } - - return walletDire.path; -} - -Future<String> pathForWallet( - {required String name, required WalletType type}) async => - await pathForWalletDir(name: name, type: type) - .then((path) => '$path/$name'); +// Future<String> pathForWalletDir( +// {required String name, required WalletType type}) async { +// Directory root = (await getApplicationDocumentsDirectory()); +// if (Platform.isIOS) { +// root = (await getLibraryDirectory()); +// } +// final prefix = walletTypeToString(type).toLowerCase(); +// final walletsDir = Directory('${root.path}/wallets'); +// final walletDire = Directory('${walletsDir.path}/$prefix/$name'); +// +// if (!walletDire.existsSync()) { +// walletDire.createSync(recursive: true); +// } +// +// return walletDire.path; +// } +// +// Future<String> pathForWallet( +// {required String name, required WalletType type}) async => +// await pathForWalletDir(name: name, type: type) +// .then((path) => '$path/$name'); From 37fa5e9d198badbc870fbbffca873a644e0fd128 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Jan 2023 16:18:17 -0600 Subject: [PATCH 014/123] remove old file and add todos --- lib/services/coins/coin_paynym_extension.dart | 2 + lib/services/mixins/paynym_support.dart | 569 ------------------ 2 files changed, 2 insertions(+), 569 deletions(-) delete mode 100644 lib/services/mixins/paynym_support.dart diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index b2ccfda9e..8810621ec 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -64,6 +64,8 @@ extension PayNym on DogecoinWallet { final node = root.derivePath(kPaynymDerivePath); final pair = btc_dart.ECPair.fromPrivateKey(node.privateKey!, network: network); + // TODO: is pair same as priv key from node? + // todo: should this priv key be used or priv key of derive(0)? final signed = pair.sign(SHA256Digest().process(data)); return signed; } diff --git a/lib/services/mixins/paynym_support.dart b/lib/services/mixins/paynym_support.dart deleted file mode 100644 index 3bea5aee6..000000000 --- a/lib/services/mixins/paynym_support.dart +++ /dev/null @@ -1,569 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:bip32/bip32.dart' as bip32; -import 'package:bip47/bip47.dart'; -import 'package:bip47/src/util.dart'; -import 'package:bitcoindart/bitcoindart.dart' as btc_dart; -import 'package:bitcoindart/src/utils/constants/op.dart' as op; -import 'package:bitcoindart/src/utils/script.dart' as bscript; -import 'package:isar/isar.dart'; -import 'package:pointycastle/digests/sha256.dart'; -import 'package:stackwallet/db/main_db.dart'; -import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; -import 'package:stackwallet/electrumx_rpc/electrumx.dart'; -import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; -import 'package:stackwallet/models/isar/models/isar_models.dart'; -import 'package:stackwallet/utilities/address_utils.dart'; -import 'package:stackwallet/utilities/bip32_utils.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; -import 'package:stackwallet/utilities/format.dart'; -import 'package:stackwallet/utilities/logger.dart'; -import 'package:tuple/tuple.dart'; -import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; - -mixin PaynymSupport { - late final btc_dart.NetworkType network; - late final MainDB db; - late final Coin coin; - late final String walletId; - void initPaynymSupport({ - required btc_dart.NetworkType network, - required MainDB db, - required Coin coin, - required String walletId, - }) { - this.network = network; - this.db = db; - this.coin = coin; - this.walletId = walletId; - } - - // generate bip32 payment code root - Future<bip32.BIP32> getRootNode({required List<String> mnemonic}) async { - final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); - return root; - } - - // fetch or generate this wallet's bip47 payment code - Future<PaymentCode> getPaymentCode({ - required List<String> mnemonic, - }) async { - // TODO: cache elsewhere - // final paymentCodeString = DB.instance - // .get<dynamic>(boxName: walletId, key: "paymentCodeString") as String?; - PaymentCode paymentCode; - // if (paymentCodeString == null) { - final root = await getRootNode(mnemonic: mnemonic); - final node = root.derivePath("m/47'/0'/0'"); - paymentCode = - PaymentCode.initFromPubKey(node.publicKey, node.chainCode, network); - // await DB.instance.put<dynamic>( - // boxName: walletId, - // key: "paymentCodeString", - // value: paymentCode.toString()); - // } else { - // paymentCode = PaymentCode.fromPaymentCode(paymentCodeString, network); - // } - return paymentCode; - } - - Future<Uint8List> signWithNotificationKey({ - required Uint8List data, - required List<String> mnemonic, - }) async { - final root = await getRootNode( - mnemonic: mnemonic, - ); - final node = root.derivePath("m/47'/0'/0'"); - final pair = btc_dart.ECPair.fromPrivateKey(node.privateKey!, network: network); - final signed = pair.sign(SHA256Digest().process(data)); - return signed; - } - - Future<String> signStringWithNotificationKey({ - required String data, - required List<String> mnemonic, - }) async { - final bytes = await signWithNotificationKey( - data: Uint8List.fromList(utf8.encode(data)), - mnemonic: mnemonic, - ); - return Format.uint8listToString(bytes); - // final bytes = - // await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); - // return Format.uint8listToString(bytes); - } - - /// Update cached lists of notification transaction IDs. - /// Returns true if there are new notification transactions found since last - /// checked. - Future<bool> checkForNotificationTransactions({ - required Coin coin, - required PaymentCode paymentCode, - required ElectrumX electrumXClient, - required CachedElectrumX cachedElectrumXClient, - required int currentChainHeight, - }) async { - final notificationAddress = paymentCode.notificationAddress(); - - final receivedNotificationTransactions = await db - .getTransactions(walletId) - .filter() - .address((q) => q.valueEqualTo(notificationAddress)) - .findAll(); - - - final unconfirmedTransactions = receivedNotificationTransactions.where( - (e) => !e.isConfirmed( - currentChainHeight, - coin.requiredConfirmations, - ), - ); - - final totalStoredCount = receivedNotificationTransactions.length; - final storedUnconfirmedCount = unconfirmedTransactions.length; - - // for (final txid in transactionIds) { - // final tx = await cachedElectrumXClient.getTransaction( - // txHash: txid, - // coin: coin, - // ); - // - // // check if tx is confirmed - // if ((tx["confirmations"] as int? ?? 0) > coin.requiredConfirmations) { - // // remove it from unconfirmed set - // unconfirmedNotificationTransactionIds.remove(txid); - // - // // add it to confirmed set - // confirmedNotificationTransactionIds.add(txid); - // } else { - // // otherwise add it to the unconfirmed set - // unconfirmedNotificationTransactionIds.add(txid); - // } - // } - // - // final newTotalCount = confirmedNotificationTransactionIds.length + - // unconfirmedNotificationTransactionIds.length; - // - // return newTotalCount > totalCount; - return false; - } - - // bool hasConnected(String paymentCodeString) { - // return getPaynymNotificationTxInfo() - // .values - // .where((e) => e["paymentCodeString"] == paymentCodeString) - // .isNotEmpty; - // } - // - // bool hasConnectedConfirmed(String paymentCodeString) { - // return getPaynymNotificationTxInfo() - // .values - // .where((e) => - // e["paymentCodeString"] == paymentCodeString && - // e["confirmed"] == true) - // .isNotEmpty; - // } - // - // // fetch paynym notification tx meta data - // Map<String, dynamic> getPaynymNotificationTxInfo() { - // final map = DB.instance.get<dynamic>( - // boxName: walletId, key: "paynymNotificationTxInfo") as Map? ?? - // {}; - // - // return Map<String, dynamic>.from(map); - // } - - // // add/update paynym notification tx meta data entry - // Future<void> updatePaynymNotificationInfo({ - // required String txid, - // required bool confirmed, - // required String paymentCodeString, - // }) async { - // final data = getPaynymNotificationTxInfo(); - // data[txid] = { - // "txid": txid, - // "confirmed": confirmed, - // "paymentCodeString": paymentCodeString, - // }; - // await DB.instance.put<dynamic>( - // boxName: walletId, - // key: "paynymNotificationTxInfo", - // value: data, - // ); - // } - - Future<Transaction?> hasSentNotificationTx(PaymentCode pCode) async { - final tx = await db - .getTransactions(walletId) - .filter() - .address((q) => q.valueEqualTo(pCode.notificationAddress())).countSync() - .findFirst(); - return tx; - } - - void preparePaymentCodeSend(PaymentCode pCode) async { - final notifTx = await hasSentNotificationTx(pCode); - final currentHeight = await chainHeight; - - if (notifTx == null) { - throw PaynymSendException("No notification transaction sent to $pCode"); - } else if (!notifTx.isConfirmed(currentHeight, MINIMUM_CONFIRMATIONS)) { - throw PaynymSendException( - "Notification transaction sent to $pCode has not confirmed yet"); - } else { - final node = getBip32Root((await mnemonic).join(" "), network) - .derivePath("m/47'/0'/0'"); - final sendToAddress = await nextUnusedSendAddressFrom( - pCode, - node.derive(0).privateKey!, - ); - - // todo: Actual transaction build - } - } - - /// get the next unused address to send to given the receiver's payment code - /// and your own private key - Future<String> nextUnusedSendAddressFrom( - PaymentCode pCode, - Uint8List privateKey, - ) async { - // https://en.bitcoin.it/wiki/BIP_0047#Path_levels - const maxCount = 2147483647; - - final paymentAddress = PaymentAddress.initWithPrivateKey( - privateKey, - pCode, - 0, // initial index to check - ); - - for ( ; - paymentAddress.index <= maxCount; - paymentAddress.index++) { - final address = paymentAddress.getSendAddress(); - - final transactionIds = await electrumXClient.getHistory( - scripthash: AddressUtils.convertToScriptHash( - address, - network, - ), - ); - - if (transactionIds.isEmpty) { - return address; - } - } - - throw PaynymSendException("Exhausted unused send addresses!"); - } - - /// get your receiving addresses given the sender's payment code and your own - /// private key - List<String> deriveReceivingAddressesFor( - PaymentCode pCode, - Uint8List privateKey, - int count, - ) { - // https://en.bitcoin.it/wiki/BIP_0047#Path_levels - const maxCount = 2147483647; - assert(count <= maxCount); - - final paymentAddress = PaymentAddress.initWithPrivateKey( - privateKey, - pCode, - 0, // initial index - ); - - final List<String> result = []; - for (paymentAddress.index = 0; - paymentAddress.index < count; - paymentAddress.index++) { - final address = paymentAddress.getReceiveAddress(); - - result.add(address); - } - - return result; - } - - Future<Map<String, dynamic>> buildNotificationTx({ - required int selectedTxFeeRate, - required String targetPaymentCodeString, - required PaymentCode myPaymentCode, - int additionalOutputs = 0, - required List<UTXO> utxos, - required int dustLimit, - required int chainHeight, - required Future<Map<String, dynamic>> Function( - List< UTXO> - ) fetchBuildTxData, - }) async { - final amountToSend = dustLimit; - final List<UTXO> availableOutputs = utxos ; - final List<UTXO> spendableOutputs = []; - int spendableSatoshiValue = 0; - - // Build list of spendable outputs and totaling their satoshi amount - for (var i = 0; i < availableOutputs.length; i++) { - if (availableOutputs[i].isBlocked == false && - availableOutputs[i] - .isConfirmed( chainHeight, coin.requiredConfirmations) == - true) { - spendableOutputs.add(availableOutputs[i]); - spendableSatoshiValue += availableOutputs[i].value; - } - } - - if (spendableSatoshiValue < amountToSend) { - // insufficient balance - throw InsufficientBalanceException( - "Spendable balance is less than the minimum required for a notification transaction."); - } else if (spendableSatoshiValue == amountToSend) { - // insufficient balance due to missing amount to cover fee - throw InsufficientBalanceException( - "Remaining balance does not cover the network fee."); - } - - // sort spendable by age (oldest first) - spendableOutputs.sort((a, b) => b.blockTime!.compareTo(a.blockTime!)); - - int satoshisBeingUsed = 0; - int outputsBeingUsed = 0; - List<UTXO> utxoObjectsToUse = []; - - for (int i = 0; - satoshisBeingUsed < amountToSend && i < spendableOutputs.length; - i++) { - utxoObjectsToUse.add(spendableOutputs[i]); - satoshisBeingUsed += spendableOutputs[i].value; - outputsBeingUsed += 1; - } - - // add additional outputs if required - for (int i = 0; - i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; - i++) { - utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); - satoshisBeingUsed += spendableOutputs[outputsBeingUsed].value; - outputsBeingUsed += 1; - } - - // gather required signing data - final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse); - - final int vSizeForNoChange = (await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0, myPaymentCode: myPaymentCode, dustLimit: dustLimit, changeAddress: )) - .item2; - - final int vSizeForWithChange = (await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: satoshisBeingUsed - amountToSend, myPaymentCode: myPaymentCode, dustLimit: dustLimit, changeAddress: ch,)) - .item2; - - // Assume 2 outputs, for recipient and payment code script - int feeForNoChange = estimateTxFee( - vSize: vSizeForNoChange, - feeRatePerKB: selectedTxFeeRate, - ); - - // Assume 3 outputs, for recipient, payment code script, and change - int feeForWithChange = estimateTxFee( - vSize: vSizeForWithChange, - feeRatePerKB: selectedTxFeeRate, - ); - - if (feeForNoChange < vSizeForNoChange * 1000) { - feeForNoChange = vSizeForNoChange * 1000; - } - if (feeForWithChange < vSizeForWithChange * 1000) { - feeForWithChange = vSizeForWithChange * 1000; - } - - if (satoshisBeingUsed - amountToSend > feeForNoChange + dustLimit) { - // try to add change output due to "left over" amount being greater than - // the estimated fee + the dust limit - int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; - - // check estimates are correct and build notification tx - if (changeAmount >= dustLimit && - satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: changeAmount, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } else { - // something broke during fee estimation or the change amount is smaller - // than the dust limit. Try without change - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } - } else if (satoshisBeingUsed - amountToSend >= feeForNoChange) { - // since we already checked if we need to add a change output we can just - // build without change here - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0, myPaymentCode: null, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } else { - // if we get here we do not have enough funds to cover the tx total so we - // check if we have any more available outputs and try again - if (spendableOutputs.length > outputsBeingUsed) { - return buildNotificationTx( - selectedTxFeeRate: selectedTxFeeRate, - targetPaymentCodeString: targetPaymentCodeString, - additionalOutputs: additionalOutputs + 1, utxos: utxos, dustLimit: dustLimit, chainHeight: chainHeight, fetchBuildTxData: fetchBuildTxData, - ); - } else { - throw InsufficientBalanceException( - "Remaining balance does not cover the network fee."); - } - } - } - - // return tuple with string value equal to the raw tx hex and the int value - // equal to its vSize - Future<Tuple2<String, int>> _createNotificationTx({ - required String targetPaymentCodeString, - required PaymentCode myPaymentCode, - required List<UTXO> utxosToUse, - required Map<String, dynamic> utxoSigningData, - required int change, - required int dustLimit, - required Address changeAddress, - }) async { - final targetPaymentCode = - PaymentCode.fromPaymentCode(targetPaymentCodeString, network); - - final utxo = utxosToUse.first; - final txPoint = utxo.txid.fromHex.toList(); - final txPointIndex = utxo.vout; - - final rev = Uint8List(txPoint.length + 4); - Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); - final buffer = rev.buffer.asByteData(); - buffer.setUint32(txPoint.length, txPointIndex, Endian.little); - - final myKeyPair = utxoSigningData[utxo.txid]["keyPair"] as btc_dart.ECPair; - - final S = SecretPoint( - myKeyPair.privateKey!, - targetPaymentCode.notificationPublicKey(), - ); - - final blindingMask = PaymentCode.getMask(S.ecdhSecret(), rev); - - final blindedPaymentCode = PaymentCode.blind( - myPaymentCode.getPayload(), - blindingMask, - ); - - final opReturnScript = bscript.compile([ - (op.OPS["OP_RETURN"] as int), - blindedPaymentCode, - ]); - - // build a notification tx - final txb = btc_dart.TransactionBuilder(network: network); - txb.setVersion(1); - - txb.addInput( - utxo.txid, - txPointIndex, - ); - - txb.addOutput(targetPaymentCode.notificationAddress(), dustLimit); - txb.addOutput(opReturnScript, 0); - - // TODO: add possible change output and mark output as dangerous - if (change > 0) { - final String changeAddressString = changeAddress.value; - txb.addOutput(changeAddressString, change); - } - - txb.sign( - vin: 0, - keyPair: myKeyPair, - ); - - // sign rest of possible inputs - for (var i = 1; i < utxosToUse.length - 1; i++) { - final txid = utxosToUse[i].txid; - txb.sign( - vin: i, - keyPair: utxoSigningData[txid]["keyPair"] as ECPair, - // witnessValue: utxosToUse[i].value, - ); - } - - final builtTx = txb.build(); - - return Tuple2(builtTx.toHex(), builtTx.virtualSize()); - } - - Future<String> confirmSendNotificationTx( - {required Map<String, dynamic> preparedTx, required ElectrumX electrumXClient,}) async { - try { - Logging.instance.log("confirmNotificationTx txData: $preparedTx", - level: LogLevel.Info); - final txHash = await electrumXClient.broadcastTransaction( - rawTx: preparedTx["hex"] as String); - Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); - - - return txHash; - } catch (e, s) { - Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", - level: LogLevel.Error); - rethrow; - } - } - -} From 26245517acb57d2fbd06a2e6e5d7c544c0067886 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 09:26:50 -0600 Subject: [PATCH 015/123] add paynym send functionality to paynym extension --- lib/services/coins/coin_paynym_extension.dart | 108 ++++++++++++------ 1 file changed, 72 insertions(+), 36 deletions(-) diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index 8810621ec..77173aadd 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -13,7 +13,6 @@ import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dar import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; -import 'package:stackwallet/utilities/address_utils.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; @@ -23,24 +22,40 @@ const kPaynymDerivePath = "m/47'/0'/0'"; extension PayNym on DogecoinWallet { // generate bip32 payment code root - Future<bip32.BIP32> getRootNode({required List<String> mnemonic}) async { + Future<bip32.BIP32> getRootNode({ + required List<String> mnemonic, + }) async { final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); return root; } + Future<Uint8List> deriveNotificationPrivateKey({ + required List<String> mnemonic, + }) async { + final root = await getRootNode(mnemonic: mnemonic); + final node = root.derivePath(kPaynymDerivePath).derive(0); + return node.privateKey!; + } + /// fetch or generate this wallet's bip47 payment code Future<PaymentCode> getPaymentCode() async { final address = await db .getAddresses(walletId) .filter() .subTypeEqualTo(AddressSubType.paynymNotification) + .and() + .not() + .typeEqualTo(AddressType.nonWallet) .findFirst(); PaymentCode paymentCode; if (address == null) { final root = await getRootNode(mnemonic: await mnemonic); final node = root.derivePath(kPaynymDerivePath); - paymentCode = - PaymentCode.initFromPubKey(node.publicKey, node.chainCode, network); + paymentCode = PaymentCode.initFromPubKey( + node.publicKey, + node.chainCode, + network, + ); await db.putAddress( Address( @@ -60,12 +75,9 @@ extension PayNym on DogecoinWallet { } Future<Uint8List> signWithNotificationKey(Uint8List data) async { - final root = await getRootNode(mnemonic: await mnemonic); - final node = root.derivePath(kPaynymDerivePath); - final pair = - btc_dart.ECPair.fromPrivateKey(node.privateKey!, network: network); - // TODO: is pair same as priv key from node? - // todo: should this priv key be used or priv key of derive(0)? + final privateKey = + await deriveNotificationPrivateKey(mnemonic: await mnemonic); + final pair = btc_dart.ECPair.fromPrivateKey(privateKey, network: network); final signed = pair.sign(SHA256Digest().process(data)); return signed; } @@ -76,24 +88,27 @@ extension PayNym on DogecoinWallet { return Format.uint8listToString(bytes); } - void preparePaymentCodeSend(PaymentCode pCode) async { - if (!(await hasConnected(pCode.notificationAddress()))) { - throw PaynymSendException("No notification transaction sent to $pCode"); + Future<Future<Map<String, dynamic>>> preparePaymentCodeSend( + PaymentCode paymentCode, int satoshiAmount) async { + if (!(await hasConnected(paymentCode.notificationAddress()))) { + throw PaynymSendException( + "No notification transaction sent to $paymentCode"); } else { - final root = await getRootNode(mnemonic: await mnemonic); - final node = root.derivePath(kPaynymDerivePath); + final myPrivateKey = + await deriveNotificationPrivateKey(mnemonic: await mnemonic); final sendToAddress = await nextUnusedSendAddressFrom( - pCode: pCode, - privateKey: node.derive(0).privateKey!, + pCode: paymentCode, + privateKey: myPrivateKey, ); - // todo: Actual transaction build + return prepareSend( + address: sendToAddress.value, satoshiAmount: satoshiAmount); } } /// get the next unused address to send to given the receiver's payment code /// and your own private key - Future<String> nextUnusedSendAddressFrom({ + Future<Address> nextUnusedSendAddressFrom({ required PaymentCode pCode, required Uint8List privateKey, int startIndex = 0, @@ -101,24 +116,46 @@ extension PayNym on DogecoinWallet { // https://en.bitcoin.it/wiki/BIP_0047#Path_levels const maxCount = 2147483647; - final paymentAddress = PaymentAddress.initWithPrivateKey( - privateKey, - pCode, - startIndex, // initial index to check - ); + for (int i = startIndex; i < maxCount; i++) { + final address = await db + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymSend) + .and() + .otherDataEqualTo(pCode.toString()) + .and() + .derivationIndexEqualTo(i) + .findFirst(); - for (; paymentAddress.index <= maxCount; paymentAddress.index++) { - final address = paymentAddress.getSendAddress(); + if (address != null) { + final count = await getTxCount(address: address.value); + // return address if unused, otherwise continue to next index + if (count == 0) { + return address; + } + } else { + final paymentAddress = PaymentAddress.initWithPrivateKey( + privateKey, + pCode, + i, // index to use + ).getSendAddress(); - final transactionIds = await electrumXClient.getHistory( - scripthash: AddressUtils.convertToScriptHash( - address, - network, - ), - ); + // add address to local db + final address = Address( + walletId: walletId, + value: paymentAddress, + publicKey: [], + derivationIndex: i, + type: AddressType.p2pkh, + subType: AddressSubType.paynymSend, + ); + await db.putAddress(address); - if (transactionIds.isEmpty) { - return address; + final count = await getTxCount(address: address.value); + // return address if unused, otherwise continue to next index + if (count == 0) { + return address; + } } } @@ -466,9 +503,8 @@ extension PayNym on DogecoinWallet { final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex; - final root = await getRootNode(mnemonic: await mnemonic); final myPrivateKey = - root.derivePath(kPaynymDerivePath).derive(0).privateKey!; + await deriveNotificationPrivateKey(mnemonic: await mnemonic); final S = SecretPoint(myPrivateKey, pubKey); From 1965501bf8d45f6b90e406f0a00f54e090b30936 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 11:13:21 -0600 Subject: [PATCH 016/123] added address scanning for send and receiving addresses given the context of your own payment code and another, address type choice also added for send/receive address generation --- lib/services/coins/coin_paynym_extension.dart | 269 +++++++++++++++--- lib/services/mixins/electrum_x_parsing.dart | 2 +- pubspec.lock | 4 +- pubspec.yaml | 2 +- 4 files changed, 229 insertions(+), 48 deletions(-) diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index 77173aadd..a97ccd355 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -134,20 +134,18 @@ extension PayNym on DogecoinWallet { return address; } } else { - final paymentAddress = PaymentAddress.initWithPrivateKey( + final pair = PaymentAddress.initWithPrivateKey( privateKey, pCode, i, // index to use - ).getSendAddress(); + ).getSendAddressKeyPair(); // add address to local db - final address = Address( - walletId: walletId, - value: paymentAddress, - publicKey: [], + final address = generatePaynymSendAddressFromKeyPair( + pair: pair, derivationIndex: i, - type: AddressType.p2pkh, - subType: AddressSubType.paynymSend, + derivePathType: DerivePathType.bip44, + toPaymentCode: pCode, ); await db.putAddress(address); @@ -162,35 +160,6 @@ extension PayNym on DogecoinWallet { throw PaynymSendException("Exhausted unused send addresses!"); } - /// get your receiving addresses given the sender's payment code and your own - /// private key - List<String> deriveReceivingAddressesFor( - PaymentCode pCode, - Uint8List privateKey, - int count, - ) { - // https://en.bitcoin.it/wiki/BIP_0047#Path_levels - const maxCount = 2147483647; - assert(count <= maxCount); - - final paymentAddress = PaymentAddress.initWithPrivateKey( - privateKey, - pCode, - 0, // initial index - ); - - final List<String> result = []; - for (paymentAddress.index = 0; - paymentAddress.index < count; - paymentAddress.index++) { - final address = paymentAddress.getReceiveAddress(); - - result.add(address); - } - - return result; - } - Future<Map<String, dynamic>> prepareNotificationTx({ required int selectedTxFeeRate, required String targetPaymentCodeString, @@ -484,14 +453,39 @@ extension PayNym on DogecoinWallet { .findAll(); for (final tx in txns) { + // quick check that may cause problems? if (tx.address.value?.value == myNotificationAddress) { return true; } - final blindedCode = - tx.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1]; + final unBlindedPaymentCode = await unBlindedPaymentCodeFromTransaction( + transaction: tx, + myCode: myCode, + ); - final designatedInput = tx.inputs.first; + if (paymentCodeString == unBlindedPaymentCode.toString()) { + return true; + } + } + + // otherwise return no + return false; + } + + Future<PaymentCode?> unBlindedPaymentCodeFromTransaction({ + required Transaction transaction, + required PaymentCode myCode, + }) async { + if (transaction.address.value != null && + transaction.address.value!.value != myCode.notificationAddress()) { + return null; + } + + try { + final blindedCode = + transaction.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1]; + + final designatedInput = transaction.inputs.first; final txPoint = designatedInput.txid.fromHex.toList(); final txPointIndex = designatedInput.vout; @@ -515,12 +509,199 @@ extension PayNym on DogecoinWallet { final unBlindedPaymentCode = PaymentCode.initFromPayload(unBlindedPayload); - if (paymentCodeString == unBlindedPaymentCode.toString()) { - return true; + return unBlindedPaymentCode; + } catch (e) { + Logging.instance.log( + "unBlindedPaymentCodeFromTransaction() failed: $e", + level: LogLevel.Warning, + ); + return null; + } + } + + Future<List<PaymentCode>> + getAllPaymentCodesFromNotificationTransactions() async { + final myCode = await getPaymentCode(); + final txns = await db + .getTransactions(walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .findAll(); + + List<PaymentCode> unBlindedList = []; + + for (final tx in txns) { + final unBlinded = await unBlindedPaymentCodeFromTransaction( + transaction: tx, + myCode: myCode, + ); + if (unBlinded != null) { + unBlindedList.add(unBlinded); } } - // otherwise return no - return false; + return unBlindedList; + } + + Future<void> restoreHistoryWith( + PaymentCode other, + int maxUnusedAddressGap, + int maxNumberOfIndexesToCheck, + ) async { + // https://en.bitcoin.it/wiki/BIP_0047#Path_levels + const maxCount = 2147483647; + assert(maxNumberOfIndexesToCheck < maxCount); + + final myPrivateKey = + await deriveNotificationPrivateKey(mnemonic: await mnemonic); + + List<Address> addresses = []; + int receivingGapCounter = 0; + int outgoingGapCounter = 0; + + for (int i = 0; + i < maxNumberOfIndexesToCheck && + (receivingGapCounter < maxUnusedAddressGap || + outgoingGapCounter < maxUnusedAddressGap); + i++) { + final paymentAddress = PaymentAddress.initWithPrivateKey( + myPrivateKey, + other, + i, // index to use + ); + + if (receivingGapCounter < maxUnusedAddressGap) { + final pair = paymentAddress.getSendAddressKeyPair(); + final address = generatePaynymSendAddressFromKeyPair( + pair: pair, + derivationIndex: i, + derivePathType: DerivePathType.bip44, + toPaymentCode: other, + ); + addresses.add(address); + + final count = await getTxCount(address: address.value); + + if (count > 0) { + receivingGapCounter++; + } else { + receivingGapCounter = 0; + } + } + + if (outgoingGapCounter < maxUnusedAddressGap) { + final pair = paymentAddress.getReceiveAddressKeyPair(); + final address = generatePaynymReceivingAddressFromKeyPair( + pair: pair, + derivationIndex: i, + derivePathType: DerivePathType.bip44, + fromPaymentCode: other, + ); + addresses.add(address); + + final count = await getTxCount(address: address.value); + + if (count > 0) { + outgoingGapCounter++; + } else { + outgoingGapCounter = 0; + } + } + } + await db.putAddresses(addresses); + } + + Address generatePaynymSendAddressFromKeyPair({ + required btc_dart.ECPair pair, + required int derivationIndex, + required DerivePathType derivePathType, + required PaymentCode toPaymentCode, + }) { + final data = btc_dart.PaymentData(pubkey: pair.publicKey); + + String addressString; + switch (derivePathType) { + case DerivePathType.bip44: + addressString = + btc_dart.P2PKH(data: data, network: network).data.address!; + break; + + // The following doesn't apply to doge currently + // + // case DerivePathType.bip49: + // addressString = btc_dart.P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart.P2WPKH(data: data, network: network).data), + // network: network) + // .data + // .address!; + // addrType = AddressType.p2sh; + // break; + // case DerivePathType.bip84: + // addressString = btc_dart.P2WPKH(network: network, data: data).data.address!; + // addrType = AddressType.p2wpkh; + // break; + + } + + final address = Address( + walletId: walletId, + value: addressString, + publicKey: pair.publicKey, + derivationIndex: derivationIndex, + type: AddressType.nonWallet, + subType: AddressSubType.paynymSend, + otherData: toPaymentCode.toString(), + ); + + return address; + } + + Address generatePaynymReceivingAddressFromKeyPair({ + required btc_dart.ECPair pair, + required int derivationIndex, + required DerivePathType derivePathType, + required PaymentCode fromPaymentCode, + }) { + final data = btc_dart.PaymentData(pubkey: pair.publicKey); + + String addressString; + AddressType addrType; + switch (derivePathType) { + case DerivePathType.bip44: + addressString = + btc_dart.P2PKH(data: data, network: network).data.address!; + addrType = AddressType.p2pkh; + break; + + // The following doesn't apply to doge currently + // + // case DerivePathType.bip49: + // addressString = btc_dart.P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart.P2WPKH(data: data, network: network).data), + // network: network) + // .data + // .address!; + // addrType = AddressType.p2sh; + // break; + // case DerivePathType.bip84: + // addressString = btc_dart.P2WPKH(network: network, data: data).data.address!; + // addrType = AddressType.p2wpkh; + // break; + + } + + final address = Address( + walletId: walletId, + value: addressString, + publicKey: pair.publicKey, + derivationIndex: derivationIndex, + type: addrType, + subType: AddressSubType.paynymReceive, + otherData: fromPaymentCode.toString(), + ); + + return address; } } diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index b9b815594..deac690f7 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -186,7 +186,7 @@ mixin ElectrumXParsing { } TransactionSubType txSubType = TransactionSubType.none; - if (coin.hasPaynymSupport && outs.length > 1) { + if (coin.hasPaynymSupport && outs.length > 1 && ins.isNotEmpty) { List<String>? scriptChunks = outs[1].scriptPubKeyAsm?.split(" "); if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { final blindedPaymentCode = scriptChunks![1]; diff --git a/pubspec.lock b/pubspec.lock index 8364e6ec9..0c8768e2a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -100,8 +100,8 @@ packages: dependency: "direct main" description: path: "." - ref: testing - resolved-ref: "8ed2f6245c71a4457ed4ffdd3a74e4bcb9f9d2d0" + ref: "2d800225329498841affa1386d96d2696c62b713" + resolved-ref: "2d800225329498841affa1386d96d2696c62b713" url: "https://github.com/cypherstack/bip47.git" source: git version: "1.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 058021b9f..967c9cba4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,7 +59,7 @@ dependencies: bip47: git: url: https://github.com/cypherstack/bip47.git - ref: testing + ref: 2d800225329498841affa1386d96d2696c62b713 # Utility plugins # provider: ^6.0.1 From 6b08acf225b10f5ac71f7784d3d8155d464acec6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 12:08:48 -0600 Subject: [PATCH 017/123] single DerivePathType enum declaration --- lib/services/coins/bitcoin/bitcoin_wallet.dart | 3 +-- .../coins/bitcoincash/bitcoincash_wallet.dart | 14 +++++++++----- lib/services/coins/dogecoin/dogecoin_wallet.dart | 16 ++++++++++------ lib/services/coins/litecoin/litecoin_wallet.dart | 3 +-- lib/services/coins/namecoin/namecoin_wallet.dart | 3 +-- lib/services/coins/particl/particl_wallet.dart | 11 +++++++++-- lib/utilities/enums/derive_path_type_enum.dart | 1 + 7 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 lib/utilities/enums/derive_path_type_enum.dart diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index d0b114829..2194c5a19 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -33,6 +33,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +51,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"; -enum DerivePathType { bip44, bip49, bip84 } - bip32.BIP32 getBip32Node( int chain, int index, diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 70e3a5d55..84f302dec 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -34,6 +34,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +51,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"; -enum DerivePathType { bip44, bip49 } - bip32.BIP32 getBip32Node(int chain, int index, String mnemonic, NetworkType network, DerivePathType derivePathType) { final root = getBip32Root(mnemonic, network); @@ -1421,9 +1420,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .address!; addrType = isar_models.AddressType.p2sh; break; - // default: - // // should never hit this due to all enum cases handled - // return null; + case DerivePathType.bip84: + throw UnsupportedError("bip84 not supported by BCH"); } // add generated address & info to derivations @@ -1466,6 +1464,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip49: type = isar_models.AddressType.p2sh; break; + case DerivePathType.bip84: + throw UnsupportedError("bip84 not supported by BCH"); } final address = await db @@ -1491,6 +1491,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip49: key = "${walletId}_${chainId}DerivationsP2SH"; break; + case DerivePathType.bip84: + throw UnsupportedError("bip84 not supported by BCH"); } return key; } @@ -2611,6 +2613,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip49: addressesP2SH.add(address); break; + case DerivePathType.bip84: + throw UnsupportedError("bip84 not supported by BCH"); } } } diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index c47ad8947..c8cc68f8e 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -34,6 +34,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +51,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e"; -enum DerivePathType { bip44 } - bip32.BIP32 getBip32Node(int chain, int index, String mnemonic, NetworkType network, DerivePathType derivePathType) { final root = getBip32Root(mnemonic, network); @@ -90,7 +89,7 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip44: return root.derivePath("m/44'/$coinType'/0'/$chain/$index"); default: - throw Exception("DerivePathType must not be null."); + throw Exception("Unsupported DerivePathType"); } } @@ -1273,9 +1272,8 @@ class DogecoinWallet extends CoinServiceAPI case DerivePathType.bip44: address = P2PKH(data: data, network: network).data.address!; break; - // default: - // // should never hit this due to all enum cases handled - // return null; + default: + throw Exception("Unsupported DerivePathType"); } // add generated address & info to derivations @@ -1320,6 +1318,8 @@ class DogecoinWallet extends CoinServiceAPI .sortByDerivationIndexDesc() .findFirst(); break; + default: + throw Exception("Unsupported DerivePathType"); } return address!.value; } @@ -1332,6 +1332,8 @@ class DogecoinWallet extends CoinServiceAPI case DerivePathType.bip44: key = "${walletId}_${chainId}DerivationsP2PKH"; break; + default: + throw Exception("Unsupported DerivePathType"); } return key; } @@ -2339,6 +2341,8 @@ class DogecoinWallet extends CoinServiceAPI case DerivePathType.bip44: addressesP2PKH.add(address); break; + default: + throw Exception("Unsupported DerivePathType"); } } } diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index fe1fdf13c..aed4182a8 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -33,6 +33,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +51,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "4966625a4b2851d9fdee139e56211a0d88575f59ed816ff5e6a63deb4e3e29a0"; -enum DerivePathType { bip44, bip49, bip84 } - bip32.BIP32 getBip32Node( int chain, int index, diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index cae6cf29a..2805f5412 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -33,6 +33,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +51,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"; -enum DerivePathType { bip44, bip49, bip84 } - bip32.BIP32 getBip32Node( int chain, int index, diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index d19fdf769..22b90d05f 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -32,6 +32,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -48,8 +49,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "0000594ada5310b367443ee0afd4fa3d0bbd5850ea4e33cdc7d6a904a7ec7c90"; -enum DerivePathType { bip44, bip84 } - bip32.BIP32 getBip32Node( int chain, int index, @@ -1407,6 +1406,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { address = P2WPKH(network: _network, data: data).data.address!; addrType = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("Unsupported DerivePathType"); } // add generated address & info to derivations @@ -1450,6 +1451,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: type = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("Unsupported DerivePathType"); } address = await db .getAddresses(walletId) @@ -1475,6 +1478,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: key = "${walletId}_${chainId}DerivationsP2WPKH"; break; + default: + throw Exception("Unsupported DerivePathType"); } return key; } @@ -2743,6 +2748,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: addressesP2WPKH.add(address); break; + default: + throw Exception("Unsupported DerivePathType"); } } } diff --git a/lib/utilities/enums/derive_path_type_enum.dart b/lib/utilities/enums/derive_path_type_enum.dart new file mode 100644 index 000000000..694b9158f --- /dev/null +++ b/lib/utilities/enums/derive_path_type_enum.dart @@ -0,0 +1 @@ +enum DerivePathType { bip44, bip49, bip84 } From 35ba2f9d793b275707ace72a38a884f54523fd02 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 12:13:01 -0600 Subject: [PATCH 018/123] use derive path type in paynym extension --- lib/services/coins/coin_paynym_extension.dart | 200 ++++++++++++------ 1 file changed, 134 insertions(+), 66 deletions(-) diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index a97ccd355..f80f78961 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -18,6 +18,8 @@ import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:tuple/tuple.dart'; +import '../../utilities/enums/derive_path_type_enum.dart'; + const kPaynymDerivePath = "m/47'/0'/0'"; extension PayNym on DogecoinWallet { @@ -38,39 +40,14 @@ extension PayNym on DogecoinWallet { } /// fetch or generate this wallet's bip47 payment code - Future<PaymentCode> getPaymentCode() async { - final address = await db - .getAddresses(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymNotification) - .and() - .not() - .typeEqualTo(AddressType.nonWallet) - .findFirst(); - PaymentCode paymentCode; - if (address == null) { - final root = await getRootNode(mnemonic: await mnemonic); - final node = root.derivePath(kPaynymDerivePath); - paymentCode = PaymentCode.initFromPubKey( - node.publicKey, - node.chainCode, - network, - ); - - await db.putAddress( - Address( - walletId: walletId, - value: paymentCode.notificationAddress(), - publicKey: paymentCode.getPubKey(), - derivationIndex: 0, - type: AddressType.p2pkh, // todo change this for btc - subType: AddressSubType.paynymNotification, - otherData: paymentCode.toString(), - ), - ); - } else { - paymentCode = PaymentCode.fromPaymentCode(address.otherData!, network); - } + Future<PaymentCode> getPaymentCode( + DerivePathType derivePathType, + ) async { + final address = await getMyNotificationAddress(derivePathType); + final paymentCode = PaymentCode.fromPaymentCode( + address.otherData!, + network, + ); return paymentCode; } @@ -344,7 +321,7 @@ extension PayNym on DogecoinWallet { }) async { final targetPaymentCode = PaymentCode.fromPaymentCode(targetPaymentCodeString, network); - final myCode = await getPaymentCode(); + final myCode = await getPaymentCode(DerivePathType.bip44); final utxo = utxosToUse.first; final txPoint = utxo.txid.fromHex.toList(); @@ -443,7 +420,7 @@ extension PayNym on DogecoinWallet { // TODO optimize Future<bool> hasConnected(String paymentCodeString) async { - final myCode = await getPaymentCode(); + final myCode = await getPaymentCode(DerivePathType.bip44); final myNotificationAddress = myCode.notificationAddress(); final txns = await db @@ -521,7 +498,7 @@ extension PayNym on DogecoinWallet { Future<List<PaymentCode>> getAllPaymentCodesFromNotificationTransactions() async { - final myCode = await getPaymentCode(); + final myCode = await getPaymentCode(DerivePathType.bip44); final txns = await db .getTransactions(walletId) .filter() @@ -627,21 +604,31 @@ extension PayNym on DogecoinWallet { break; // The following doesn't apply to doge currently - // - // case DerivePathType.bip49: - // addressString = btc_dart.P2SH( - // data: btc_dart.PaymentData( - // redeem: btc_dart.P2WPKH(data: data, network: network).data), - // network: network) - // .data - // .address!; - // addrType = AddressType.p2sh; - // break; - // case DerivePathType.bip84: - // addressString = btc_dart.P2WPKH(network: network, data: data).data.address!; - // addrType = AddressType.p2wpkh; - // break; + case DerivePathType.bip49: + addressString = btc_dart + .P2SH( + data: btc_dart.PaymentData( + redeem: btc_dart + .P2WPKH( + data: data, + network: network, + ) + .data), + network: network, + ) + .data + .address!; + break; + case DerivePathType.bip84: + addressString = btc_dart + .P2WPKH( + network: network, + data: data, + ) + .data + .address!; + break; } final address = Address( @@ -669,27 +656,44 @@ extension PayNym on DogecoinWallet { AddressType addrType; switch (derivePathType) { case DerivePathType.bip44: - addressString = - btc_dart.P2PKH(data: data, network: network).data.address!; + addressString = btc_dart + .P2PKH( + data: data, + network: network, + ) + .data + .address!; addrType = AddressType.p2pkh; break; // The following doesn't apply to doge currently - // - // case DerivePathType.bip49: - // addressString = btc_dart.P2SH( - // data: btc_dart.PaymentData( - // redeem: btc_dart.P2WPKH(data: data, network: network).data), - // network: network) - // .data - // .address!; - // addrType = AddressType.p2sh; - // break; - // case DerivePathType.bip84: - // addressString = btc_dart.P2WPKH(network: network, data: data).data.address!; - // addrType = AddressType.p2wpkh; - // break; + case DerivePathType.bip49: + addressString = btc_dart + .P2SH( + data: btc_dart.PaymentData( + redeem: btc_dart + .P2WPKH( + data: data, + network: network, + ) + .data), + network: network, + ) + .data + .address!; + addrType = AddressType.p2sh; + break; + case DerivePathType.bip84: + addressString = btc_dart + .P2WPKH( + network: network, + data: data, + ) + .data + .address!; + addrType = AddressType.p2wpkh; + break; } final address = Address( @@ -704,4 +708,68 @@ extension PayNym on DogecoinWallet { return address; } + + Future<Address> getMyNotificationAddress( + DerivePathType derivePathType, + ) async { + AddressType type; + switch (derivePathType) { + case DerivePathType.bip44: + type = AddressType.p2pkh; + break; + case DerivePathType.bip49: + type = AddressType.p2sh; + break; + case DerivePathType.bip84: + type = AddressType.p2wpkh; + break; + } + + final storedAddress = await db + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymNotification) + .and() + .typeEqualTo(type) + .and() + .not() + .typeEqualTo(AddressType.nonWallet) + .findFirst(); + + if (storedAddress != null) { + return storedAddress; + } else { + final root = await getRootNode(mnemonic: await mnemonic); + final node = root.derivePath(kPaynymDerivePath); + final paymentCode = PaymentCode.initFromPubKey( + node.publicKey, + node.chainCode, + network, + ); + + String addressString; + switch (derivePathType) { + case DerivePathType.bip44: + addressString = paymentCode.notificationAddress(); + break; + case DerivePathType.bip49: + throw Exception("DerivePathType not supported."); + case DerivePathType.bip84: + throw Exception("DerivePathType not supported."); + } + + final address = Address( + walletId: walletId, + value: addressString, + publicKey: paymentCode.getPubKey(), + derivationIndex: 0, + type: type, + subType: AddressSubType.paynymNotification, + otherData: paymentCode.toString(), + ); + + await db.putAddress(address); + return address; + } + } } From 79db4f048cdacc3d40bc74d69c1f026ab9283c29 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 13:49:14 -0600 Subject: [PATCH 019/123] use derive path type extension method per coin --- .../coins/bitcoin/bitcoin_wallet.dart | 22 ++++++------ .../coins/bitcoincash/bitcoincash_wallet.dart | 24 ++++++------- .../coins/dogecoin/dogecoin_wallet.dart | 22 ++++++------ .../coins/litecoin/litecoin_wallet.dart | 22 ++++++------ .../coins/namecoin/namecoin_wallet.dart | 22 ++++++------ .../coins/particl/particl_wallet.dart | 22 ++++++------ .../enums/derive_path_type_enum.dart | 36 ++++++++++++++++++- 7 files changed, 102 insertions(+), 68 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 2194c5a19..82e5f646d 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -193,7 +193,7 @@ class BitcoinWallet extends CoinServiceAPI .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip84); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -206,7 +206,7 @@ class BitcoinWallet extends CoinServiceAPI .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip84); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -1868,7 +1868,7 @@ class BitcoinWallet extends CoinServiceAPI // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1887,7 +1887,7 @@ class BitcoinWallet extends CoinServiceAPI } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1907,7 +1907,7 @@ class BitcoinWallet extends CoinServiceAPI // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip84); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1926,12 +1926,12 @@ class BitcoinWallet extends CoinServiceAPI } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2269,7 +2269,7 @@ class BitcoinWallet extends CoinServiceAPI utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip84), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2308,8 +2308,8 @@ class BitcoinWallet extends CoinServiceAPI feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip84); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -3035,7 +3035,7 @@ class BitcoinWallet extends CoinServiceAPI // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 84f302dec..969eb1815 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -169,7 +169,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip44); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -182,7 +182,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip44); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -1754,7 +1754,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip44); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1773,12 +1773,12 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1798,7 +1798,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip44); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1817,12 +1817,12 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2348,7 +2348,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip44), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2401,8 +2401,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip44); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -3001,7 +3001,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip44); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index c8cc68f8e..b276af965 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -168,7 +168,7 @@ class DogecoinWallet extends CoinServiceAPI .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip44); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); // @override Future<String> get currentChangeAddress async => @@ -182,7 +182,7 @@ class DogecoinWallet extends CoinServiceAPI .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip44); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -1657,7 +1657,7 @@ class DogecoinWallet extends CoinServiceAPI // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip44); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1676,12 +1676,12 @@ class DogecoinWallet extends CoinServiceAPI } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions($DerivePathType.bip44): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions($DerivePathType.bip44): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1701,7 +1701,7 @@ class DogecoinWallet extends CoinServiceAPI // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip44); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1720,7 +1720,7 @@ class DogecoinWallet extends CoinServiceAPI } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkChangeAddressForTransactions(${DerivePathType.bip44}): $e\n$s", + "Exception rethrown from _checkChangeAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2089,7 +2089,7 @@ class DogecoinWallet extends CoinServiceAPI utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip44), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2142,8 +2142,8 @@ class DogecoinWallet extends CoinServiceAPI feeForTwoOutputs) { // generate new change address if current change address has been used await checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip44); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -2760,7 +2760,7 @@ class DogecoinWallet extends CoinServiceAPI // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip44); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index aed4182a8..be93d478f 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -193,7 +193,7 @@ class LitecoinWallet extends CoinServiceAPI .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip84); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -206,7 +206,7 @@ class LitecoinWallet extends CoinServiceAPI .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip84); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -1891,7 +1891,7 @@ class LitecoinWallet extends CoinServiceAPI // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1910,7 +1910,7 @@ class LitecoinWallet extends CoinServiceAPI } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1930,7 +1930,7 @@ class LitecoinWallet extends CoinServiceAPI // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip84); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1949,12 +1949,12 @@ class LitecoinWallet extends CoinServiceAPI } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2349,7 +2349,7 @@ class LitecoinWallet extends CoinServiceAPI utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip84), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2388,8 +2388,8 @@ class LitecoinWallet extends CoinServiceAPI feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip84); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -3345,7 +3345,7 @@ class LitecoinWallet extends CoinServiceAPI // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 2805f5412..2cf0e8ef5 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -188,7 +188,7 @@ class NamecoinWallet extends CoinServiceAPI .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip84); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -201,7 +201,7 @@ class NamecoinWallet extends CoinServiceAPI .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip84); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -1873,7 +1873,7 @@ class NamecoinWallet extends CoinServiceAPI // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1892,7 +1892,7 @@ class NamecoinWallet extends CoinServiceAPI } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1912,7 +1912,7 @@ class NamecoinWallet extends CoinServiceAPI // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip84); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1932,12 +1932,12 @@ class NamecoinWallet extends CoinServiceAPI } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2336,7 +2336,7 @@ class NamecoinWallet extends CoinServiceAPI utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip84), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2375,8 +2375,8 @@ class NamecoinWallet extends CoinServiceAPI feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip84); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -3336,7 +3336,7 @@ class NamecoinWallet extends CoinServiceAPI // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 22b90d05f..4f822d87a 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -183,7 +183,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip84); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -196,7 +196,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip84); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -1766,7 +1766,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1785,7 +1785,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1805,7 +1805,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip84); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1824,12 +1824,12 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2506,7 +2506,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip84), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2545,8 +2545,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip84); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -3335,7 +3335,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/utilities/enums/derive_path_type_enum.dart b/lib/utilities/enums/derive_path_type_enum.dart index 694b9158f..55f103d45 100644 --- a/lib/utilities/enums/derive_path_type_enum.dart +++ b/lib/utilities/enums/derive_path_type_enum.dart @@ -1 +1,35 @@ -enum DerivePathType { bip44, bip49, bip84 } +import 'package:stackwallet/utilities/enums/coin_enum.dart'; + +enum DerivePathType { + bip44, + bip49, + bip84, +} + +extension DerivePathTypeExt on DerivePathType { + static DerivePathType primaryFor(Coin coin) { + switch (coin) { + case Coin.bitcoincash: + case Coin.bitcoincashTestnet: + case Coin.dogecoin: + case Coin.dogecoinTestNet: + case Coin.firo: + case Coin.firoTestNet: + return DerivePathType.bip44; + + case Coin.bitcoin: + case Coin.bitcoinTestNet: + case Coin.litecoin: + case Coin.litecoinTestNet: + case Coin.namecoin: + case Coin.particl: + return DerivePathType.bip84; + + case Coin.epicCash: + case Coin.monero: + case Coin.wownero: + throw UnsupportedError( + "$coin does not use bitcoin style derivation paths"); + } + } +} From 9c44dc6c6b31ff766a676bc401269481e84cba49 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 14:33:59 -0600 Subject: [PATCH 020/123] add support to make adding segwit paynym support simple once implemented --- lib/pages/paynym/paynym_claim_view.dart | 4 +- .../sub_widgets/wallet_navigation_bar.dart | 4 +- .../wallet_view/desktop_wallet_view.dart | 4 +- lib/services/coins/coin_paynym_extension.dart | 184 +++++++++++------- .../paynym_follow_toggle_button.dart | 7 +- pubspec.lock | 4 +- pubspec.yaml | 2 +- 7 files changed, 129 insertions(+), 80 deletions(-) diff --git a/lib/pages/paynym/paynym_claim_view.dart b/lib/pages/paynym/paynym_claim_view.dart index cf5ffc671..f141e04a4 100644 --- a/lib/pages/paynym/paynym_claim_view.dart +++ b/lib/pages/paynym/paynym_claim_view.dart @@ -12,6 +12,7 @@ import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.da import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; @@ -168,7 +169,8 @@ class _PaynymClaimViewState extends ConsumerState<PaynymClaimView> { if (shouldCancel) return; // get payment code - final pCode = await wallet.getPaymentCode(); + final pCode = await wallet.getPaymentCode( + DerivePathTypeExt.primaryFor(wallet.coin)); if (shouldCancel) return; diff --git a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart index 28b4e735c..f251dedd4 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart @@ -12,6 +12,7 @@ import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; @@ -120,7 +121,8 @@ class _WalletNavigationBarState extends State<WalletNavigationBar> { .getManager(widget.walletId) .wallet as DogecoinWallet); - final code = await wallet.getPaymentCode(); + final code = await wallet.getPaymentCode( + DerivePathTypeExt.primaryFor(wallet.coin)); final account = await ref .read(paynymAPIProvider) diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index d4a77bae8..d48646860 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -31,6 +31,7 @@ import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; @@ -304,7 +305,8 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> { .getManager(widget.walletId) .wallet as DogecoinWallet); - final code = await wallet.getPaymentCode(); + final code = + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(wallet.coin)); final account = await ref.read(paynymAPIProvider).nym(code.toString()); diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index f80f78961..7a631e154 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -14,12 +14,11 @@ import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:tuple/tuple.dart'; -import '../../utilities/enums/derive_path_type_enum.dart'; - const kPaynymDerivePath = "m/47'/0'/0'"; extension PayNym on DogecoinWallet { @@ -66,8 +65,10 @@ extension PayNym on DogecoinWallet { } Future<Future<Map<String, dynamic>>> preparePaymentCodeSend( - PaymentCode paymentCode, int satoshiAmount) async { - if (!(await hasConnected(paymentCode.notificationAddress()))) { + {required PaymentCode paymentCode, + required int satoshiAmount, + Map<String, dynamic>? args}) async { + if (!(await hasConnected(paymentCode.notificationAddressP2PKH()))) { throw PaynymSendException( "No notification transaction sent to $paymentCode"); } else { @@ -360,7 +361,8 @@ extension PayNym on DogecoinWallet { txPointIndex, ); - txb.addOutput(targetPaymentCode.notificationAddress(), DUST_LIMIT); + // todo: modify address once segwit support is in our bip47 + txb.addOutput(targetPaymentCode.notificationAddressP2PKH(), DUST_LIMIT); txb.addOutput(opReturnScript, 0); // TODO: add possible change output and mark output as dangerous @@ -420,8 +422,8 @@ extension PayNym on DogecoinWallet { // TODO optimize Future<bool> hasConnected(String paymentCodeString) async { - final myCode = await getPaymentCode(DerivePathType.bip44); - final myNotificationAddress = myCode.notificationAddress(); + final myNotificationAddress = + await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); final txns = await db .getTransactions(walletId) @@ -431,13 +433,13 @@ extension PayNym on DogecoinWallet { for (final tx in txns) { // quick check that may cause problems? - if (tx.address.value?.value == myNotificationAddress) { + if (tx.address.value?.value == myNotificationAddress.value) { return true; } final unBlindedPaymentCode = await unBlindedPaymentCodeFromTransaction( transaction: tx, - myCode: myCode, + myNotificationAddress: myNotificationAddress, ); if (paymentCodeString == unBlindedPaymentCode.toString()) { @@ -451,10 +453,10 @@ extension PayNym on DogecoinWallet { Future<PaymentCode?> unBlindedPaymentCodeFromTransaction({ required Transaction transaction, - required PaymentCode myCode, + required Address myNotificationAddress, }) async { if (transaction.address.value != null && - transaction.address.value!.value != myCode.notificationAddress()) { + transaction.address.value!.value != myNotificationAddress.value) { return null; } @@ -498,7 +500,8 @@ extension PayNym on DogecoinWallet { Future<List<PaymentCode>> getAllPaymentCodesFromNotificationTransactions() async { - final myCode = await getPaymentCode(DerivePathType.bip44); + final myAddress = + await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); final txns = await db .getTransactions(walletId) .filter() @@ -510,7 +513,7 @@ extension PayNym on DogecoinWallet { for (final tx in txns) { final unBlinded = await unBlindedPaymentCodeFromTransaction( transaction: tx, - myCode: myCode, + myNotificationAddress: myAddress, ); if (unBlinded != null) { unBlindedList.add(unBlinded); @@ -603,32 +606,34 @@ extension PayNym on DogecoinWallet { btc_dart.P2PKH(data: data, network: network).data.address!; break; - // The following doesn't apply to doge currently - case DerivePathType.bip49: - addressString = btc_dart - .P2SH( - data: btc_dart.PaymentData( - redeem: btc_dart - .P2WPKH( - data: data, - network: network, - ) - .data), - network: network, - ) - .data - .address!; - break; - - case DerivePathType.bip84: - addressString = btc_dart - .P2WPKH( - network: network, - data: data, - ) - .data - .address!; - break; + // The following doesn't apply currently + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // break; + // + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); } final address = Address( @@ -666,34 +671,36 @@ extension PayNym on DogecoinWallet { addrType = AddressType.p2pkh; break; - // The following doesn't apply to doge currently - case DerivePathType.bip49: - addressString = btc_dart - .P2SH( - data: btc_dart.PaymentData( - redeem: btc_dart - .P2WPKH( - data: data, - network: network, - ) - .data), - network: network, - ) - .data - .address!; - addrType = AddressType.p2sh; - break; - - case DerivePathType.bip84: - addressString = btc_dart - .P2WPKH( - network: network, - data: data, - ) - .data - .address!; - addrType = AddressType.p2wpkh; - break; + // The following doesn't apply currently + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // addrType = AddressType.p2sh; + // break; + // + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // addrType = AddressType.p2wpkh; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); } final address = Address( @@ -712,6 +719,9 @@ extension PayNym on DogecoinWallet { Future<Address> getMyNotificationAddress( DerivePathType derivePathType, ) async { + // TODO: fix when segwit is here + derivePathType = DerivePathType.bip44; + AddressType type; switch (derivePathType) { case DerivePathType.bip44: @@ -748,14 +758,44 @@ extension PayNym on DogecoinWallet { ); String addressString; + final data = + btc_dart.PaymentData(pubkey: paymentCode.notificationPublicKey()); switch (derivePathType) { case DerivePathType.bip44: - addressString = paymentCode.notificationAddress(); + addressString = btc_dart + .P2PKH( + data: data, + network: network, + ) + .data + .address!; break; - case DerivePathType.bip49: - throw Exception("DerivePathType not supported."); - case DerivePathType.bip84: - throw Exception("DerivePathType not supported."); + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // break; + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); } final address = Address( diff --git a/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart b/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart index ea3771d95..a93a4510c 100644 --- a/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart +++ b/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart @@ -12,6 +12,7 @@ import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.da import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; @@ -67,7 +68,8 @@ class _PaynymFollowToggleButtonState .read(paynymAPIProvider) .nym(widget.paymentCodeStringToFollow, true); - final myPCode = await wallet.getPaymentCode(); + final myPCode = + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(wallet.coin)); PaynymResponse<String> token = await ref.read(paynymAPIProvider).token(myPCode.toString()); @@ -167,7 +169,8 @@ class _PaynymFollowToggleButtonState .read(paynymAPIProvider) .nym(widget.paymentCodeStringToFollow, true); - final myPCode = await wallet.getPaymentCode(); + final myPCode = + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(wallet.coin)); PaynymResponse<String> token = await ref.read(paynymAPIProvider).token(myPCode.toString()); diff --git a/pubspec.lock b/pubspec.lock index 0c8768e2a..8721ccc48 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -100,8 +100,8 @@ packages: dependency: "direct main" description: path: "." - ref: "2d800225329498841affa1386d96d2696c62b713" - resolved-ref: "2d800225329498841affa1386d96d2696c62b713" + ref: "87bb760be323228aed6ca7bd4532a709a4f10690" + resolved-ref: "87bb760be323228aed6ca7bd4532a709a4f10690" url: "https://github.com/cypherstack/bip47.git" source: git version: "1.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 967c9cba4..759fc51f5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,7 +59,7 @@ dependencies: bip47: git: url: https://github.com/cypherstack/bip47.git - ref: 2d800225329498841affa1386d96d2696c62b713 + ref: 87bb760be323228aed6ca7bd4532a709a4f10690 # Utility plugins # provider: ^6.0.1 From 907c380812be5ac485efb44645df5dcf425264a6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 15:07:44 -0600 Subject: [PATCH 021/123] copy extension into a mixin --- lib/services/mixins/paynym_support.dart | 899 ++++++++++++++++++++++++ 1 file changed, 899 insertions(+) create mode 100644 lib/services/mixins/paynym_support.dart diff --git a/lib/services/mixins/paynym_support.dart b/lib/services/mixins/paynym_support.dart new file mode 100644 index 000000000..3db2ec602 --- /dev/null +++ b/lib/services/mixins/paynym_support.dart @@ -0,0 +1,899 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:bip32/bip32.dart' as bip32; +import 'package:bip47/bip47.dart'; +import 'package:bip47/src/util.dart'; +import 'package:bitcoindart/bitcoindart.dart' as btc_dart; +import 'package:bitcoindart/src/utils/constants/op.dart' as op; +import 'package:bitcoindart/src/utils/script.dart' as bscript; +import 'package:isar/isar.dart'; +import 'package:pointycastle/digests/sha256.dart'; +import 'package:stackwallet/db/main_db.dart'; +import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; +import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/utilities/bip32_utils.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/logger.dart'; +import 'package:tuple/tuple.dart'; + +const kPaynymDerivePath = "m/47'/0'/0'"; + +mixin PaynymSupport { + // passed in wallet data + late final String walletId; + late final String walletName; + late final btc_dart.NetworkType network; + late final Coin coin; + late final MainDB db; + late final ElectrumX electrumXClient; + + // passed in wallet functions + late final Future<List<String>> Function() getMnemonic; + late final Future<int> Function() getChainHeight; + late final Future<String> Function() getCurrentChangeAddress; + late final int Function({ + required int vSize, + required int feeRatePerKB, + }) estimateTxFee; + late final Future<Map<String, dynamic>> Function({ + required String address, + required int satoshiAmount, + Map<String, dynamic>? args, + }) prepareSend; + late final Future<int> Function({ + required String address, + }) getTxCount; + late final Future<Map<String, dynamic>> Function( + List<UTXO> utxosToUse, + ) fetchBuildTxData; + late final Future<void> Function() refresh; + late final Future<void> Function() checkChangeAddressForTransactions; + + // initializer + void initPaynymSupport({ + required String walletId, + required String walletName, + required btc_dart.NetworkType network, + required Coin coin, + required MainDB db, + required ElectrumX electrumXClient, + required Future<List<String>> Function() getMnemonic, + required Future<int> Function() getChainHeight, + required Future<String> Function() getCurrentChangeAddress, + required int Function({ + required int vSize, + required int feeRatePerKB, + }) + estimateTxFee, + required Future<Map<String, dynamic>> Function({ + required String address, + required int satoshiAmount, + Map<String, dynamic>? args, + }) + prepareSend, + required Future<int> Function({ + required String address, + }) + getTxCount, + required Future<Map<String, dynamic>> Function( + List<UTXO> utxosToUse, + ) + fetchBuildTxData, + required Future<void> Function() refresh, + required Future<void> Function() checkChangeAddressForTransactions, + }) { + this.walletId = walletId; + this.walletName = walletName; + this.network = network; + this.coin = coin; + this.db = db; + this.electrumXClient = electrumXClient; + this.getMnemonic = getMnemonic; + this.getChainHeight = getChainHeight; + this.getCurrentChangeAddress = getCurrentChangeAddress; + this.estimateTxFee = estimateTxFee; + this.prepareSend = prepareSend; + this.getTxCount = getTxCount; + this.fetchBuildTxData = fetchBuildTxData; + this.refresh = refresh; + this.checkChangeAddressForTransactions = checkChangeAddressForTransactions; + } + + // generate bip32 payment code root + Future<bip32.BIP32> getRootNode({ + required List<String> mnemonic, + }) async { + final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); + return root; + } + + Future<Uint8List> deriveNotificationPrivateKey({ + required List<String> mnemonic, + }) async { + final root = await getRootNode(mnemonic: mnemonic); + final node = root.derivePath(kPaynymDerivePath).derive(0); + return node.privateKey!; + } + + /// fetch or generate this wallet's bip47 payment code + Future<PaymentCode> getPaymentCode( + DerivePathType derivePathType, + ) async { + final address = await getMyNotificationAddress(derivePathType); + final paymentCode = PaymentCode.fromPaymentCode( + address.otherData!, + network, + ); + return paymentCode; + } + + Future<Uint8List> signWithNotificationKey(Uint8List data) async { + final privateKey = + await deriveNotificationPrivateKey(mnemonic: await getMnemonic()); + final pair = btc_dart.ECPair.fromPrivateKey(privateKey, network: network); + final signed = pair.sign(SHA256Digest().process(data)); + return signed; + } + + Future<String> signStringWithNotificationKey(String data) async { + final bytes = + await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); + return Format.uint8listToString(bytes); + } + + Future<Future<Map<String, dynamic>>> preparePaymentCodeSend( + {required PaymentCode paymentCode, + required int satoshiAmount, + Map<String, dynamic>? args}) async { + if (!(await hasConnected(paymentCode.notificationAddressP2PKH()))) { + throw PaynymSendException( + "No notification transaction sent to $paymentCode"); + } else { + final myPrivateKey = + await deriveNotificationPrivateKey(mnemonic: await getMnemonic()); + final sendToAddress = await nextUnusedSendAddressFrom( + pCode: paymentCode, + privateKey: myPrivateKey, + ); + + return prepareSend( + address: sendToAddress.value, satoshiAmount: satoshiAmount); + } + } + + /// get the next unused address to send to given the receiver's payment code + /// and your own private key + Future<Address> nextUnusedSendAddressFrom({ + required PaymentCode pCode, + required Uint8List privateKey, + int startIndex = 0, + }) async { + // https://en.bitcoin.it/wiki/BIP_0047#Path_levels + const maxCount = 2147483647; + + for (int i = startIndex; i < maxCount; i++) { + final address = await db + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymSend) + .and() + .otherDataEqualTo(pCode.toString()) + .and() + .derivationIndexEqualTo(i) + .findFirst(); + + if (address != null) { + final count = await getTxCount(address: address.value); + // return address if unused, otherwise continue to next index + if (count == 0) { + return address; + } + } else { + final pair = PaymentAddress.initWithPrivateKey( + privateKey, + pCode, + i, // index to use + ).getSendAddressKeyPair(); + + // add address to local db + final address = generatePaynymSendAddressFromKeyPair( + pair: pair, + derivationIndex: i, + derivePathType: DerivePathType.bip44, + toPaymentCode: pCode, + ); + await db.putAddress(address); + + final count = await getTxCount(address: address.value); + // return address if unused, otherwise continue to next index + if (count == 0) { + return address; + } + } + } + + throw PaynymSendException("Exhausted unused send addresses!"); + } + + Future<Map<String, dynamic>> prepareNotificationTx({ + required int selectedTxFeeRate, + required String targetPaymentCodeString, + int additionalOutputs = 0, + List<UTXO>? utxos, + }) async { + const amountToSend = DUST_LIMIT; + final List<UTXO> availableOutputs = + utxos ?? await db.getUTXOs(walletId).findAll(); + final List<UTXO> spendableOutputs = []; + int spendableSatoshiValue = 0; + + // Build list of spendable outputs and totaling their satoshi amount + for (var i = 0; i < availableOutputs.length; i++) { + if (availableOutputs[i].isBlocked == false && + availableOutputs[i] + .isConfirmed(await getChainHeight(), MINIMUM_CONFIRMATIONS) == + true) { + spendableOutputs.add(availableOutputs[i]); + spendableSatoshiValue += availableOutputs[i].value; + } + } + + if (spendableSatoshiValue < amountToSend) { + // insufficient balance + throw InsufficientBalanceException( + "Spendable balance is less than the minimum required for a notification transaction."); + } else if (spendableSatoshiValue == amountToSend) { + // insufficient balance due to missing amount to cover fee + throw InsufficientBalanceException( + "Remaining balance does not cover the network fee."); + } + + // sort spendable by age (oldest first) + spendableOutputs.sort((a, b) => b.blockTime!.compareTo(a.blockTime!)); + + int satoshisBeingUsed = 0; + int outputsBeingUsed = 0; + List<UTXO> utxoObjectsToUse = []; + + for (int i = 0; + satoshisBeingUsed < amountToSend && i < spendableOutputs.length; + i++) { + utxoObjectsToUse.add(spendableOutputs[i]); + satoshisBeingUsed += spendableOutputs[i].value; + outputsBeingUsed += 1; + } + + // add additional outputs if required + for (int i = 0; + i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; + i++) { + utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); + satoshisBeingUsed += spendableOutputs[outputsBeingUsed].value; + outputsBeingUsed += 1; + } + + // gather required signing data + final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse); + + final int vSizeForNoChange = (await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0)) + .item2; + + final int vSizeForWithChange = (await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: satoshisBeingUsed - amountToSend)) + .item2; + + // Assume 2 outputs, for recipient and payment code script + int feeForNoChange = estimateTxFee( + vSize: vSizeForNoChange, + feeRatePerKB: selectedTxFeeRate, + ); + + // Assume 3 outputs, for recipient, payment code script, and change + int feeForWithChange = estimateTxFee( + vSize: vSizeForWithChange, + feeRatePerKB: selectedTxFeeRate, + ); + + if (feeForNoChange < vSizeForNoChange * 1000) { + feeForNoChange = vSizeForNoChange * 1000; + } + if (feeForWithChange < vSizeForWithChange * 1000) { + feeForWithChange = vSizeForWithChange * 1000; + } + + if (satoshisBeingUsed - amountToSend > feeForNoChange + DUST_LIMIT) { + // try to add change output due to "left over" amount being greater than + // the estimated fee + the dust limit + int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; + + // check estimates are correct and build notification tx + if (changeAmount >= DUST_LIMIT && + satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { + final txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: changeAmount, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } else { + // something broke during fee estimation or the change amount is smaller + // than the dust limit. Try without change + final txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend; + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } + } else if (satoshisBeingUsed - amountToSend >= feeForNoChange) { + // since we already checked if we need to add a change output we can just + // build without change here + final txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend; + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } else { + // if we get here we do not have enough funds to cover the tx total so we + // check if we have any more available outputs and try again + if (spendableOutputs.length > outputsBeingUsed) { + return prepareNotificationTx( + selectedTxFeeRate: selectedTxFeeRate, + targetPaymentCodeString: targetPaymentCodeString, + additionalOutputs: additionalOutputs + 1, + ); + } else { + throw InsufficientBalanceException( + "Remaining balance does not cover the network fee."); + } + } + } + + // return tuple with string value equal to the raw tx hex and the int value + // equal to its vSize + Future<Tuple2<String, int>> _createNotificationTx({ + required String targetPaymentCodeString, + required List<UTXO> utxosToUse, + required Map<String, dynamic> utxoSigningData, + required int change, + }) async { + final targetPaymentCode = + PaymentCode.fromPaymentCode(targetPaymentCodeString, network); + final myCode = await getPaymentCode(DerivePathType.bip44); + + final utxo = utxosToUse.first; + final txPoint = utxo.txid.fromHex.toList(); + final txPointIndex = utxo.vout; + + final rev = Uint8List(txPoint.length + 4); + Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); + final buffer = rev.buffer.asByteData(); + buffer.setUint32(txPoint.length, txPointIndex, Endian.little); + + final myKeyPair = utxoSigningData[utxo.txid]["keyPair"] as btc_dart.ECPair; + + final S = SecretPoint( + myKeyPair.privateKey!, + targetPaymentCode.notificationPublicKey(), + ); + + final blindingMask = PaymentCode.getMask(S.ecdhSecret(), rev); + + final blindedPaymentCode = PaymentCode.blind( + myCode.getPayload(), + blindingMask, + ); + + final opReturnScript = bscript.compile([ + (op.OPS["OP_RETURN"] as int), + blindedPaymentCode, + ]); + + // build a notification tx + final txb = btc_dart.TransactionBuilder(network: network); + txb.setVersion(1); + + txb.addInput( + utxo.txid, + txPointIndex, + ); + + // todo: modify address once segwit support is in our bip47 + txb.addOutput(targetPaymentCode.notificationAddressP2PKH(), DUST_LIMIT); + txb.addOutput(opReturnScript, 0); + + // TODO: add possible change output and mark output as dangerous + if (change > 0) { + // generate new change address if current change address has been used + await checkChangeAddressForTransactions(); + final String changeAddress = await getCurrentChangeAddress(); + txb.addOutput(changeAddress, change); + } + + txb.sign( + vin: 0, + keyPair: myKeyPair, + ); + + // sign rest of possible inputs + for (var i = 1; i < utxosToUse.length - 1; i++) { + final txid = utxosToUse[i].txid; + txb.sign( + vin: i, + keyPair: utxoSigningData[txid]["keyPair"] as btc_dart.ECPair, + // witnessValue: utxosToUse[i].value, + ); + } + + final builtTx = txb.build(); + + return Tuple2(builtTx.toHex(), builtTx.virtualSize()); + } + + Future<String> broadcastNotificationTx( + {required Map<String, dynamic> preparedTx}) async { + try { + Logging.instance.log("confirmNotificationTx txData: $preparedTx", + level: LogLevel.Info); + final txHash = await electrumXClient.broadcastTransaction( + rawTx: preparedTx["hex"] as String); + Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); + + // TODO: only refresh transaction data + try { + await refresh(); + } catch (e) { + Logging.instance.log( + "refresh() failed in confirmNotificationTx ($walletName::$walletId): $e", + level: LogLevel.Error, + ); + } + + return txHash; + } catch (e, s) { + Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", + level: LogLevel.Error); + rethrow; + } + } + + // TODO optimize + Future<bool> hasConnected(String paymentCodeString) async { + final myNotificationAddress = + await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); + + final txns = await db + .getTransactions(walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .findAll(); + + for (final tx in txns) { + // quick check that may cause problems? + if (tx.address.value?.value == myNotificationAddress.value) { + return true; + } + + final unBlindedPaymentCode = await unBlindedPaymentCodeFromTransaction( + transaction: tx, + myNotificationAddress: myNotificationAddress, + ); + + if (paymentCodeString == unBlindedPaymentCode.toString()) { + return true; + } + } + + // otherwise return no + return false; + } + + Future<PaymentCode?> unBlindedPaymentCodeFromTransaction({ + required Transaction transaction, + required Address myNotificationAddress, + }) async { + if (transaction.address.value != null && + transaction.address.value!.value != myNotificationAddress.value) { + return null; + } + + try { + final blindedCode = + transaction.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1]; + + final designatedInput = transaction.inputs.first; + + final txPoint = designatedInput.txid.fromHex.toList(); + final txPointIndex = designatedInput.vout; + + final rev = Uint8List(txPoint.length + 4); + Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); + final buffer = rev.buffer.asByteData(); + buffer.setUint32(txPoint.length, txPointIndex, Endian.little); + + final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex; + + final myPrivateKey = + await deriveNotificationPrivateKey(mnemonic: await getMnemonic()); + + final S = SecretPoint(myPrivateKey, pubKey); + + final mask = PaymentCode.getMask(S.ecdhSecret(), rev); + + final unBlindedPayload = PaymentCode.blind(blindedCode.fromHex, mask); + + final unBlindedPaymentCode = + PaymentCode.initFromPayload(unBlindedPayload); + + return unBlindedPaymentCode; + } catch (e) { + Logging.instance.log( + "unBlindedPaymentCodeFromTransaction() failed: $e", + level: LogLevel.Warning, + ); + return null; + } + } + + Future<List<PaymentCode>> + getAllPaymentCodesFromNotificationTransactions() async { + final myAddress = + await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); + final txns = await db + .getTransactions(walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .findAll(); + + List<PaymentCode> unBlindedList = []; + + for (final tx in txns) { + final unBlinded = await unBlindedPaymentCodeFromTransaction( + transaction: tx, + myNotificationAddress: myAddress, + ); + if (unBlinded != null) { + unBlindedList.add(unBlinded); + } + } + + return unBlindedList; + } + + Future<void> restoreHistoryWith( + PaymentCode other, + int maxUnusedAddressGap, + int maxNumberOfIndexesToCheck, + ) async { + // https://en.bitcoin.it/wiki/BIP_0047#Path_levels + const maxCount = 2147483647; + assert(maxNumberOfIndexesToCheck < maxCount); + + final myPrivateKey = + await deriveNotificationPrivateKey(mnemonic: await getMnemonic()); + + List<Address> addresses = []; + int receivingGapCounter = 0; + int outgoingGapCounter = 0; + + for (int i = 0; + i < maxNumberOfIndexesToCheck && + (receivingGapCounter < maxUnusedAddressGap || + outgoingGapCounter < maxUnusedAddressGap); + i++) { + final paymentAddress = PaymentAddress.initWithPrivateKey( + myPrivateKey, + other, + i, // index to use + ); + + if (receivingGapCounter < maxUnusedAddressGap) { + final pair = paymentAddress.getSendAddressKeyPair(); + final address = generatePaynymSendAddressFromKeyPair( + pair: pair, + derivationIndex: i, + derivePathType: DerivePathType.bip44, + toPaymentCode: other, + ); + addresses.add(address); + + final count = await getTxCount(address: address.value); + + if (count > 0) { + receivingGapCounter++; + } else { + receivingGapCounter = 0; + } + } + + if (outgoingGapCounter < maxUnusedAddressGap) { + final pair = paymentAddress.getReceiveAddressKeyPair(); + final address = generatePaynymReceivingAddressFromKeyPair( + pair: pair, + derivationIndex: i, + derivePathType: DerivePathType.bip44, + fromPaymentCode: other, + ); + addresses.add(address); + + final count = await getTxCount(address: address.value); + + if (count > 0) { + outgoingGapCounter++; + } else { + outgoingGapCounter = 0; + } + } + } + await db.putAddresses(addresses); + } + + Address generatePaynymSendAddressFromKeyPair({ + required btc_dart.ECPair pair, + required int derivationIndex, + required DerivePathType derivePathType, + required PaymentCode toPaymentCode, + }) { + final data = btc_dart.PaymentData(pubkey: pair.publicKey); + + String addressString; + switch (derivePathType) { + case DerivePathType.bip44: + addressString = + btc_dart.P2PKH(data: data, network: network).data.address!; + break; + + // The following doesn't apply currently + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // break; + // + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); + } + + final address = Address( + walletId: walletId, + value: addressString, + publicKey: pair.publicKey, + derivationIndex: derivationIndex, + type: AddressType.nonWallet, + subType: AddressSubType.paynymSend, + otherData: toPaymentCode.toString(), + ); + + return address; + } + + Address generatePaynymReceivingAddressFromKeyPair({ + required btc_dart.ECPair pair, + required int derivationIndex, + required DerivePathType derivePathType, + required PaymentCode fromPaymentCode, + }) { + final data = btc_dart.PaymentData(pubkey: pair.publicKey); + + String addressString; + AddressType addrType; + switch (derivePathType) { + case DerivePathType.bip44: + addressString = btc_dart + .P2PKH( + data: data, + network: network, + ) + .data + .address!; + addrType = AddressType.p2pkh; + break; + + // The following doesn't apply currently + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // addrType = AddressType.p2sh; + // break; + // + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // addrType = AddressType.p2wpkh; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); + } + + final address = Address( + walletId: walletId, + value: addressString, + publicKey: pair.publicKey, + derivationIndex: derivationIndex, + type: addrType, + subType: AddressSubType.paynymReceive, + otherData: fromPaymentCode.toString(), + ); + + return address; + } + + Future<Address> getMyNotificationAddress( + DerivePathType derivePathType, + ) async { + // TODO: fix when segwit is here + derivePathType = DerivePathType.bip44; + + AddressType type; + switch (derivePathType) { + case DerivePathType.bip44: + type = AddressType.p2pkh; + break; + case DerivePathType.bip49: + type = AddressType.p2sh; + break; + case DerivePathType.bip84: + type = AddressType.p2wpkh; + break; + } + + final storedAddress = await db + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymNotification) + .and() + .typeEqualTo(type) + .and() + .not() + .typeEqualTo(AddressType.nonWallet) + .findFirst(); + + if (storedAddress != null) { + return storedAddress; + } else { + final root = await getRootNode(mnemonic: await getMnemonic()); + final node = root.derivePath(kPaynymDerivePath); + final paymentCode = PaymentCode.initFromPubKey( + node.publicKey, + node.chainCode, + network, + ); + + String addressString; + final data = + btc_dart.PaymentData(pubkey: paymentCode.notificationPublicKey()); + switch (derivePathType) { + case DerivePathType.bip44: + addressString = btc_dart + .P2PKH( + data: data, + network: network, + ) + .data + .address!; + break; + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // break; + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); + } + + final address = Address( + walletId: walletId, + value: addressString, + publicKey: paymentCode.getPubKey(), + derivationIndex: 0, + type: type, + subType: AddressSubType.paynymNotification, + otherData: paymentCode.toString(), + ); + + await db.putAddress(address); + return address; + } + } +} From 7cb497f4f770ec6cb57408b9bf2cba76b804751e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 15:46:48 -0600 Subject: [PATCH 022/123] remove coin enum hasPaynymSupport getter in favor of type checking --- .../sub_widgets/wallet_navigation_bar.dart | 26 ++++++++++--------- .../wallet_view/desktop_wallet_view.dart | 4 +-- lib/services/coins/manager.dart | 3 +++ lib/services/mixins/electrum_x_parsing.dart | 3 ++- lib/utilities/enums/coin_enum.dart | 23 ---------------- 5 files changed, 21 insertions(+), 38 deletions(-) diff --git a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart index f251dedd4..bb070f3e3 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart @@ -8,8 +8,7 @@ import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_support.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; @@ -18,7 +17,7 @@ import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/widgets/loading_indicator.dart'; -class WalletNavigationBar extends StatefulWidget { +class WalletNavigationBar extends ConsumerStatefulWidget { const WalletNavigationBar({ Key? key, required this.onReceivePressed, @@ -41,10 +40,11 @@ class WalletNavigationBar extends StatefulWidget { final String walletId; @override - State<WalletNavigationBar> createState() => _WalletNavigationBarState(); + ConsumerState<WalletNavigationBar> createState() => + _WalletNavigationBarState(); } -class _WalletNavigationBarState extends State<WalletNavigationBar> { +class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> { double scale = 0; final duration = const Duration(milliseconds: 200); @@ -115,14 +115,15 @@ class _WalletNavigationBarState extends State<WalletNavigationBar> { ), ); - // todo make generic and not doge specific - final wallet = (ref + final manager = ref .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet); + .getManager(widget.walletId); - final code = await wallet.getPaymentCode( - DerivePathTypeExt.primaryFor(wallet.coin)); + final paynymInterface = + manager.wallet as PaynymWalletInterface; + + final code = await paynymInterface.getPaymentCode( + DerivePathTypeExt.primaryFor(manager.coin)); final account = await ref .read(paynymAPIProvider) @@ -359,7 +360,8 @@ class _WalletNavigationBarState extends State<WalletNavigationBar> { ), ), ), - if (widget.coin.hasPaynymSupport) + if (ref.watch(walletsChangeNotifierProvider.select((value) => + value.getManager(widget.walletId).hasPaynymSupport))) RawMaterialButton( constraints: const BoxConstraints( minWidth: 66, diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index d48646860..5c1e048a0 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -21,7 +21,6 @@ import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/ui/transaction_filter_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; @@ -536,7 +535,8 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> { ); }, ), - if (coin.hasPaynymSupport) + if (ref.watch(walletsChangeNotifierProvider.select((value) => + value.getManager(widget.walletId).hasPaynymSupport))) SecondaryButton( label: "PayNym", width: 160, diff --git a/lib/services/coins/manager.dart b/lib/services/coins/manager.dart index a590752e0..65ba54c36 100644 --- a/lib/services/coins/manager.dart +++ b/lib/services/coins/manager.dart @@ -9,6 +9,7 @@ import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/paynym_support.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; @@ -214,4 +215,6 @@ class Manager with ChangeNotifier { } int get currentHeight => _currentWallet.storedChainHeight; + + bool get hasPaynymSupport => _currentWallet is PaynymWalletInterface; } diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index deac690f7..b95a749f1 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -1,6 +1,7 @@ import 'package:bip47/src/util.dart'; import 'package:decimal/decimal.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/services/mixins/paynym_support.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:tuple/tuple.dart'; @@ -186,7 +187,7 @@ mixin ElectrumXParsing { } TransactionSubType txSubType = TransactionSubType.none; - if (coin.hasPaynymSupport && outs.length > 1 && ins.isNotEmpty) { + if (this is PaynymWalletInterface && outs.length > 1 && ins.isNotEmpty) { List<String>? scriptChunks = outs[1].scriptPubKeyAsm?.split(" "); if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { final blindedPaymentCode = scriptChunks![1]; diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart index a517992de..df586ebf5 100644 --- a/lib/utilities/enums/coin_enum.dart +++ b/lib/utilities/enums/coin_enum.dart @@ -171,29 +171,6 @@ extension CoinExt on Coin { } } - bool get hasPaynymSupport { - switch (this) { - case Coin.bitcoin: - case Coin.litecoin: - case Coin.bitcoincash: - case Coin.firo: - case Coin.namecoin: - case Coin.particl: - case Coin.bitcoinTestNet: - case Coin.litecoinTestNet: - case Coin.bitcoincashTestnet: - case Coin.firoTestNet: - case Coin.epicCash: - case Coin.monero: - case Coin.wownero: - return false; - - case Coin.dogecoin: - case Coin.dogecoinTestNet: - return true; - } - } - int get requiredConfirmations { switch (this) { case Coin.bitcoin: From fb3f430edc87f1ccd6362fd24938dd9d534f4230 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 15:49:57 -0600 Subject: [PATCH 023/123] disable PaynymSupport extension and use PaynymWalletInterface instead --- .../sub_widgets/wallet_navigation_bar.dart | 2 +- lib/services/coins/coin_paynym_extension.dart | 1630 ++++++++--------- .../coins/dogecoin/dogecoin_wallet.dart | 20 +- lib/services/coins/manager.dart | 2 +- lib/services/mixins/electrum_x_parsing.dart | 2 +- ...port.dart => paynym_wallet_interface.dart} | 156 +- 6 files changed, 915 insertions(+), 897 deletions(-) rename lib/services/mixins/{paynym_support.dart => paynym_wallet_interface.dart} (88%) diff --git a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart index bb070f3e3..d8ca42192 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart @@ -8,7 +8,7 @@ import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/mixins/paynym_support.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index 7a631e154..082976f67 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -1,815 +1,815 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:bip32/bip32.dart' as bip32; -import 'package:bip47/bip47.dart'; -import 'package:bip47/src/util.dart'; -import 'package:bitcoindart/bitcoindart.dart' as btc_dart; -import 'package:bitcoindart/src/utils/constants/op.dart' as op; -import 'package:bitcoindart/src/utils/script.dart' as bscript; -import 'package:isar/isar.dart'; -import 'package:pointycastle/digests/sha256.dart'; -import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; -import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; -import 'package:stackwallet/models/isar/models/isar_models.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; -import 'package:stackwallet/utilities/bip32_utils.dart'; -import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; -import 'package:stackwallet/utilities/format.dart'; -import 'package:stackwallet/utilities/logger.dart'; -import 'package:tuple/tuple.dart'; - -const kPaynymDerivePath = "m/47'/0'/0'"; - -extension PayNym on DogecoinWallet { - // generate bip32 payment code root - Future<bip32.BIP32> getRootNode({ - required List<String> mnemonic, - }) async { - final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); - return root; - } - - Future<Uint8List> deriveNotificationPrivateKey({ - required List<String> mnemonic, - }) async { - final root = await getRootNode(mnemonic: mnemonic); - final node = root.derivePath(kPaynymDerivePath).derive(0); - return node.privateKey!; - } - - /// fetch or generate this wallet's bip47 payment code - Future<PaymentCode> getPaymentCode( - DerivePathType derivePathType, - ) async { - final address = await getMyNotificationAddress(derivePathType); - final paymentCode = PaymentCode.fromPaymentCode( - address.otherData!, - network, - ); - return paymentCode; - } - - Future<Uint8List> signWithNotificationKey(Uint8List data) async { - final privateKey = - await deriveNotificationPrivateKey(mnemonic: await mnemonic); - final pair = btc_dart.ECPair.fromPrivateKey(privateKey, network: network); - final signed = pair.sign(SHA256Digest().process(data)); - return signed; - } - - Future<String> signStringWithNotificationKey(String data) async { - final bytes = - await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); - return Format.uint8listToString(bytes); - } - - Future<Future<Map<String, dynamic>>> preparePaymentCodeSend( - {required PaymentCode paymentCode, - required int satoshiAmount, - Map<String, dynamic>? args}) async { - if (!(await hasConnected(paymentCode.notificationAddressP2PKH()))) { - throw PaynymSendException( - "No notification transaction sent to $paymentCode"); - } else { - final myPrivateKey = - await deriveNotificationPrivateKey(mnemonic: await mnemonic); - final sendToAddress = await nextUnusedSendAddressFrom( - pCode: paymentCode, - privateKey: myPrivateKey, - ); - - return prepareSend( - address: sendToAddress.value, satoshiAmount: satoshiAmount); - } - } - - /// get the next unused address to send to given the receiver's payment code - /// and your own private key - Future<Address> nextUnusedSendAddressFrom({ - required PaymentCode pCode, - required Uint8List privateKey, - int startIndex = 0, - }) async { - // https://en.bitcoin.it/wiki/BIP_0047#Path_levels - const maxCount = 2147483647; - - for (int i = startIndex; i < maxCount; i++) { - final address = await db - .getAddresses(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymSend) - .and() - .otherDataEqualTo(pCode.toString()) - .and() - .derivationIndexEqualTo(i) - .findFirst(); - - if (address != null) { - final count = await getTxCount(address: address.value); - // return address if unused, otherwise continue to next index - if (count == 0) { - return address; - } - } else { - final pair = PaymentAddress.initWithPrivateKey( - privateKey, - pCode, - i, // index to use - ).getSendAddressKeyPair(); - - // add address to local db - final address = generatePaynymSendAddressFromKeyPair( - pair: pair, - derivationIndex: i, - derivePathType: DerivePathType.bip44, - toPaymentCode: pCode, - ); - await db.putAddress(address); - - final count = await getTxCount(address: address.value); - // return address if unused, otherwise continue to next index - if (count == 0) { - return address; - } - } - } - - throw PaynymSendException("Exhausted unused send addresses!"); - } - - Future<Map<String, dynamic>> prepareNotificationTx({ - required int selectedTxFeeRate, - required String targetPaymentCodeString, - int additionalOutputs = 0, - List<UTXO>? utxos, - }) async { - const amountToSend = DUST_LIMIT; - final List<UTXO> availableOutputs = utxos ?? await this.utxos; - final List<UTXO> spendableOutputs = []; - int spendableSatoshiValue = 0; - - // Build list of spendable outputs and totaling their satoshi amount - for (var i = 0; i < availableOutputs.length; i++) { - if (availableOutputs[i].isBlocked == false && - availableOutputs[i] - .isConfirmed(await chainHeight, MINIMUM_CONFIRMATIONS) == - true) { - spendableOutputs.add(availableOutputs[i]); - spendableSatoshiValue += availableOutputs[i].value; - } - } - - if (spendableSatoshiValue < amountToSend) { - // insufficient balance - throw InsufficientBalanceException( - "Spendable balance is less than the minimum required for a notification transaction."); - } else if (spendableSatoshiValue == amountToSend) { - // insufficient balance due to missing amount to cover fee - throw InsufficientBalanceException( - "Remaining balance does not cover the network fee."); - } - - // sort spendable by age (oldest first) - spendableOutputs.sort((a, b) => b.blockTime!.compareTo(a.blockTime!)); - - int satoshisBeingUsed = 0; - int outputsBeingUsed = 0; - List<UTXO> utxoObjectsToUse = []; - - for (int i = 0; - satoshisBeingUsed < amountToSend && i < spendableOutputs.length; - i++) { - utxoObjectsToUse.add(spendableOutputs[i]); - satoshisBeingUsed += spendableOutputs[i].value; - outputsBeingUsed += 1; - } - - // add additional outputs if required - for (int i = 0; - i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; - i++) { - utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); - satoshisBeingUsed += spendableOutputs[outputsBeingUsed].value; - outputsBeingUsed += 1; - } - - // gather required signing data - final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse); - - final int vSizeForNoChange = (await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0)) - .item2; - - final int vSizeForWithChange = (await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: satoshisBeingUsed - amountToSend)) - .item2; - - // Assume 2 outputs, for recipient and payment code script - int feeForNoChange = estimateTxFee( - vSize: vSizeForNoChange, - feeRatePerKB: selectedTxFeeRate, - ); - - // Assume 3 outputs, for recipient, payment code script, and change - int feeForWithChange = estimateTxFee( - vSize: vSizeForWithChange, - feeRatePerKB: selectedTxFeeRate, - ); - - if (feeForNoChange < vSizeForNoChange * 1000) { - feeForNoChange = vSizeForNoChange * 1000; - } - if (feeForWithChange < vSizeForWithChange * 1000) { - feeForWithChange = vSizeForWithChange * 1000; - } - - if (satoshisBeingUsed - amountToSend > feeForNoChange + DUST_LIMIT) { - // try to add change output due to "left over" amount being greater than - // the estimated fee + the dust limit - int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; - - // check estimates are correct and build notification tx - if (changeAmount >= DUST_LIMIT && - satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: changeAmount, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } else { - // something broke during fee estimation or the change amount is smaller - // than the dust limit. Try without change - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } - } else if (satoshisBeingUsed - amountToSend >= feeForNoChange) { - // since we already checked if we need to add a change output we can just - // build without change here - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } else { - // if we get here we do not have enough funds to cover the tx total so we - // check if we have any more available outputs and try again - if (spendableOutputs.length > outputsBeingUsed) { - return prepareNotificationTx( - selectedTxFeeRate: selectedTxFeeRate, - targetPaymentCodeString: targetPaymentCodeString, - additionalOutputs: additionalOutputs + 1, - ); - } else { - throw InsufficientBalanceException( - "Remaining balance does not cover the network fee."); - } - } - } - - // return tuple with string value equal to the raw tx hex and the int value - // equal to its vSize - Future<Tuple2<String, int>> _createNotificationTx({ - required String targetPaymentCodeString, - required List<UTXO> utxosToUse, - required Map<String, dynamic> utxoSigningData, - required int change, - }) async { - final targetPaymentCode = - PaymentCode.fromPaymentCode(targetPaymentCodeString, network); - final myCode = await getPaymentCode(DerivePathType.bip44); - - final utxo = utxosToUse.first; - final txPoint = utxo.txid.fromHex.toList(); - final txPointIndex = utxo.vout; - - final rev = Uint8List(txPoint.length + 4); - Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); - final buffer = rev.buffer.asByteData(); - buffer.setUint32(txPoint.length, txPointIndex, Endian.little); - - final myKeyPair = utxoSigningData[utxo.txid]["keyPair"] as btc_dart.ECPair; - - final S = SecretPoint( - myKeyPair.privateKey!, - targetPaymentCode.notificationPublicKey(), - ); - - final blindingMask = PaymentCode.getMask(S.ecdhSecret(), rev); - - final blindedPaymentCode = PaymentCode.blind( - myCode.getPayload(), - blindingMask, - ); - - final opReturnScript = bscript.compile([ - (op.OPS["OP_RETURN"] as int), - blindedPaymentCode, - ]); - - // build a notification tx - final txb = btc_dart.TransactionBuilder(network: network); - txb.setVersion(1); - - txb.addInput( - utxo.txid, - txPointIndex, - ); - - // todo: modify address once segwit support is in our bip47 - txb.addOutput(targetPaymentCode.notificationAddressP2PKH(), DUST_LIMIT); - txb.addOutput(opReturnScript, 0); - - // TODO: add possible change output and mark output as dangerous - if (change > 0) { - // generate new change address if current change address has been used - await checkChangeAddressForTransactions(); - final String changeAddress = await currentChangeAddress; - txb.addOutput(changeAddress, change); - } - - txb.sign( - vin: 0, - keyPair: myKeyPair, - ); - - // sign rest of possible inputs - for (var i = 1; i < utxosToUse.length - 1; i++) { - final txid = utxosToUse[i].txid; - txb.sign( - vin: i, - keyPair: utxoSigningData[txid]["keyPair"] as btc_dart.ECPair, - // witnessValue: utxosToUse[i].value, - ); - } - - final builtTx = txb.build(); - - return Tuple2(builtTx.toHex(), builtTx.virtualSize()); - } - - Future<String> broadcastNotificationTx( - {required Map<String, dynamic> preparedTx}) async { - try { - Logging.instance.log("confirmNotificationTx txData: $preparedTx", - level: LogLevel.Info); - final txHash = await electrumXClient.broadcastTransaction( - rawTx: preparedTx["hex"] as String); - Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); - - // TODO: only refresh transaction data - try { - await refresh(); - } catch (e) { - Logging.instance.log( - "refresh() failed in confirmNotificationTx ($walletName::$walletId): $e", - level: LogLevel.Error, - ); - } - - return txHash; - } catch (e, s) { - Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", - level: LogLevel.Error); - rethrow; - } - } - - // TODO optimize - Future<bool> hasConnected(String paymentCodeString) async { - final myNotificationAddress = - await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); - - final txns = await db - .getTransactions(walletId) - .filter() - .subTypeEqualTo(TransactionSubType.bip47Notification) - .findAll(); - - for (final tx in txns) { - // quick check that may cause problems? - if (tx.address.value?.value == myNotificationAddress.value) { - return true; - } - - final unBlindedPaymentCode = await unBlindedPaymentCodeFromTransaction( - transaction: tx, - myNotificationAddress: myNotificationAddress, - ); - - if (paymentCodeString == unBlindedPaymentCode.toString()) { - return true; - } - } - - // otherwise return no - return false; - } - - Future<PaymentCode?> unBlindedPaymentCodeFromTransaction({ - required Transaction transaction, - required Address myNotificationAddress, - }) async { - if (transaction.address.value != null && - transaction.address.value!.value != myNotificationAddress.value) { - return null; - } - - try { - final blindedCode = - transaction.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1]; - - final designatedInput = transaction.inputs.first; - - final txPoint = designatedInput.txid.fromHex.toList(); - final txPointIndex = designatedInput.vout; - - final rev = Uint8List(txPoint.length + 4); - Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); - final buffer = rev.buffer.asByteData(); - buffer.setUint32(txPoint.length, txPointIndex, Endian.little); - - final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex; - - final myPrivateKey = - await deriveNotificationPrivateKey(mnemonic: await mnemonic); - - final S = SecretPoint(myPrivateKey, pubKey); - - final mask = PaymentCode.getMask(S.ecdhSecret(), rev); - - final unBlindedPayload = PaymentCode.blind(blindedCode.fromHex, mask); - - final unBlindedPaymentCode = - PaymentCode.initFromPayload(unBlindedPayload); - - return unBlindedPaymentCode; - } catch (e) { - Logging.instance.log( - "unBlindedPaymentCodeFromTransaction() failed: $e", - level: LogLevel.Warning, - ); - return null; - } - } - - Future<List<PaymentCode>> - getAllPaymentCodesFromNotificationTransactions() async { - final myAddress = - await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); - final txns = await db - .getTransactions(walletId) - .filter() - .subTypeEqualTo(TransactionSubType.bip47Notification) - .findAll(); - - List<PaymentCode> unBlindedList = []; - - for (final tx in txns) { - final unBlinded = await unBlindedPaymentCodeFromTransaction( - transaction: tx, - myNotificationAddress: myAddress, - ); - if (unBlinded != null) { - unBlindedList.add(unBlinded); - } - } - - return unBlindedList; - } - - Future<void> restoreHistoryWith( - PaymentCode other, - int maxUnusedAddressGap, - int maxNumberOfIndexesToCheck, - ) async { - // https://en.bitcoin.it/wiki/BIP_0047#Path_levels - const maxCount = 2147483647; - assert(maxNumberOfIndexesToCheck < maxCount); - - final myPrivateKey = - await deriveNotificationPrivateKey(mnemonic: await mnemonic); - - List<Address> addresses = []; - int receivingGapCounter = 0; - int outgoingGapCounter = 0; - - for (int i = 0; - i < maxNumberOfIndexesToCheck && - (receivingGapCounter < maxUnusedAddressGap || - outgoingGapCounter < maxUnusedAddressGap); - i++) { - final paymentAddress = PaymentAddress.initWithPrivateKey( - myPrivateKey, - other, - i, // index to use - ); - - if (receivingGapCounter < maxUnusedAddressGap) { - final pair = paymentAddress.getSendAddressKeyPair(); - final address = generatePaynymSendAddressFromKeyPair( - pair: pair, - derivationIndex: i, - derivePathType: DerivePathType.bip44, - toPaymentCode: other, - ); - addresses.add(address); - - final count = await getTxCount(address: address.value); - - if (count > 0) { - receivingGapCounter++; - } else { - receivingGapCounter = 0; - } - } - - if (outgoingGapCounter < maxUnusedAddressGap) { - final pair = paymentAddress.getReceiveAddressKeyPair(); - final address = generatePaynymReceivingAddressFromKeyPair( - pair: pair, - derivationIndex: i, - derivePathType: DerivePathType.bip44, - fromPaymentCode: other, - ); - addresses.add(address); - - final count = await getTxCount(address: address.value); - - if (count > 0) { - outgoingGapCounter++; - } else { - outgoingGapCounter = 0; - } - } - } - await db.putAddresses(addresses); - } - - Address generatePaynymSendAddressFromKeyPair({ - required btc_dart.ECPair pair, - required int derivationIndex, - required DerivePathType derivePathType, - required PaymentCode toPaymentCode, - }) { - final data = btc_dart.PaymentData(pubkey: pair.publicKey); - - String addressString; - switch (derivePathType) { - case DerivePathType.bip44: - addressString = - btc_dart.P2PKH(data: data, network: network).data.address!; - break; - - // The following doesn't apply currently - // case DerivePathType.bip49: - // addressString = btc_dart - // .P2SH( - // data: btc_dart.PaymentData( - // redeem: btc_dart - // .P2WPKH( - // data: data, - // network: network, - // ) - // .data), - // network: network, - // ) - // .data - // .address!; - // break; - // - // case DerivePathType.bip84: - // addressString = btc_dart - // .P2WPKH( - // network: network, - // data: data, - // ) - // .data - // .address!; - // break; - default: - throw UnimplementedError("segwit paynyms not implemented yet"); - } - - final address = Address( - walletId: walletId, - value: addressString, - publicKey: pair.publicKey, - derivationIndex: derivationIndex, - type: AddressType.nonWallet, - subType: AddressSubType.paynymSend, - otherData: toPaymentCode.toString(), - ); - - return address; - } - - Address generatePaynymReceivingAddressFromKeyPair({ - required btc_dart.ECPair pair, - required int derivationIndex, - required DerivePathType derivePathType, - required PaymentCode fromPaymentCode, - }) { - final data = btc_dart.PaymentData(pubkey: pair.publicKey); - - String addressString; - AddressType addrType; - switch (derivePathType) { - case DerivePathType.bip44: - addressString = btc_dart - .P2PKH( - data: data, - network: network, - ) - .data - .address!; - addrType = AddressType.p2pkh; - break; - - // The following doesn't apply currently - // case DerivePathType.bip49: - // addressString = btc_dart - // .P2SH( - // data: btc_dart.PaymentData( - // redeem: btc_dart - // .P2WPKH( - // data: data, - // network: network, - // ) - // .data), - // network: network, - // ) - // .data - // .address!; - // addrType = AddressType.p2sh; - // break; - // - // case DerivePathType.bip84: - // addressString = btc_dart - // .P2WPKH( - // network: network, - // data: data, - // ) - // .data - // .address!; - // addrType = AddressType.p2wpkh; - // break; - default: - throw UnimplementedError("segwit paynyms not implemented yet"); - } - - final address = Address( - walletId: walletId, - value: addressString, - publicKey: pair.publicKey, - derivationIndex: derivationIndex, - type: addrType, - subType: AddressSubType.paynymReceive, - otherData: fromPaymentCode.toString(), - ); - - return address; - } - - Future<Address> getMyNotificationAddress( - DerivePathType derivePathType, - ) async { - // TODO: fix when segwit is here - derivePathType = DerivePathType.bip44; - - AddressType type; - switch (derivePathType) { - case DerivePathType.bip44: - type = AddressType.p2pkh; - break; - case DerivePathType.bip49: - type = AddressType.p2sh; - break; - case DerivePathType.bip84: - type = AddressType.p2wpkh; - break; - } - - final storedAddress = await db - .getAddresses(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymNotification) - .and() - .typeEqualTo(type) - .and() - .not() - .typeEqualTo(AddressType.nonWallet) - .findFirst(); - - if (storedAddress != null) { - return storedAddress; - } else { - final root = await getRootNode(mnemonic: await mnemonic); - final node = root.derivePath(kPaynymDerivePath); - final paymentCode = PaymentCode.initFromPubKey( - node.publicKey, - node.chainCode, - network, - ); - - String addressString; - final data = - btc_dart.PaymentData(pubkey: paymentCode.notificationPublicKey()); - switch (derivePathType) { - case DerivePathType.bip44: - addressString = btc_dart - .P2PKH( - data: data, - network: network, - ) - .data - .address!; - break; - // case DerivePathType.bip49: - // addressString = btc_dart - // .P2SH( - // data: btc_dart.PaymentData( - // redeem: btc_dart - // .P2WPKH( - // data: data, - // network: network, - // ) - // .data), - // network: network, - // ) - // .data - // .address!; - // break; - // case DerivePathType.bip84: - // addressString = btc_dart - // .P2WPKH( - // network: network, - // data: data, - // ) - // .data - // .address!; - // break; - default: - throw UnimplementedError("segwit paynyms not implemented yet"); - } - - final address = Address( - walletId: walletId, - value: addressString, - publicKey: paymentCode.getPubKey(), - derivationIndex: 0, - type: type, - subType: AddressSubType.paynymNotification, - otherData: paymentCode.toString(), - ); - - await db.putAddress(address); - return address; - } - } -} +// import 'dart:convert'; +// import 'dart:typed_data'; +// +// import 'package:bip32/bip32.dart' as bip32; +// import 'package:bip47/bip47.dart'; +// import 'package:bip47/src/util.dart'; +// import 'package:bitcoindart/bitcoindart.dart' as btc_dart; +// import 'package:bitcoindart/src/utils/constants/op.dart' as op; +// import 'package:bitcoindart/src/utils/script.dart' as bscript; +// import 'package:isar/isar.dart'; +// import 'package:pointycastle/digests/sha256.dart'; +// import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; +// import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; +// import 'package:stackwallet/models/isar/models/isar_models.dart'; +// import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +// import 'package:stackwallet/utilities/bip32_utils.dart'; +// import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +// import 'package:stackwallet/utilities/format.dart'; +// import 'package:stackwallet/utilities/logger.dart'; +// import 'package:tuple/tuple.dart'; +// +// const kPaynymDerivePath = "m/47'/0'/0'"; +// +// extension PayNym on DogecoinWallet { +// // generate bip32 payment code root +// Future<bip32.BIP32> getRootNode({ +// required List<String> mnemonic, +// }) async { +// final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); +// return root; +// } +// +// Future<Uint8List> deriveNotificationPrivateKey({ +// required List<String> mnemonic, +// }) async { +// final root = await getRootNode(mnemonic: mnemonic); +// final node = root.derivePath(kPaynymDerivePath).derive(0); +// return node.privateKey!; +// } +// +// /// fetch or generate this wallet's bip47 payment code +// Future<PaymentCode> getPaymentCode( +// DerivePathType derivePathType, +// ) async { +// final address = await getMyNotificationAddress(derivePathType); +// final paymentCode = PaymentCode.fromPaymentCode( +// address.otherData!, +// network, +// ); +// return paymentCode; +// } +// +// Future<Uint8List> signWithNotificationKey(Uint8List data) async { +// final privateKey = +// await deriveNotificationPrivateKey(mnemonic: await mnemonic); +// final pair = btc_dart.ECPair.fromPrivateKey(privateKey, network: network); +// final signed = pair.sign(SHA256Digest().process(data)); +// return signed; +// } +// +// Future<String> signStringWithNotificationKey(String data) async { +// final bytes = +// await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); +// return Format.uint8listToString(bytes); +// } +// +// Future<Future<Map<String, dynamic>>> preparePaymentCodeSend( +// {required PaymentCode paymentCode, +// required int satoshiAmount, +// Map<String, dynamic>? args}) async { +// if (!(await hasConnected(paymentCode.notificationAddressP2PKH()))) { +// throw PaynymSendException( +// "No notification transaction sent to $paymentCode"); +// } else { +// final myPrivateKey = +// await deriveNotificationPrivateKey(mnemonic: await mnemonic); +// final sendToAddress = await nextUnusedSendAddressFrom( +// pCode: paymentCode, +// privateKey: myPrivateKey, +// ); +// +// return prepareSend( +// address: sendToAddress.value, satoshiAmount: satoshiAmount); +// } +// } +// +// /// get the next unused address to send to given the receiver's payment code +// /// and your own private key +// Future<Address> nextUnusedSendAddressFrom({ +// required PaymentCode pCode, +// required Uint8List privateKey, +// int startIndex = 0, +// }) async { +// // https://en.bitcoin.it/wiki/BIP_0047#Path_levels +// const maxCount = 2147483647; +// +// for (int i = startIndex; i < maxCount; i++) { +// final address = await db +// .getAddresses(walletId) +// .filter() +// .subTypeEqualTo(AddressSubType.paynymSend) +// .and() +// .otherDataEqualTo(pCode.toString()) +// .and() +// .derivationIndexEqualTo(i) +// .findFirst(); +// +// if (address != null) { +// final count = await getTxCount(address: address.value); +// // return address if unused, otherwise continue to next index +// if (count == 0) { +// return address; +// } +// } else { +// final pair = PaymentAddress.initWithPrivateKey( +// privateKey, +// pCode, +// i, // index to use +// ).getSendAddressKeyPair(); +// +// // add address to local db +// final address = generatePaynymSendAddressFromKeyPair( +// pair: pair, +// derivationIndex: i, +// derivePathType: DerivePathType.bip44, +// toPaymentCode: pCode, +// ); +// await db.putAddress(address); +// +// final count = await getTxCount(address: address.value); +// // return address if unused, otherwise continue to next index +// if (count == 0) { +// return address; +// } +// } +// } +// +// throw PaynymSendException("Exhausted unused send addresses!"); +// } +// +// Future<Map<String, dynamic>> prepareNotificationTx({ +// required int selectedTxFeeRate, +// required String targetPaymentCodeString, +// int additionalOutputs = 0, +// List<UTXO>? utxos, +// }) async { +// const amountToSend = DUST_LIMIT; +// final List<UTXO> availableOutputs = utxos ?? await this.utxos; +// final List<UTXO> spendableOutputs = []; +// int spendableSatoshiValue = 0; +// +// // Build list of spendable outputs and totaling their satoshi amount +// for (var i = 0; i < availableOutputs.length; i++) { +// if (availableOutputs[i].isBlocked == false && +// availableOutputs[i] +// .isConfirmed(await chainHeight, MINIMUM_CONFIRMATIONS) == +// true) { +// spendableOutputs.add(availableOutputs[i]); +// spendableSatoshiValue += availableOutputs[i].value; +// } +// } +// +// if (spendableSatoshiValue < amountToSend) { +// // insufficient balance +// throw InsufficientBalanceException( +// "Spendable balance is less than the minimum required for a notification transaction."); +// } else if (spendableSatoshiValue == amountToSend) { +// // insufficient balance due to missing amount to cover fee +// throw InsufficientBalanceException( +// "Remaining balance does not cover the network fee."); +// } +// +// // sort spendable by age (oldest first) +// spendableOutputs.sort((a, b) => b.blockTime!.compareTo(a.blockTime!)); +// +// int satoshisBeingUsed = 0; +// int outputsBeingUsed = 0; +// List<UTXO> utxoObjectsToUse = []; +// +// for (int i = 0; +// satoshisBeingUsed < amountToSend && i < spendableOutputs.length; +// i++) { +// utxoObjectsToUse.add(spendableOutputs[i]); +// satoshisBeingUsed += spendableOutputs[i].value; +// outputsBeingUsed += 1; +// } +// +// // add additional outputs if required +// for (int i = 0; +// i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; +// i++) { +// utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); +// satoshisBeingUsed += spendableOutputs[outputsBeingUsed].value; +// outputsBeingUsed += 1; +// } +// +// // gather required signing data +// final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse); +// +// final int vSizeForNoChange = (await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: 0)) +// .item2; +// +// final int vSizeForWithChange = (await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: satoshisBeingUsed - amountToSend)) +// .item2; +// +// // Assume 2 outputs, for recipient and payment code script +// int feeForNoChange = estimateTxFee( +// vSize: vSizeForNoChange, +// feeRatePerKB: selectedTxFeeRate, +// ); +// +// // Assume 3 outputs, for recipient, payment code script, and change +// int feeForWithChange = estimateTxFee( +// vSize: vSizeForWithChange, +// feeRatePerKB: selectedTxFeeRate, +// ); +// +// if (feeForNoChange < vSizeForNoChange * 1000) { +// feeForNoChange = vSizeForNoChange * 1000; +// } +// if (feeForWithChange < vSizeForWithChange * 1000) { +// feeForWithChange = vSizeForWithChange * 1000; +// } +// +// if (satoshisBeingUsed - amountToSend > feeForNoChange + DUST_LIMIT) { +// // try to add change output due to "left over" amount being greater than +// // the estimated fee + the dust limit +// int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; +// +// // check estimates are correct and build notification tx +// if (changeAmount >= DUST_LIMIT && +// satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { +// final txn = await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: changeAmount, +// ); +// +// int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; +// +// Map<String, dynamic> transactionObject = { +// "hex": txn.item1, +// "recipientPaynym": targetPaymentCodeString, +// "amount": amountToSend, +// "fee": feeBeingPaid, +// "vSize": txn.item2, +// }; +// return transactionObject; +// } else { +// // something broke during fee estimation or the change amount is smaller +// // than the dust limit. Try without change +// final txn = await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: 0, +// ); +// +// int feeBeingPaid = satoshisBeingUsed - amountToSend; +// +// Map<String, dynamic> transactionObject = { +// "hex": txn.item1, +// "recipientPaynym": targetPaymentCodeString, +// "amount": amountToSend, +// "fee": feeBeingPaid, +// "vSize": txn.item2, +// }; +// return transactionObject; +// } +// } else if (satoshisBeingUsed - amountToSend >= feeForNoChange) { +// // since we already checked if we need to add a change output we can just +// // build without change here +// final txn = await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: 0, +// ); +// +// int feeBeingPaid = satoshisBeingUsed - amountToSend; +// +// Map<String, dynamic> transactionObject = { +// "hex": txn.item1, +// "recipientPaynym": targetPaymentCodeString, +// "amount": amountToSend, +// "fee": feeBeingPaid, +// "vSize": txn.item2, +// }; +// return transactionObject; +// } else { +// // if we get here we do not have enough funds to cover the tx total so we +// // check if we have any more available outputs and try again +// if (spendableOutputs.length > outputsBeingUsed) { +// return prepareNotificationTx( +// selectedTxFeeRate: selectedTxFeeRate, +// targetPaymentCodeString: targetPaymentCodeString, +// additionalOutputs: additionalOutputs + 1, +// ); +// } else { +// throw InsufficientBalanceException( +// "Remaining balance does not cover the network fee."); +// } +// } +// } +// +// // return tuple with string value equal to the raw tx hex and the int value +// // equal to its vSize +// Future<Tuple2<String, int>> _createNotificationTx({ +// required String targetPaymentCodeString, +// required List<UTXO> utxosToUse, +// required Map<String, dynamic> utxoSigningData, +// required int change, +// }) async { +// final targetPaymentCode = +// PaymentCode.fromPaymentCode(targetPaymentCodeString, network); +// final myCode = await getPaymentCode(DerivePathType.bip44); +// +// final utxo = utxosToUse.first; +// final txPoint = utxo.txid.fromHex.toList(); +// final txPointIndex = utxo.vout; +// +// final rev = Uint8List(txPoint.length + 4); +// Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); +// final buffer = rev.buffer.asByteData(); +// buffer.setUint32(txPoint.length, txPointIndex, Endian.little); +// +// final myKeyPair = utxoSigningData[utxo.txid]["keyPair"] as btc_dart.ECPair; +// +// final S = SecretPoint( +// myKeyPair.privateKey!, +// targetPaymentCode.notificationPublicKey(), +// ); +// +// final blindingMask = PaymentCode.getMask(S.ecdhSecret(), rev); +// +// final blindedPaymentCode = PaymentCode.blind( +// myCode.getPayload(), +// blindingMask, +// ); +// +// final opReturnScript = bscript.compile([ +// (op.OPS["OP_RETURN"] as int), +// blindedPaymentCode, +// ]); +// +// // build a notification tx +// final txb = btc_dart.TransactionBuilder(network: network); +// txb.setVersion(1); +// +// txb.addInput( +// utxo.txid, +// txPointIndex, +// ); +// +// // todo: modify address once segwit support is in our bip47 +// txb.addOutput(targetPaymentCode.notificationAddressP2PKH(), DUST_LIMIT); +// txb.addOutput(opReturnScript, 0); +// +// // TODO: add possible change output and mark output as dangerous +// if (change > 0) { +// // generate new change address if current change address has been used +// await checkChangeAddressForTransactions(); +// final String changeAddress = await currentChangeAddress; +// txb.addOutput(changeAddress, change); +// } +// +// txb.sign( +// vin: 0, +// keyPair: myKeyPair, +// ); +// +// // sign rest of possible inputs +// for (var i = 1; i < utxosToUse.length - 1; i++) { +// final txid = utxosToUse[i].txid; +// txb.sign( +// vin: i, +// keyPair: utxoSigningData[txid]["keyPair"] as btc_dart.ECPair, +// // witnessValue: utxosToUse[i].value, +// ); +// } +// +// final builtTx = txb.build(); +// +// return Tuple2(builtTx.toHex(), builtTx.virtualSize()); +// } +// +// Future<String> broadcastNotificationTx( +// {required Map<String, dynamic> preparedTx}) async { +// try { +// Logging.instance.log("confirmNotificationTx txData: $preparedTx", +// level: LogLevel.Info); +// final txHash = await electrumXClient.broadcastTransaction( +// rawTx: preparedTx["hex"] as String); +// Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); +// +// // TODO: only refresh transaction data +// try { +// await refresh(); +// } catch (e) { +// Logging.instance.log( +// "refresh() failed in confirmNotificationTx ($walletName::$walletId): $e", +// level: LogLevel.Error, +// ); +// } +// +// return txHash; +// } catch (e, s) { +// Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", +// level: LogLevel.Error); +// rethrow; +// } +// } +// +// // TODO optimize +// Future<bool> hasConnected(String paymentCodeString) async { +// final myNotificationAddress = +// await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); +// +// final txns = await db +// .getTransactions(walletId) +// .filter() +// .subTypeEqualTo(TransactionSubType.bip47Notification) +// .findAll(); +// +// for (final tx in txns) { +// // quick check that may cause problems? +// if (tx.address.value?.value == myNotificationAddress.value) { +// return true; +// } +// +// final unBlindedPaymentCode = await unBlindedPaymentCodeFromTransaction( +// transaction: tx, +// myNotificationAddress: myNotificationAddress, +// ); +// +// if (paymentCodeString == unBlindedPaymentCode.toString()) { +// return true; +// } +// } +// +// // otherwise return no +// return false; +// } +// +// Future<PaymentCode?> unBlindedPaymentCodeFromTransaction({ +// required Transaction transaction, +// required Address myNotificationAddress, +// }) async { +// if (transaction.address.value != null && +// transaction.address.value!.value != myNotificationAddress.value) { +// return null; +// } +// +// try { +// final blindedCode = +// transaction.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1]; +// +// final designatedInput = transaction.inputs.first; +// +// final txPoint = designatedInput.txid.fromHex.toList(); +// final txPointIndex = designatedInput.vout; +// +// final rev = Uint8List(txPoint.length + 4); +// Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); +// final buffer = rev.buffer.asByteData(); +// buffer.setUint32(txPoint.length, txPointIndex, Endian.little); +// +// final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex; +// +// final myPrivateKey = +// await deriveNotificationPrivateKey(mnemonic: await mnemonic); +// +// final S = SecretPoint(myPrivateKey, pubKey); +// +// final mask = PaymentCode.getMask(S.ecdhSecret(), rev); +// +// final unBlindedPayload = PaymentCode.blind(blindedCode.fromHex, mask); +// +// final unBlindedPaymentCode = +// PaymentCode.initFromPayload(unBlindedPayload); +// +// return unBlindedPaymentCode; +// } catch (e) { +// Logging.instance.log( +// "unBlindedPaymentCodeFromTransaction() failed: $e", +// level: LogLevel.Warning, +// ); +// return null; +// } +// } +// +// Future<List<PaymentCode>> +// getAllPaymentCodesFromNotificationTransactions() async { +// final myAddress = +// await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); +// final txns = await db +// .getTransactions(walletId) +// .filter() +// .subTypeEqualTo(TransactionSubType.bip47Notification) +// .findAll(); +// +// List<PaymentCode> unBlindedList = []; +// +// for (final tx in txns) { +// final unBlinded = await unBlindedPaymentCodeFromTransaction( +// transaction: tx, +// myNotificationAddress: myAddress, +// ); +// if (unBlinded != null) { +// unBlindedList.add(unBlinded); +// } +// } +// +// return unBlindedList; +// } +// +// Future<void> restoreHistoryWith( +// PaymentCode other, +// int maxUnusedAddressGap, +// int maxNumberOfIndexesToCheck, +// ) async { +// // https://en.bitcoin.it/wiki/BIP_0047#Path_levels +// const maxCount = 2147483647; +// assert(maxNumberOfIndexesToCheck < maxCount); +// +// final myPrivateKey = +// await deriveNotificationPrivateKey(mnemonic: await mnemonic); +// +// List<Address> addresses = []; +// int receivingGapCounter = 0; +// int outgoingGapCounter = 0; +// +// for (int i = 0; +// i < maxNumberOfIndexesToCheck && +// (receivingGapCounter < maxUnusedAddressGap || +// outgoingGapCounter < maxUnusedAddressGap); +// i++) { +// final paymentAddress = PaymentAddress.initWithPrivateKey( +// myPrivateKey, +// other, +// i, // index to use +// ); +// +// if (receivingGapCounter < maxUnusedAddressGap) { +// final pair = paymentAddress.getSendAddressKeyPair(); +// final address = generatePaynymSendAddressFromKeyPair( +// pair: pair, +// derivationIndex: i, +// derivePathType: DerivePathType.bip44, +// toPaymentCode: other, +// ); +// addresses.add(address); +// +// final count = await getTxCount(address: address.value); +// +// if (count > 0) { +// receivingGapCounter++; +// } else { +// receivingGapCounter = 0; +// } +// } +// +// if (outgoingGapCounter < maxUnusedAddressGap) { +// final pair = paymentAddress.getReceiveAddressKeyPair(); +// final address = generatePaynymReceivingAddressFromKeyPair( +// pair: pair, +// derivationIndex: i, +// derivePathType: DerivePathType.bip44, +// fromPaymentCode: other, +// ); +// addresses.add(address); +// +// final count = await getTxCount(address: address.value); +// +// if (count > 0) { +// outgoingGapCounter++; +// } else { +// outgoingGapCounter = 0; +// } +// } +// } +// await db.putAddresses(addresses); +// } +// +// Address generatePaynymSendAddressFromKeyPair({ +// required btc_dart.ECPair pair, +// required int derivationIndex, +// required DerivePathType derivePathType, +// required PaymentCode toPaymentCode, +// }) { +// final data = btc_dart.PaymentData(pubkey: pair.publicKey); +// +// String addressString; +// switch (derivePathType) { +// case DerivePathType.bip44: +// addressString = +// btc_dart.P2PKH(data: data, network: network).data.address!; +// break; +// +// // The following doesn't apply currently +// // case DerivePathType.bip49: +// // addressString = btc_dart +// // .P2SH( +// // data: btc_dart.PaymentData( +// // redeem: btc_dart +// // .P2WPKH( +// // data: data, +// // network: network, +// // ) +// // .data), +// // network: network, +// // ) +// // .data +// // .address!; +// // break; +// // +// // case DerivePathType.bip84: +// // addressString = btc_dart +// // .P2WPKH( +// // network: network, +// // data: data, +// // ) +// // .data +// // .address!; +// // break; +// default: +// throw UnimplementedError("segwit paynyms not implemented yet"); +// } +// +// final address = Address( +// walletId: walletId, +// value: addressString, +// publicKey: pair.publicKey, +// derivationIndex: derivationIndex, +// type: AddressType.nonWallet, +// subType: AddressSubType.paynymSend, +// otherData: toPaymentCode.toString(), +// ); +// +// return address; +// } +// +// Address generatePaynymReceivingAddressFromKeyPair({ +// required btc_dart.ECPair pair, +// required int derivationIndex, +// required DerivePathType derivePathType, +// required PaymentCode fromPaymentCode, +// }) { +// final data = btc_dart.PaymentData(pubkey: pair.publicKey); +// +// String addressString; +// AddressType addrType; +// switch (derivePathType) { +// case DerivePathType.bip44: +// addressString = btc_dart +// .P2PKH( +// data: data, +// network: network, +// ) +// .data +// .address!; +// addrType = AddressType.p2pkh; +// break; +// +// // The following doesn't apply currently +// // case DerivePathType.bip49: +// // addressString = btc_dart +// // .P2SH( +// // data: btc_dart.PaymentData( +// // redeem: btc_dart +// // .P2WPKH( +// // data: data, +// // network: network, +// // ) +// // .data), +// // network: network, +// // ) +// // .data +// // .address!; +// // addrType = AddressType.p2sh; +// // break; +// // +// // case DerivePathType.bip84: +// // addressString = btc_dart +// // .P2WPKH( +// // network: network, +// // data: data, +// // ) +// // .data +// // .address!; +// // addrType = AddressType.p2wpkh; +// // break; +// default: +// throw UnimplementedError("segwit paynyms not implemented yet"); +// } +// +// final address = Address( +// walletId: walletId, +// value: addressString, +// publicKey: pair.publicKey, +// derivationIndex: derivationIndex, +// type: addrType, +// subType: AddressSubType.paynymReceive, +// otherData: fromPaymentCode.toString(), +// ); +// +// return address; +// } +// +// Future<Address> getMyNotificationAddress( +// DerivePathType derivePathType, +// ) async { +// // TODO: fix when segwit is here +// derivePathType = DerivePathType.bip44; +// +// AddressType type; +// switch (derivePathType) { +// case DerivePathType.bip44: +// type = AddressType.p2pkh; +// break; +// case DerivePathType.bip49: +// type = AddressType.p2sh; +// break; +// case DerivePathType.bip84: +// type = AddressType.p2wpkh; +// break; +// } +// +// final storedAddress = await db +// .getAddresses(walletId) +// .filter() +// .subTypeEqualTo(AddressSubType.paynymNotification) +// .and() +// .typeEqualTo(type) +// .and() +// .not() +// .typeEqualTo(AddressType.nonWallet) +// .findFirst(); +// +// if (storedAddress != null) { +// return storedAddress; +// } else { +// final root = await getRootNode(mnemonic: await mnemonic); +// final node = root.derivePath(kPaynymDerivePath); +// final paymentCode = PaymentCode.initFromPubKey( +// node.publicKey, +// node.chainCode, +// network, +// ); +// +// String addressString; +// final data = +// btc_dart.PaymentData(pubkey: paymentCode.notificationPublicKey()); +// switch (derivePathType) { +// case DerivePathType.bip44: +// addressString = btc_dart +// .P2PKH( +// data: data, +// network: network, +// ) +// .data +// .address!; +// break; +// // case DerivePathType.bip49: +// // addressString = btc_dart +// // .P2SH( +// // data: btc_dart.PaymentData( +// // redeem: btc_dart +// // .P2WPKH( +// // data: data, +// // network: network, +// // ) +// // .data), +// // network: network, +// // ) +// // .data +// // .address!; +// // break; +// // case DerivePathType.bip84: +// // addressString = btc_dart +// // .P2WPKH( +// // network: network, +// // data: data, +// // ) +// // .data +// // .address!; +// // break; +// default: +// throw UnimplementedError("segwit paynyms not implemented yet"); +// } +// +// final address = Address( +// walletId: walletId, +// value: addressString, +// publicKey: paymentCode.getPubKey(), +// derivationIndex: 0, +// type: type, +// subType: AddressSubType.paynymNotification, +// otherData: paymentCode.toString(), +// ); +// +// await db.putAddress(address); +// return address; +// } +// } +// } diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index b276af965..f5a057500 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -24,6 +24,7 @@ import 'package:stackwallet/services/event_bus/events/global/updated_in_backgrou import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -125,7 +126,7 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { } class DogecoinWallet extends CoinServiceAPI - with WalletCache, WalletDB, ElectrumXParsing { + with WalletCache, WalletDB, ElectrumXParsing, PaynymWalletInterface { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); final _prefs = Prefs.instance; @@ -1099,6 +1100,23 @@ class DogecoinWallet extends CoinServiceAPI _secureStore = secureStore; initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); + initPaynymWalletInterface( + walletId: walletId, + walletName: walletName, + network: network, + coin: coin, + db: db, + electrumXClient: electrumXClient, + getMnemonic: () => mnemonic, + getChainHeight: () => chainHeight, + getCurrentChangeAddress: () => currentChangeAddress, + estimateTxFee: estimateTxFee, + prepareSend: prepareSend, + getTxCount: getTxCount, + fetchBuildTxData: fetchBuildTxData, + refresh: refresh, + checkChangeAddressForTransactions: checkChangeAddressForTransactions, + ); } @override diff --git a/lib/services/coins/manager.dart b/lib/services/coins/manager.dart index 65ba54c36..892766cf5 100644 --- a/lib/services/coins/manager.dart +++ b/lib/services/coins/manager.dart @@ -9,7 +9,7 @@ import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; -import 'package:stackwallet/services/mixins/paynym_support.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index b95a749f1..61bc03beb 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -1,7 +1,7 @@ import 'package:bip47/src/util.dart'; import 'package:decimal/decimal.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; -import 'package:stackwallet/services/mixins/paynym_support.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:tuple/tuple.dart'; diff --git a/lib/services/mixins/paynym_support.dart b/lib/services/mixins/paynym_wallet_interface.dart similarity index 88% rename from lib/services/mixins/paynym_support.dart rename to lib/services/mixins/paynym_wallet_interface.dart index 3db2ec602..1073c3c40 100644 --- a/lib/services/mixins/paynym_support.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -24,39 +24,39 @@ import 'package:tuple/tuple.dart'; const kPaynymDerivePath = "m/47'/0'/0'"; -mixin PaynymSupport { +mixin PaynymWalletInterface { // passed in wallet data - late final String walletId; - late final String walletName; - late final btc_dart.NetworkType network; - late final Coin coin; - late final MainDB db; - late final ElectrumX electrumXClient; + late final String _walletId; + late final String _walletName; + late final btc_dart.NetworkType _network; + late final Coin _coin; + late final MainDB _db; + late final ElectrumX _electrumXClient; // passed in wallet functions - late final Future<List<String>> Function() getMnemonic; - late final Future<int> Function() getChainHeight; - late final Future<String> Function() getCurrentChangeAddress; + late final Future<List<String>> Function() _getMnemonic; + late final Future<int> Function() _getChainHeight; + late final Future<String> Function() _getCurrentChangeAddress; late final int Function({ required int vSize, required int feeRatePerKB, - }) estimateTxFee; + }) _estimateTxFee; late final Future<Map<String, dynamic>> Function({ required String address, required int satoshiAmount, Map<String, dynamic>? args, - }) prepareSend; + }) _prepareSend; late final Future<int> Function({ required String address, - }) getTxCount; + }) _getTxCount; late final Future<Map<String, dynamic>> Function( List<UTXO> utxosToUse, - ) fetchBuildTxData; - late final Future<void> Function() refresh; - late final Future<void> Function() checkChangeAddressForTransactions; + ) _fetchBuildTxData; + late final Future<void> Function() _refresh; + late final Future<void> Function() _checkChangeAddressForTransactions; // initializer - void initPaynymSupport({ + void initPaynymWalletInterface({ required String walletId, required String walletName, required btc_dart.NetworkType network, @@ -88,28 +88,28 @@ mixin PaynymSupport { required Future<void> Function() refresh, required Future<void> Function() checkChangeAddressForTransactions, }) { - this.walletId = walletId; - this.walletName = walletName; - this.network = network; - this.coin = coin; - this.db = db; - this.electrumXClient = electrumXClient; - this.getMnemonic = getMnemonic; - this.getChainHeight = getChainHeight; - this.getCurrentChangeAddress = getCurrentChangeAddress; - this.estimateTxFee = estimateTxFee; - this.prepareSend = prepareSend; - this.getTxCount = getTxCount; - this.fetchBuildTxData = fetchBuildTxData; - this.refresh = refresh; - this.checkChangeAddressForTransactions = checkChangeAddressForTransactions; + _walletId = walletId; + _walletName = walletName; + _network = network; + _coin = coin; + _db = db; + _electrumXClient = electrumXClient; + _getMnemonic = getMnemonic; + _getChainHeight = getChainHeight; + _getCurrentChangeAddress = getCurrentChangeAddress; + _estimateTxFee = estimateTxFee; + _prepareSend = prepareSend; + _getTxCount = getTxCount; + _fetchBuildTxData = fetchBuildTxData; + _refresh = refresh; + _checkChangeAddressForTransactions = checkChangeAddressForTransactions; } // generate bip32 payment code root Future<bip32.BIP32> getRootNode({ required List<String> mnemonic, }) async { - final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); + final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), _network); return root; } @@ -128,15 +128,15 @@ mixin PaynymSupport { final address = await getMyNotificationAddress(derivePathType); final paymentCode = PaymentCode.fromPaymentCode( address.otherData!, - network, + _network, ); return paymentCode; } Future<Uint8List> signWithNotificationKey(Uint8List data) async { final privateKey = - await deriveNotificationPrivateKey(mnemonic: await getMnemonic()); - final pair = btc_dart.ECPair.fromPrivateKey(privateKey, network: network); + await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); + final pair = btc_dart.ECPair.fromPrivateKey(privateKey, network: _network); final signed = pair.sign(SHA256Digest().process(data)); return signed; } @@ -156,13 +156,13 @@ mixin PaynymSupport { "No notification transaction sent to $paymentCode"); } else { final myPrivateKey = - await deriveNotificationPrivateKey(mnemonic: await getMnemonic()); + await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); final sendToAddress = await nextUnusedSendAddressFrom( pCode: paymentCode, privateKey: myPrivateKey, ); - return prepareSend( + return _prepareSend( address: sendToAddress.value, satoshiAmount: satoshiAmount); } } @@ -178,8 +178,8 @@ mixin PaynymSupport { const maxCount = 2147483647; for (int i = startIndex; i < maxCount; i++) { - final address = await db - .getAddresses(walletId) + final address = await _db + .getAddresses(_walletId) .filter() .subTypeEqualTo(AddressSubType.paynymSend) .and() @@ -189,7 +189,7 @@ mixin PaynymSupport { .findFirst(); if (address != null) { - final count = await getTxCount(address: address.value); + final count = await _getTxCount(address: address.value); // return address if unused, otherwise continue to next index if (count == 0) { return address; @@ -208,9 +208,9 @@ mixin PaynymSupport { derivePathType: DerivePathType.bip44, toPaymentCode: pCode, ); - await db.putAddress(address); + await _db.putAddress(address); - final count = await getTxCount(address: address.value); + final count = await _getTxCount(address: address.value); // return address if unused, otherwise continue to next index if (count == 0) { return address; @@ -229,15 +229,15 @@ mixin PaynymSupport { }) async { const amountToSend = DUST_LIMIT; final List<UTXO> availableOutputs = - utxos ?? await db.getUTXOs(walletId).findAll(); + utxos ?? await _db.getUTXOs(_walletId).findAll(); final List<UTXO> spendableOutputs = []; int spendableSatoshiValue = 0; // Build list of spendable outputs and totaling their satoshi amount for (var i = 0; i < availableOutputs.length; i++) { if (availableOutputs[i].isBlocked == false && - availableOutputs[i] - .isConfirmed(await getChainHeight(), MINIMUM_CONFIRMATIONS) == + availableOutputs[i].isConfirmed( + await _getChainHeight(), MINIMUM_CONFIRMATIONS) == true) { spendableOutputs.add(availableOutputs[i]); spendableSatoshiValue += availableOutputs[i].value; @@ -279,7 +279,7 @@ mixin PaynymSupport { } // gather required signing data - final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse); + final utxoSigningData = await _fetchBuildTxData(utxoObjectsToUse); final int vSizeForNoChange = (await _createNotificationTx( targetPaymentCodeString: targetPaymentCodeString, @@ -296,13 +296,13 @@ mixin PaynymSupport { .item2; // Assume 2 outputs, for recipient and payment code script - int feeForNoChange = estimateTxFee( + int feeForNoChange = _estimateTxFee( vSize: vSizeForNoChange, feeRatePerKB: selectedTxFeeRate, ); // Assume 3 outputs, for recipient, payment code script, and change - int feeForWithChange = estimateTxFee( + int feeForWithChange = _estimateTxFee( vSize: vSizeForWithChange, feeRatePerKB: selectedTxFeeRate, ); @@ -405,7 +405,7 @@ mixin PaynymSupport { required int change, }) async { final targetPaymentCode = - PaymentCode.fromPaymentCode(targetPaymentCodeString, network); + PaymentCode.fromPaymentCode(targetPaymentCodeString, _network); final myCode = await getPaymentCode(DerivePathType.bip44); final utxo = utxosToUse.first; @@ -437,7 +437,7 @@ mixin PaynymSupport { ]); // build a notification tx - final txb = btc_dart.TransactionBuilder(network: network); + final txb = btc_dart.TransactionBuilder(network: _network); txb.setVersion(1); txb.addInput( @@ -452,8 +452,8 @@ mixin PaynymSupport { // TODO: add possible change output and mark output as dangerous if (change > 0) { // generate new change address if current change address has been used - await checkChangeAddressForTransactions(); - final String changeAddress = await getCurrentChangeAddress(); + await _checkChangeAddressForTransactions(); + final String changeAddress = await _getCurrentChangeAddress(); txb.addOutput(changeAddress, change); } @@ -482,16 +482,16 @@ mixin PaynymSupport { try { Logging.instance.log("confirmNotificationTx txData: $preparedTx", level: LogLevel.Info); - final txHash = await electrumXClient.broadcastTransaction( + final txHash = await _electrumXClient.broadcastTransaction( rawTx: preparedTx["hex"] as String); Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); // TODO: only refresh transaction data try { - await refresh(); + await _refresh(); } catch (e) { Logging.instance.log( - "refresh() failed in confirmNotificationTx ($walletName::$walletId): $e", + "refresh() failed in confirmNotificationTx ($_walletName::$_walletId): $e", level: LogLevel.Error, ); } @@ -507,10 +507,10 @@ mixin PaynymSupport { // TODO optimize Future<bool> hasConnected(String paymentCodeString) async { final myNotificationAddress = - await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); + await getMyNotificationAddress(DerivePathTypeExt.primaryFor(_coin)); - final txns = await db - .getTransactions(walletId) + final txns = await _db + .getTransactions(_walletId) .filter() .subTypeEqualTo(TransactionSubType.bip47Notification) .findAll(); @@ -561,7 +561,7 @@ mixin PaynymSupport { final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex; final myPrivateKey = - await deriveNotificationPrivateKey(mnemonic: await getMnemonic()); + await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); final S = SecretPoint(myPrivateKey, pubKey); @@ -585,9 +585,9 @@ mixin PaynymSupport { Future<List<PaymentCode>> getAllPaymentCodesFromNotificationTransactions() async { final myAddress = - await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); - final txns = await db - .getTransactions(walletId) + await getMyNotificationAddress(DerivePathTypeExt.primaryFor(_coin)); + final txns = await _db + .getTransactions(_walletId) .filter() .subTypeEqualTo(TransactionSubType.bip47Notification) .findAll(); @@ -617,7 +617,7 @@ mixin PaynymSupport { assert(maxNumberOfIndexesToCheck < maxCount); final myPrivateKey = - await deriveNotificationPrivateKey(mnemonic: await getMnemonic()); + await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); List<Address> addresses = []; int receivingGapCounter = 0; @@ -644,7 +644,7 @@ mixin PaynymSupport { ); addresses.add(address); - final count = await getTxCount(address: address.value); + final count = await _getTxCount(address: address.value); if (count > 0) { receivingGapCounter++; @@ -663,7 +663,7 @@ mixin PaynymSupport { ); addresses.add(address); - final count = await getTxCount(address: address.value); + final count = await _getTxCount(address: address.value); if (count > 0) { outgoingGapCounter++; @@ -672,7 +672,7 @@ mixin PaynymSupport { } } } - await db.putAddresses(addresses); + await _db.putAddresses(addresses); } Address generatePaynymSendAddressFromKeyPair({ @@ -687,7 +687,7 @@ mixin PaynymSupport { switch (derivePathType) { case DerivePathType.bip44: addressString = - btc_dart.P2PKH(data: data, network: network).data.address!; + btc_dart.P2PKH(data: data, network: _network).data.address!; break; // The following doesn't apply currently @@ -721,7 +721,7 @@ mixin PaynymSupport { } final address = Address( - walletId: walletId, + walletId: _walletId, value: addressString, publicKey: pair.publicKey, derivationIndex: derivationIndex, @@ -748,7 +748,7 @@ mixin PaynymSupport { addressString = btc_dart .P2PKH( data: data, - network: network, + network: _network, ) .data .address!; @@ -788,7 +788,7 @@ mixin PaynymSupport { } final address = Address( - walletId: walletId, + walletId: _walletId, value: addressString, publicKey: pair.publicKey, derivationIndex: derivationIndex, @@ -819,8 +819,8 @@ mixin PaynymSupport { break; } - final storedAddress = await db - .getAddresses(walletId) + final storedAddress = await _db + .getAddresses(_walletId) .filter() .subTypeEqualTo(AddressSubType.paynymNotification) .and() @@ -833,12 +833,12 @@ mixin PaynymSupport { if (storedAddress != null) { return storedAddress; } else { - final root = await getRootNode(mnemonic: await getMnemonic()); + final root = await getRootNode(mnemonic: await _getMnemonic()); final node = root.derivePath(kPaynymDerivePath); final paymentCode = PaymentCode.initFromPubKey( node.publicKey, node.chainCode, - network, + _network, ); String addressString; @@ -849,7 +849,7 @@ mixin PaynymSupport { addressString = btc_dart .P2PKH( data: data, - network: network, + network: _network, ) .data .address!; @@ -883,7 +883,7 @@ mixin PaynymSupport { } final address = Address( - walletId: walletId, + walletId: _walletId, value: addressString, publicKey: paymentCode.getPubKey(), derivationIndex: 0, @@ -892,7 +892,7 @@ mixin PaynymSupport { otherData: paymentCode.toString(), ); - await db.putAddress(address); + await _db.putAddress(address); return address; } } From 700084f70839bb91c3c42e2586a3013f68be7431 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 16:11:06 -0600 Subject: [PATCH 024/123] remove wallet specific derivePathType tests as it was removed from the wallet files --- test/services/coins/bitcoin/bitcoin_wallet_test.dart | 7 +------ .../coins/bitcoincash/bitcoincash_wallet_test.dart | 7 +------ test/services/coins/dogecoin/dogecoin_wallet_test.dart | 6 +----- test/services/coins/namecoin/namecoin_wallet_test.dart | 7 +------ test/services/coins/particl/particl_wallet_test.dart | 7 +------ 5 files changed, 5 insertions(+), 29 deletions(-) diff --git a/test/services/coins/bitcoin/bitcoin_wallet_test.dart b/test/services/coins/bitcoin/bitcoin_wallet_test.dart index 6fdea3d03..2efce36f3 100644 --- a/test/services/coins/bitcoin/bitcoin_wallet_test.dart +++ b/test/services/coins/bitcoin/bitcoin_wallet_test.dart @@ -11,6 +11,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'bitcoin_wallet_test.mocks.dart'; @@ -39,12 +40,6 @@ void main() async { }); }); - test("bitcoin DerivePathType enum", () { - expect(DerivePathType.values.length, 3); - expect(DerivePathType.values.toString(), - "[DerivePathType.bip44, DerivePathType.bip49, DerivePathType.bip84]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, bitcoin); diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart index c4cdede86..93d85c324 100644 --- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart @@ -11,6 +11,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'bitcoincash_wallet_test.mocks.dart'; @@ -40,12 +41,6 @@ void main() async { }); }); - test("bitcoincash DerivePathType enum", () { - expect(DerivePathType.values.length, 2); - expect(DerivePathType.values.toString(), - "[DerivePathType.bip44, DerivePathType.bip49]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, bitcoincash); diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.dart index e9f166736..7a025e760 100644 --- a/test/services/coins/dogecoin/dogecoin_wallet_test.dart +++ b/test/services/coins/dogecoin/dogecoin_wallet_test.dart @@ -11,6 +11,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'dogecoin_wallet_test.mocks.dart'; @@ -39,11 +40,6 @@ void main() { }); }); - test("dogecoin DerivePathType enum", () { - expect(DerivePathType.values.length, 1); - expect(DerivePathType.values.toString(), "[DerivePathType.bip44]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, dogecoin); diff --git a/test/services/coins/namecoin/namecoin_wallet_test.dart b/test/services/coins/namecoin/namecoin_wallet_test.dart index 53ce2edbd..22750a935 100644 --- a/test/services/coins/namecoin/namecoin_wallet_test.dart +++ b/test/services/coins/namecoin/namecoin_wallet_test.dart @@ -10,6 +10,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'namecoin_wallet_test.mocks.dart'; @@ -38,12 +39,6 @@ void main() { }); }); - test("namecoin DerivePathType enum", () { - expect(DerivePathType.values.length, 3); - expect(DerivePathType.values.toString(), - "[DerivePathType.bip44, DerivePathType.bip49, DerivePathType.bip84]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, namecoin); diff --git a/test/services/coins/particl/particl_wallet_test.dart b/test/services/coins/particl/particl_wallet_test.dart index 698a5f657..4f4d0e81b 100644 --- a/test/services/coins/particl/particl_wallet_test.dart +++ b/test/services/coins/particl/particl_wallet_test.dart @@ -10,6 +10,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/particl/particl_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'particl_wallet_test.mocks.dart'; @@ -39,12 +40,6 @@ void main() { }); }); - test("particl DerivePathType enum", () { - expect(DerivePathType.values.length, 2); - expect(DerivePathType.values.toString(), - "[DerivePathType.bip44, DerivePathType.bip84]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, particl); From 8cd34fc228b14a72a6dbf751e4a4affb19acb8e5 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 16:16:20 -0600 Subject: [PATCH 025/123] build runner update mocks --- .../pages/send_view/send_view_test.mocks.dart | 981 ++++++++++-------- ...d_address_book_view_screen_test.mocks.dart | 5 + ..._entry_details_view_screen_test.mocks.dart | 5 + ...ess_book_entry_view_screen_test.mocks.dart | 5 + .../lockscreen_view_screen_test.mocks.dart | 5 + .../main_view_screen_testA_test.mocks.dart | 5 + .../main_view_screen_testB_test.mocks.dart | 5 + .../main_view_screen_testC_test.mocks.dart | 5 + .../backup_key_view_screen_test.mocks.dart | 5 + ...up_key_warning_view_screen_test.mocks.dart | 5 + .../create_pin_view_screen_test.mocks.dart | 5 + ...restore_wallet_view_screen_test.mocks.dart | 5 + ...ify_backup_key_view_screen_test.mocks.dart | 5 + .../currency_view_screen_test.mocks.dart | 5 + ...dd_custom_node_view_screen_test.mocks.dart | 5 + .../node_details_view_screen_test.mocks.dart | 5 + .../wallet_backup_view_screen_test.mocks.dart | 5 + ...rescan_warning_view_screen_test.mocks.dart | 5 + ...elete_mnemonic_view_screen_test.mocks.dart | 5 + ...allet_settings_view_screen_test.mocks.dart | 5 + .../settings_view_screen_test.mocks.dart | 5 + ...search_results_view_screen_test.mocks.dart | 5 + .../confirm_send_view_screen_test.mocks.dart | 5 + .../receive_view_screen_test.mocks.dart | 5 + .../send_view_screen_test.mocks.dart | 5 + .../wallet_view_screen_test.mocks.dart | 5 + .../managed_favorite_test.mocks.dart | 937 +++++++++-------- .../table_view/table_view_row_test.mocks.dart | 805 +++++++------- .../transaction_card_test.mocks.dart | 5 + test/widget_tests/wallet_card_test.mocks.dart | 420 ++++---- ...et_info_row_balance_future_test.mocks.dart | 921 ++++++++-------- .../wallet_info_row_test.mocks.dart | 921 ++++++++-------- 32 files changed, 2803 insertions(+), 2312 deletions(-) diff --git a/test/pages/send_view/send_view_test.mocks.dart b/test/pages/send_view/send_view_test.mocks.dart index bcd5f44fc..12548c513 100644 --- a/test/pages/send_view/send_view_test.mocks.dart +++ b/test/pages/send_view/send_view_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i17; -import 'dart:ui' as _i19; +import 'dart:async' as _i18; +import 'dart:ui' as _i20; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,26 +13,28 @@ import 'package:stackwallet/db/main_db.dart' as _i13; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i11; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i10; import 'package:stackwallet/models/balance.dart' as _i12; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i22; -import 'package:stackwallet/models/node_model.dart' as _i20; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i23; +import 'package:stackwallet/models/node_model.dart' as _i21; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i9; import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart' - as _i25; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i21; -import 'package:stackwallet/services/coins/coin_service.dart' as _i14; + as _i27; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i22; +import 'package:stackwallet/services/coins/coin_service.dart' as _i15; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i23; +import 'package:stackwallet/services/locale_service.dart' as _i25; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i8; -import 'package:stackwallet/services/wallets.dart' as _i15; +import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i26; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i24; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i28; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i24; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i26; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' as _i7; -import 'package:stackwallet/utilities/prefs.dart' as _i18; +import 'package:stackwallet/utilities/prefs.dart' as _i19; +import 'package:tuple/tuple.dart' as _i14; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -171,9 +173,20 @@ class _FakeElectrumXNode_11 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_12 extends _i1.SmartFake - implements _i14.CoinServiceAPI { - _FakeCoinServiceAPI_12( +class _FakeTuple4_12<T1, T2, T3, T4> extends _i1.SmartFake + implements _i14.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_13 extends _i1.SmartFake + implements _i15.CoinServiceAPI { + _FakeCoinServiceAPI_13( Object parent, Invocation parentInvocation, ) : super( @@ -185,7 +198,7 @@ class _FakeCoinServiceAPI_12 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i15.Wallets { +class MockWallets extends _i1.Mock implements _i16.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -252,7 +265,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i16.Coin? coin}) => + List<String> getWalletIdsFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -262,18 +275,18 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Coin, + returnValue: <_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i16.Coin? coin) => + _i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -337,17 +350,17 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( + _i18.Future<void> load(_i19.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> loadAfterStackRestore( - _i18.Prefs? prefs, + _i18.Future<void> loadAfterStackRestore( + _i19.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -358,11 +371,11 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { managers, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -370,7 +383,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -396,19 +409,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i18.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i18.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i17.Future<Map<String, _i2.WalletInfo>>); + ) as _i18.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<bool> renameWallet({ + _i18.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -423,13 +436,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> addExistingStackWallet({ + _i18.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -443,13 +456,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<String?> addNewWallet({ + _i18.Future<String?> addNewWallet({ required String? name, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -462,46 +475,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i18.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i18.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> moveFavorite({ + _i18.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -514,48 +527,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i18.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i18.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<bool> isMnemonicVerified({required String? walletId}) => + _i18.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> setMnemonicVerified({required String? walletId}) => + _i18.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> deleteWallet( + _i18.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -567,20 +580,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i18.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -588,7 +601,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -630,33 +643,33 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), ) as _i7.SecureStorageInterface); @override - List<_i20.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i21.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i20.NodeModel>[], - ) as List<_i20.NodeModel>); + returnValue: <_i21.NodeModel>[], + ) as List<_i21.NodeModel>); @override - List<_i20.NodeModel> get nodes => (super.noSuchMethod( + List<_i21.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i20.NodeModel>[], - ) as List<_i20.NodeModel>); + returnValue: <_i21.NodeModel>[], + ) as List<_i21.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateDefaults() => (super.noSuchMethod( + _i18.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setPrimaryNodeFor({ - required _i16.Coin? coin, - required _i20.NodeModel? node, + _i18.Future<void> setPrimaryNodeFor({ + required _i17.Coin? coin, + required _i21.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -669,44 +682,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i20.NodeModel? getPrimaryNodeFor({required _i16.Coin? coin}) => + _i21.NodeModel? getPrimaryNodeFor({required _i17.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i20.NodeModel?); + )) as _i21.NodeModel?); @override - List<_i20.NodeModel> getNodesFor(_i16.Coin? coin) => (super.noSuchMethod( + List<_i21.NodeModel> getNodesFor(_i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i20.NodeModel>[], - ) as List<_i20.NodeModel>); + returnValue: <_i21.NodeModel>[], + ) as List<_i21.NodeModel>); @override - _i20.NodeModel? getNodeById({required String? id}) => + _i21.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i20.NodeModel?); + )) as _i21.NodeModel?); @override - List<_i20.NodeModel> failoverNodesFor({required _i16.Coin? coin}) => + List<_i21.NodeModel> failoverNodesFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i20.NodeModel>[], - ) as List<_i20.NodeModel>); + returnValue: <_i21.NodeModel>[], + ) as List<_i21.NodeModel>); @override - _i17.Future<void> add( - _i20.NodeModel? node, + _i18.Future<void> add( + _i21.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -719,11 +732,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> delete( + _i18.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -735,11 +748,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setEnabledState( + _i18.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -753,12 +766,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> edit( - _i20.NodeModel? editedNode, + _i18.Future<void> edit( + _i21.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -771,20 +784,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i18.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -792,7 +805,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -820,13 +833,13 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i22.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i17.Timer? _timer) => super.noSuchMethod( + set timer(_i18.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -903,59 +916,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override - _i17.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), - ) as _i17.Future<List<_i22.UTXO>>); + returnValue: _i18.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), + ) as _i18.Future<List<_i23.UTXO>>); @override - _i17.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), - ) as _i17.Future<List<_i22.Transaction>>); + _i18.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), + ) as _i18.Future<List<_i23.Transaction>>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i18.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i17.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i18.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i9.FeeObject>); + ) as _i18.Future<_i9.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<int> get chainHeight => (super.noSuchMethod( + _i18.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -1044,26 +1057,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { ), ) as _i13.MainDB); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i21.DerivePathType addressType({required String? address}) => + _i24.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i21.DerivePathType.bip44, - ) as _i21.DerivePathType); + returnValue: _i24.DerivePathType.bip44, + ) as _i24.DerivePathType); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1080,47 +1093,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i18.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i18.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i18.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1136,26 +1149,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -1173,33 +1186,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1209,36 +1222,36 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<_i10.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i18.Future<_i10.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), returnValue: - _i17.Future<_i10.ElectrumXNode>.value(_FakeElectrumXNode_11( + _i18.Future<_i10.ElectrumXNode>.value(_FakeElectrumXNode_11( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i17.Future<_i10.ElectrumXNode>); + ) as _i18.Future<_i10.ElectrumXNode>); @override - _i17.Future<void> addDerivation({ + _i18.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i21.DerivePathType? derivePathType, + required _i24.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1252,13 +1265,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addDerivations({ + _i18.Future<void> addDerivations({ required int? chain, - required _i21.DerivePathType? derivePathType, + required _i24.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1271,50 +1284,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<List<Map<String, dynamic>>> fastFetch( + _i18.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i17.Future<List<Map<String, dynamic>>>.value( + returnValue: _i18.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i17.Future<List<Map<String, dynamic>>>); + ) as _i18.Future<List<Map<String, dynamic>>>); @override - _i17.Future<int> getTxCount({required String? address}) => + _i18.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i18.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> checkCurrentChangeAddressesForTransactions() => + _i18.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1338,7 +1351,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i22.UTXO>? utxos, + List<_i23.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1354,19 +1367,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { }, )); @override - _i17.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i22.UTXO>? utxosToUse) => + _i18.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i23.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<Map<String, dynamic>> buildTransaction({ - required List<_i22.UTXO>? utxosToUse, + _i18.Future<Map<String, dynamic>> buildTransaction({ + required List<_i23.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1383,10 +1396,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1398,11 +1411,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1414,8 +1427,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1434,25 +1447,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i18.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void initCache( String? walletId, - _i16.Coin? coin, + _i17.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1465,14 +1478,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i18.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1482,14 +1495,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i18.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1499,15 +1512,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i18.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i12.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1523,15 +1536,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { ), ) as _i12.Balance); @override - _i17.Future<void> updateCachedBalance(_i12.Balance? balance) => + _i18.Future<void> updateCachedBalance(_i12.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i12.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1547,15 +1560,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { ), ) as _i12.Balance); @override - _i17.Future<void> updateCachedBalanceSecondary(_i12.Balance? balance) => + _i18.Future<void> updateCachedBalanceSecondary(_i12.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void initWalletDB({_i13.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1565,12 +1578,55 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i18.Future< + _i14.Tuple4<_i23.Transaction, List<_i23.Output>, List<_i23.Input>, + _i23.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i23.Address>? myAddresses, + _i17.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i18.Future< + _i14.Tuple4<_i23.Transaction, List<_i23.Output>, List<_i23.Input>, + _i23.Address>>.value(_FakeTuple4_12<_i23.Transaction, + List<_i23.Output>, List<_i23.Input>, _i23.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i18.Future< + _i14.Tuple4<_i23.Transaction, List<_i23.Output>, List<_i23.Input>, + _i23.Address>>); } /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i23.LocaleService { +class MockLocaleService extends _i1.Mock implements _i25.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -1586,17 +1642,17 @@ class MockLocaleService extends _i1.Mock implements _i23.LocaleService { returnValue: false, ) as bool); @override - _i17.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i18.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1604,7 +1660,7 @@ class MockLocaleService extends _i1.Mock implements _i23.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1632,7 +1688,7 @@ class MockLocaleService extends _i1.Mock implements _i23.LocaleService { /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i18.Prefs { +class MockPrefs extends _i1.Mock implements _i19.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -1688,12 +1744,12 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValueForMissingStub: null, ); @override - _i24.SyncingType get syncType => (super.noSuchMethod( + _i26.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i24.SyncingType.currentWalletOnly, - ) as _i24.SyncingType); + returnValue: _i26.SyncingType.currentWalletOnly, + ) as _i26.SyncingType); @override - set syncType(_i24.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i26.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -1753,12 +1809,12 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValueForMissingStub: null, ); @override - _i25.ExchangeRateType get exchangeRateType => (super.noSuchMethod( + _i27.ExchangeRateType get exchangeRateType => (super.noSuchMethod( Invocation.getter(#exchangeRateType), - returnValue: _i25.ExchangeRateType.estimated, - ) as _i25.ExchangeRateType); + returnValue: _i27.ExchangeRateType.estimated, + ) as _i27.ExchangeRateType); @override - set exchangeRateType(_i25.ExchangeRateType? exchangeRateType) => + set exchangeRateType(_i27.ExchangeRateType? exchangeRateType) => super.noSuchMethod( Invocation.setter( #exchangeRateType, @@ -1840,12 +1896,12 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValueForMissingStub: null, ); @override - _i26.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i28.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i26.BackupFrequencyType.everyTenMinutes, - ) as _i26.BackupFrequencyType); + returnValue: _i28.BackupFrequencyType.everyTenMinutes, + ) as _i28.BackupFrequencyType); @override - set backupFrequencyType(_i26.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i28.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -1915,33 +1971,33 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValue: false, ) as bool); @override - _i17.Future<void> init() => (super.noSuchMethod( + _i18.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i18.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i18.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1949,7 +2005,7 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1992,23 +2048,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i14.CoinServiceAPI get wallet => (super.noSuchMethod( + _i15.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_12( + returnValue: _FakeCoinServiceAPI_13( this, Invocation.getter(#wallet), ), - ) as _i14.CoinServiceAPI); + ) as _i15.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2041,23 +2097,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i18.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i9.FeeObject>); + ) as _i18.Future<_i9.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i12.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2067,16 +2123,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i12.Balance); @override - _i17.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), - ) as _i17.Future<List<_i22.Transaction>>); + _i18.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), + ) as _i18.Future<List<_i23.Transaction>>); @override - _i17.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), - ) as _i17.Future<List<_i22.UTXO>>); + returnValue: _i18.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), + ) as _i18.Future<List<_i23.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2096,10 +2152,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -2111,19 +2167,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -2133,7 +2194,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2149,27 +2210,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2179,33 +2240,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2222,20 +2283,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i18.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2247,11 +2308,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2263,18 +2324,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2282,7 +2343,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2302,7 +2363,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i15.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -2313,10 +2374,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2349,23 +2410,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i17.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i18.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i9.FeeObject>); + ) as _i18.Future<_i9.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i12.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2375,16 +2436,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { ), ) as _i12.Balance); @override - _i17.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), - ) as _i17.Future<List<_i22.Transaction>>); + _i18.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), + ) as _i18.Future<List<_i23.Transaction>>); @override - _i17.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), - ) as _i17.Future<List<_i22.UTXO>>); + returnValue: _i18.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), + ) as _i18.Future<List<_i23.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2404,10 +2465,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2424,7 +2485,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: 0, ) as int); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2440,36 +2501,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2479,15 +2540,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2504,38 +2565,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2547,11 +2608,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2563,24 +2624,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); } diff --git a/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart index bb5c5c408..54ade45c2 100644 --- a/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart @@ -363,6 +363,11 @@ class MockManager extends _i1.Mock implements _i11.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart index f0c334e7e..84fc1bf4e 100644 --- a/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart @@ -324,6 +324,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart index f0c11b04a..7d23a2dd7 100644 --- a/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart @@ -322,6 +322,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/lockscreen_view_screen_test.mocks.dart b/test/screen_tests/lockscreen_view_screen_test.mocks.dart index 6328b6881..92518048b 100644 --- a/test/screen_tests/lockscreen_view_screen_test.mocks.dart +++ b/test/screen_tests/lockscreen_view_screen_test.mocks.dart @@ -631,6 +631,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart index c0c6f6902..01f47579b 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart @@ -418,6 +418,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart index aef163b0e..106485fdb 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart @@ -418,6 +418,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart index 7f31b64c4..419b72e3f 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart @@ -418,6 +418,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart b/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart index 56e72d944..50cd7afd8 100644 --- a/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart b/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart index a7467d9be..ba5f52688 100644 --- a/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart @@ -416,6 +416,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart b/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart index 9267a9fba..7a1afa588 100644 --- a/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart @@ -631,6 +631,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart b/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart index 13aa6edb8..31fb8546c 100644 --- a/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart @@ -472,6 +472,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart b/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart index b8c7f3cbd..742498415 100644 --- a/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart index 68f2eeb10..b4c96f70c 100644 --- a/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart index 8b60863ab..9fe30a1cb 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart @@ -408,6 +408,11 @@ class MockManager extends _i1.Mock implements _i11.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart index 09d59deb2..f0b37d032 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart @@ -408,6 +408,11 @@ class MockManager extends _i1.Mock implements _i11.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart index a958461b8..3711513b4 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart index 284065eba..fc733ad66 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart index 24da7d388..b36f289d8 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart @@ -416,6 +416,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart index 0bf926563..dc382ee73 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart @@ -673,6 +673,11 @@ class MockManager extends _i1.Mock implements _i15.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart index 487f2f2bf..e469b8be4 100644 --- a/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart @@ -416,6 +416,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart b/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart index 31bda1f65..bd3520e44 100644 --- a/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart +++ b/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart @@ -195,6 +195,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart index 161b63e1d..cbfc6644f 100644 --- a/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart @@ -194,6 +194,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart index 7172f3e29..a4936c793 100644 --- a/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart index ba206a8c6..3126e4580 100644 --- a/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart @@ -235,6 +235,11 @@ class MockManager extends _i1.Mock implements _i8.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart index ae6a2d1f9..135802891 100644 --- a/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart @@ -195,6 +195,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/widget_tests/managed_favorite_test.mocks.dart b/test/widget_tests/managed_favorite_test.mocks.dart index a5ee69930..a51988ce0 100644 --- a/test/widget_tests/managed_favorite_test.mocks.dart +++ b/test/widget_tests/managed_favorite_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i17; -import 'dart:ui' as _i19; +import 'dart:async' as _i18; +import 'dart:ui' as _i20; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,22 +13,24 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; -import 'package:stackwallet/models/node_model.dart' as _i23; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i22; +import 'package:stackwallet/models/node_model.dart' as _i25; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i20; -import 'package:stackwallet/services/coins/coin_service.dart' as _i14; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i21; +import 'package:stackwallet/services/coins/coin_service.dart' as _i15; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i22; +import 'package:stackwallet/services/locale_service.dart' as _i24; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i15; +import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i23; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i13; -import 'package:stackwallet/utilities/prefs.dart' as _i18; + as _i14; +import 'package:stackwallet/utilities/prefs.dart' as _i19; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -155,9 +157,9 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } -class _FakeSecureStorageInterface_11 extends _i1.SmartFake - implements _i13.SecureStorageInterface { - _FakeSecureStorageInterface_11( +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( Object parent, Invocation parentInvocation, ) : super( @@ -166,9 +168,20 @@ class _FakeSecureStorageInterface_11 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_12 extends _i1.SmartFake - implements _i14.CoinServiceAPI { - _FakeCoinServiceAPI_12( +class _FakeSecureStorageInterface_12 extends _i1.SmartFake + implements _i14.SecureStorageInterface { + _FakeSecureStorageInterface_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_13 extends _i1.SmartFake + implements _i15.CoinServiceAPI { + _FakeCoinServiceAPI_13( Object parent, Invocation parentInvocation, ) : super( @@ -180,7 +193,7 @@ class _FakeCoinServiceAPI_12 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i15.Wallets { +class MockWallets extends _i1.Mock implements _i16.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -247,7 +260,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i16.Coin? coin}) => + List<String> getWalletIdsFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -257,18 +270,18 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Coin, + returnValue: <_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i16.Coin? coin) => + _i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -332,17 +345,17 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( + _i18.Future<void> load(_i19.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> loadAfterStackRestore( - _i18.Prefs? prefs, + _i18.Future<void> loadAfterStackRestore( + _i19.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -353,11 +366,11 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { managers, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -365,7 +378,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -391,19 +404,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i18.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i18.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i17.Future<Map<String, _i2.WalletInfo>>); + ) as _i18.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<bool> renameWallet({ + _i18.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -418,13 +431,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> addExistingStackWallet({ + _i18.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -438,13 +451,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<String?> addNewWallet({ + _i18.Future<String?> addNewWallet({ required String? name, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -457,46 +470,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i18.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i18.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> moveFavorite({ + _i18.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -509,48 +522,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i18.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i18.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<bool> isMnemonicVerified({required String? walletId}) => + _i18.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> setMnemonicVerified({required String? walletId}) => + _i18.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> deleteWallet( + _i18.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -562,20 +575,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i18.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -583,7 +596,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -611,13 +624,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i17.Timer? _timer) => super.noSuchMethod( + set timer(_i18.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -694,59 +707,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i18.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<int> get chainHeight => (super.noSuchMethod( + _i18.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -835,26 +848,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i12.MainDB); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i20.DerivePathType addressType({required String? address}) => + _i23.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i20.DerivePathType.bip44, - ) as _i20.DerivePathType); + returnValue: _i23.DerivePathType.bip44, + ) as _i23.DerivePathType); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -871,47 +884,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i18.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i18.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i18.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -927,26 +940,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -964,33 +977,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1000,35 +1013,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i18.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i17.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i18.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i17.Future<_i9.ElectrumXNode>); + ) as _i18.Future<_i9.ElectrumXNode>); @override - _i17.Future<void> addDerivation({ + _i18.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1042,13 +1055,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addDerivations({ + _i18.Future<void> addDerivations({ required int? chain, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1061,50 +1074,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<List<Map<String, dynamic>>> fastFetch( + _i18.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i17.Future<List<Map<String, dynamic>>>.value( + returnValue: _i18.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i17.Future<List<Map<String, dynamic>>>); + ) as _i18.Future<List<Map<String, dynamic>>>); @override - _i17.Future<int> getTxCount({required String? address}) => + _i18.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i18.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> checkCurrentChangeAddressesForTransactions() => + _i18.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1128,7 +1141,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i21.UTXO>? utxos, + List<_i22.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1144,19 +1157,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, )); @override - _i17.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i21.UTXO>? utxosToUse) => + _i18.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i22.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<Map<String, dynamic>> buildTransaction({ - required List<_i21.UTXO>? utxosToUse, + _i18.Future<Map<String, dynamic>> buildTransaction({ + required List<_i22.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1173,10 +1186,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1188,11 +1201,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1204,8 +1217,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1224,25 +1237,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i18.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void initCache( String? walletId, - _i16.Coin? coin, + _i17.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1255,14 +1268,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i18.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1272,14 +1285,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i18.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1289,15 +1302,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i18.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1313,15 +1326,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1337,15 +1350,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1355,12 +1368,55 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i22.Address>? myAddresses, + _i17.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>.value(_FakeTuple4_11<_i22.Transaction, + List<_i22.Output>, List<_i22.Input>, _i22.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>); } /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i22.LocaleService { +class MockLocaleService extends _i1.Mock implements _i24.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -1376,17 +1432,17 @@ class MockLocaleService extends _i1.Mock implements _i22.LocaleService { returnValue: false, ) as bool); @override - _i17.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i18.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1394,7 +1450,7 @@ class MockLocaleService extends _i1.Mock implements _i22.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1424,41 +1480,41 @@ class MockLocaleService extends _i1.Mock implements _i22.LocaleService { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i13.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i14.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_11( + returnValue: _FakeSecureStorageInterface_12( this, Invocation.getter(#secureStorageInterface), ), - ) as _i13.SecureStorageInterface); + ) as _i14.SecureStorageInterface); @override - List<_i23.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i25.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i23.NodeModel>[], - ) as List<_i23.NodeModel>); + returnValue: <_i25.NodeModel>[], + ) as List<_i25.NodeModel>); @override - List<_i23.NodeModel> get nodes => (super.noSuchMethod( + List<_i25.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i23.NodeModel>[], - ) as List<_i23.NodeModel>); + returnValue: <_i25.NodeModel>[], + ) as List<_i25.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateDefaults() => (super.noSuchMethod( + _i18.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setPrimaryNodeFor({ - required _i16.Coin? coin, - required _i23.NodeModel? node, + _i18.Future<void> setPrimaryNodeFor({ + required _i17.Coin? coin, + required _i25.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -1471,44 +1527,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i23.NodeModel? getPrimaryNodeFor({required _i16.Coin? coin}) => + _i25.NodeModel? getPrimaryNodeFor({required _i17.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i23.NodeModel?); + )) as _i25.NodeModel?); @override - List<_i23.NodeModel> getNodesFor(_i16.Coin? coin) => (super.noSuchMethod( + List<_i25.NodeModel> getNodesFor(_i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i23.NodeModel>[], - ) as List<_i23.NodeModel>); + returnValue: <_i25.NodeModel>[], + ) as List<_i25.NodeModel>); @override - _i23.NodeModel? getNodeById({required String? id}) => + _i25.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i23.NodeModel?); + )) as _i25.NodeModel?); @override - List<_i23.NodeModel> failoverNodesFor({required _i16.Coin? coin}) => + List<_i25.NodeModel> failoverNodesFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i23.NodeModel>[], - ) as List<_i23.NodeModel>); + returnValue: <_i25.NodeModel>[], + ) as List<_i25.NodeModel>); @override - _i17.Future<void> add( - _i23.NodeModel? node, + _i18.Future<void> add( + _i25.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -1521,11 +1577,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> delete( + _i18.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -1537,11 +1593,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setEnabledState( + _i18.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -1555,12 +1611,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> edit( - _i23.NodeModel? editedNode, + _i18.Future<void> edit( + _i25.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -1573,20 +1629,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i18.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1594,7 +1650,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1637,23 +1693,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i14.CoinServiceAPI get wallet => (super.noSuchMethod( + _i15.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_12( + returnValue: _FakeCoinServiceAPI_13( this, Invocation.getter(#wallet), ), - ) as _i14.CoinServiceAPI); + ) as _i15.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1686,23 +1742,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1712,16 +1768,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1741,10 +1797,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -1756,19 +1812,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1778,7 +1839,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1794,27 +1855,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1824,33 +1885,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1867,20 +1928,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i18.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1892,11 +1953,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1908,18 +1969,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1927,7 +1988,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1947,7 +2008,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i15.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1958,10 +2019,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1994,23 +2055,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2020,16 +2081,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2049,10 +2110,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2069,7 +2130,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: 0, ) as int); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2085,36 +2146,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2124,15 +2185,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2149,38 +2210,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2192,11 +2253,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2208,24 +2269,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); } diff --git a/test/widget_tests/table_view/table_view_row_test.mocks.dart b/test/widget_tests/table_view/table_view_row_test.mocks.dart index d31019d37..aeefa1a27 100644 --- a/test/widget_tests/table_view/table_view_row_test.mocks.dart +++ b/test/widget_tests/table_view/table_view_row_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i16; -import 'dart:ui' as _i18; +import 'dart:async' as _i17; +import 'dart:ui' as _i19; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,18 +13,20 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i20; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i19; -import 'package:stackwallet/services/coins/coin_service.dart' as _i13; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i20; +import 'package:stackwallet/services/coins/coin_service.dart' as _i14; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i14; +import 'package:stackwallet/services/wallets.dart' as _i15; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i15; -import 'package:stackwallet/utilities/prefs.dart' as _i17; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i22; +import 'package:stackwallet/utilities/prefs.dart' as _i18; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -151,9 +153,20 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } -class _FakeCoinServiceAPI_11 extends _i1.SmartFake - implements _i13.CoinServiceAPI { - _FakeCoinServiceAPI_11( +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_12 extends _i1.SmartFake + implements _i14.CoinServiceAPI { + _FakeCoinServiceAPI_12( Object parent, Invocation parentInvocation, ) : super( @@ -165,7 +178,7 @@ class _FakeCoinServiceAPI_11 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i14.Wallets { +class MockWallets extends _i1.Mock implements _i15.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -232,7 +245,7 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i15.Coin? coin}) => + List<String> getWalletIdsFor({required _i16.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -242,18 +255,18 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i15.Coin, + returnValue: <_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i15.Coin? coin) => + _i16.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -317,17 +330,17 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { returnValueForMissingStub: null, ); @override - _i16.Future<void> load(_i17.Prefs? prefs) => (super.noSuchMethod( + _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> loadAfterStackRestore( - _i17.Prefs? prefs, + _i17.Future<void> loadAfterStackRestore( + _i18.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -338,11 +351,11 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { managers, ], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -350,7 +363,7 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -376,19 +389,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i16.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i16.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i16.Future<Map<String, _i2.WalletInfo>>); + ) as _i17.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i16.Future<bool> renameWallet({ + _i17.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -403,13 +416,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> addExistingStackWallet({ + _i17.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i15.Coin? coin, + required _i16.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -423,13 +436,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<String?> addNewWallet({ + _i17.Future<String?> addNewWallet({ required String? name, - required _i15.Coin? coin, + required _i16.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -442,46 +455,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i16.Future<String?>.value(), - ) as _i16.Future<String?>); + returnValue: _i17.Future<String?>.value(), + ) as _i17.Future<String?>); @override - _i16.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i16.Future<List<String>>.value(<String>[]), - ) as _i16.Future<List<String>>); + returnValue: _i17.Future<List<String>>.value(<String>[]), + ) as _i17.Future<List<String>>); @override - _i16.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> moveFavorite({ + _i17.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -494,48 +507,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i16.Future<String?>.value(), - ) as _i16.Future<String?>); + returnValue: _i17.Future<String?>.value(), + ) as _i17.Future<String?>); @override - _i16.Future<bool> isMnemonicVerified({required String? walletId}) => + _i17.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> setMnemonicVerified({required String? walletId}) => + _i17.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<int> deleteWallet( + _i17.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -547,20 +560,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -568,7 +581,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -596,13 +609,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i16.Timer? _timer) => super.noSuchMethod( + set timer(_i17.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -679,59 +692,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: false, ) as bool); @override - _i15.Coin get coin => (super.noSuchMethod( + _i16.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i15.Coin.bitcoin, - ) as _i15.Coin); + returnValue: _i16.Coin.bitcoin, + ) as _i16.Coin); @override - _i16.Future<List<_i20.UTXO>> get utxos => (super.noSuchMethod( + _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i16.Future<List<_i20.UTXO>>.value(<_i20.UTXO>[]), - ) as _i16.Future<List<_i20.UTXO>>); + returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), + ) as _i17.Future<List<_i21.UTXO>>); @override - _i16.Future<List<_i20.Transaction>> get transactions => (super.noSuchMethod( + _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i16.Future<List<_i20.Transaction>>.value(<_i20.Transaction>[]), - ) as _i16.Future<List<_i20.Transaction>>); + _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), + ) as _i17.Future<List<_i21.Transaction>>); @override - _i16.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override - _i16.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i16.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i16.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i16.Future<_i8.FeeObject>); + ) as _i17.Future<_i8.FeeObject>); @override - _i16.Future<int> get maxFee => (super.noSuchMethod( + _i17.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i16.Future<List<String>>.value(<String>[]), - ) as _i16.Future<List<String>>); + returnValue: _i17.Future<List<String>>.value(<String>[]), + ) as _i17.Future<List<String>>); @override - _i16.Future<int> get chainHeight => (super.noSuchMethod( + _i17.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -820,26 +833,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { ), ) as _i12.MainDB); @override - _i16.Future<void> exit() => (super.noSuchMethod( + _i17.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i19.DerivePathType addressType({required String? address}) => + _i22.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i19.DerivePathType.bip44, - ) as _i19.DerivePathType); + returnValue: _i22.DerivePathType.bip44, + ) as _i22.DerivePathType); @override - _i16.Future<void> recoverFromMnemonic({ + _i17.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -856,47 +869,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { #height: height, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> refresh() => (super.noSuchMethod( + _i17.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<Map<String, dynamic>> prepareSend({ + _i17.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -912,26 +925,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { }, ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override - _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -949,33 +962,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i16.Future<void> initializeNew() => (super.noSuchMethod( + _i17.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> initializeExisting() => (super.noSuchMethod( + _i17.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -985,35 +998,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i17.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i16.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i17.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i16.Future<_i9.ElectrumXNode>); + ) as _i17.Future<_i9.ElectrumXNode>); @override - _i16.Future<void> addDerivation({ + _i17.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i19.DerivePathType? derivePathType, + required _i22.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1027,13 +1040,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> addDerivations({ + _i17.Future<void> addDerivations({ required int? chain, - required _i19.DerivePathType? derivePathType, + required _i22.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1046,50 +1059,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<List<Map<String, dynamic>>> fastFetch( + _i17.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i16.Future<List<Map<String, dynamic>>>.value( + returnValue: _i17.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i16.Future<List<Map<String, dynamic>>>); + ) as _i17.Future<List<Map<String, dynamic>>>); @override - _i16.Future<int> getTxCount({required String? address}) => + _i17.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> checkCurrentChangeAddressesForTransactions() => + _i17.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1113,7 +1126,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i20.UTXO>? utxos, + List<_i21.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1129,19 +1142,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { }, )); @override - _i16.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i20.UTXO>? utxosToUse) => + _i17.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i21.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<Map<String, dynamic>> buildTransaction({ - required List<_i20.UTXO>? utxosToUse, + _i17.Future<Map<String, dynamic>> buildTransaction({ + required List<_i21.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1158,10 +1171,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { }, ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<void> fullRescan( + _i17.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1173,11 +1186,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<int> estimateFeeFor( + _i17.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1189,8 +1202,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { feeRate, ], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1209,25 +1222,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: 0, ) as int); @override - _i16.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override void initCache( String? walletId, - _i15.Coin? coin, + _i16.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1240,14 +1253,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i16.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1257,14 +1270,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: 0, ) as int); @override - _i16.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1274,15 +1287,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1298,15 +1311,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { ), ) as _i11.Balance); @override - _i16.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i17.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1322,15 +1335,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { ), ) as _i11.Balance); @override - _i16.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i17.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1340,6 +1353,49 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i17.Future< + _i13.Tuple4<_i21.Transaction, List<_i21.Output>, List<_i21.Input>, + _i21.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i21.Address>? myAddresses, + _i16.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i17.Future< + _i13.Tuple4<_i21.Transaction, List<_i21.Output>, List<_i21.Input>, + _i21.Address>>.value(_FakeTuple4_11<_i21.Transaction, + List<_i21.Output>, List<_i21.Input>, _i21.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i17.Future< + _i13.Tuple4<_i21.Transaction, List<_i21.Output>, List<_i21.Input>, + _i21.Address>>); } /// A class which mocks [Manager]. @@ -1360,23 +1416,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i13.CoinServiceAPI get wallet => (super.noSuchMethod( + _i14.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_11( + returnValue: _FakeCoinServiceAPI_12( this, Invocation.getter(#wallet), ), - ) as _i13.CoinServiceAPI); + ) as _i14.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i15.Coin get coin => (super.noSuchMethod( + _i16.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i15.Coin.bitcoin, - ) as _i15.Coin); + returnValue: _i16.Coin.bitcoin, + ) as _i16.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1409,23 +1465,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i16.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i16.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i16.Future<_i8.FeeObject>); + ) as _i17.Future<_i8.FeeObject>); @override - _i16.Future<int> get maxFee => (super.noSuchMethod( + _i17.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1435,16 +1491,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i16.Future<List<_i20.Transaction>> get transactions => (super.noSuchMethod( + _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i16.Future<List<_i20.Transaction>>.value(<_i20.Transaction>[]), - ) as _i16.Future<List<_i20.Transaction>>); + _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), + ) as _i17.Future<List<_i21.Transaction>>); @override - _i16.Future<List<_i20.UTXO>> get utxos => (super.noSuchMethod( + _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i16.Future<List<_i20.UTXO>>.value(<_i20.UTXO>[]), - ) as _i16.Future<List<_i20.UTXO>>); + returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), + ) as _i17.Future<List<_i21.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1464,10 +1520,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i16.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i16.Future<List<String>>.value(<String>[]), - ) as _i16.Future<List<String>>); + returnValue: _i17.Future<List<String>>.value(<String>[]), + ) as _i17.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -1479,19 +1535,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i16.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1501,7 +1562,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i16.Future<Map<String, dynamic>> prepareSend({ + _i17.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1517,27 +1578,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override - _i16.Future<void> refresh() => (super.noSuchMethod( + _i17.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1547,33 +1608,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> initializeNew() => (super.noSuchMethod( + _i17.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> initializeExisting() => (super.noSuchMethod( + _i17.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> recoverFromMnemonic({ + _i17.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1590,20 +1651,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> fullRescan( + _i17.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1615,11 +1676,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<int> estimateFeeFor( + _i17.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1631,18 +1692,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1650,7 +1711,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1670,7 +1731,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1681,10 +1742,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i15.Coin get coin => (super.noSuchMethod( + _i16.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i15.Coin.bitcoin, - ) as _i15.Coin); + returnValue: _i16.Coin.bitcoin, + ) as _i16.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1717,23 +1778,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i16.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i16.Future<_i8.FeeObject>); + ) as _i17.Future<_i8.FeeObject>); @override - _i16.Future<int> get maxFee => (super.noSuchMethod( + _i17.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1743,16 +1804,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { ), ) as _i11.Balance); @override - _i16.Future<List<_i20.Transaction>> get transactions => (super.noSuchMethod( + _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i16.Future<List<_i20.Transaction>>.value(<_i20.Transaction>[]), - ) as _i16.Future<List<_i20.Transaction>>); + _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), + ) as _i17.Future<List<_i21.Transaction>>); @override - _i16.Future<List<_i20.UTXO>> get utxos => (super.noSuchMethod( + _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i16.Future<List<_i20.UTXO>>.value(<_i20.UTXO>[]), - ) as _i16.Future<List<_i20.UTXO>>); + returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), + ) as _i17.Future<List<_i21.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1772,10 +1833,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValue: '', ) as String); @override - _i16.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i16.Future<List<String>>.value(<String>[]), - ) as _i16.Future<List<String>>); + returnValue: _i17.Future<List<String>>.value(<String>[]), + ) as _i17.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -1792,7 +1853,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValue: 0, ) as int); @override - _i16.Future<Map<String, dynamic>> prepareSend({ + _i17.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1808,36 +1869,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { }, ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override - _i16.Future<void> refresh() => (super.noSuchMethod( + _i17.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1847,15 +1908,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValue: false, ) as bool); @override - _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> recoverFromMnemonic({ + _i17.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1872,38 +1933,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { #height: height, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> initializeNew() => (super.noSuchMethod( + _i17.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> initializeExisting() => (super.noSuchMethod( + _i17.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> exit() => (super.noSuchMethod( + _i17.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> fullRescan( + _i17.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1915,11 +1976,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<int> estimateFeeFor( + _i17.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1931,24 +1992,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { feeRate, ], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); } diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index c3b2cce4b..1ef218b2d 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -538,6 +538,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/widget_tests/wallet_card_test.mocks.dart b/test/widget_tests/wallet_card_test.mocks.dart index 5a5d048b3..2bffe7a06 100644 --- a/test/widget_tests/wallet_card_test.mocks.dart +++ b/test/widget_tests/wallet_card_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i15; -import 'dart:ui' as _i17; +import 'dart:async' as _i16; +import 'dart:ui' as _i18; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,18 +13,20 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i19; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i20; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i18; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i19; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i20; +import 'package:stackwallet/services/locale_service.dart' as _i22; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i13; +import 'package:stackwallet/services/wallets.dart' as _i14; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i14; -import 'package:stackwallet/utilities/prefs.dart' as _i16; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i15; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i21; +import 'package:stackwallet/utilities/prefs.dart' as _i17; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -151,10 +153,21 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i13.Wallets { +class MockWallets extends _i1.Mock implements _i14.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -221,7 +234,7 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i14.Coin? coin}) => + List<String> getWalletIdsFor({required _i15.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -231,18 +244,18 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i14.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i14.Coin, + returnValue: <_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i14.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i14.Coin? coin) => + _i15.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -306,17 +319,17 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { returnValueForMissingStub: null, ); @override - _i15.Future<void> load(_i16.Prefs? prefs) => (super.noSuchMethod( + _i16.Future<void> load(_i17.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> loadAfterStackRestore( - _i16.Prefs? prefs, + _i16.Future<void> loadAfterStackRestore( + _i17.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -327,11 +340,11 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { managers, ], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -339,7 +352,7 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -359,13 +372,13 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i15.Timer? _timer) => super.noSuchMethod( + set timer(_i16.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -442,59 +455,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: false, ) as bool); @override - _i14.Coin get coin => (super.noSuchMethod( + _i15.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i14.Coin.bitcoin, - ) as _i14.Coin); + returnValue: _i15.Coin.bitcoin, + ) as _i15.Coin); @override - _i15.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( + _i16.Future<List<_i20.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i15.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), - ) as _i15.Future<List<_i19.UTXO>>); + returnValue: _i16.Future<List<_i20.UTXO>>.value(<_i20.UTXO>[]), + ) as _i16.Future<List<_i20.UTXO>>); @override - _i15.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( + _i16.Future<List<_i20.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i15.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), - ) as _i15.Future<List<_i19.Transaction>>); + _i16.Future<List<_i20.Transaction>>.value(<_i20.Transaction>[]), + ) as _i16.Future<List<_i20.Transaction>>); @override - _i15.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i16.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i15.Future<String>.value(''), - ) as _i15.Future<String>); + returnValue: _i16.Future<String>.value(''), + ) as _i16.Future<String>); @override - _i15.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i16.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i15.Future<String>.value(''), - ) as _i15.Future<String>); + returnValue: _i16.Future<String>.value(''), + ) as _i16.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i15.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i16.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i15.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i16.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i15.Future<_i8.FeeObject>); + ) as _i16.Future<_i8.FeeObject>); @override - _i15.Future<int> get maxFee => (super.noSuchMethod( + _i16.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override - _i15.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i16.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i15.Future<List<String>>.value(<String>[]), - ) as _i15.Future<List<String>>); + returnValue: _i16.Future<List<String>>.value(<String>[]), + ) as _i16.Future<List<String>>); @override - _i15.Future<int> get chainHeight => (super.noSuchMethod( + _i16.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -583,26 +596,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { ), ) as _i12.MainDB); @override - _i15.Future<void> exit() => (super.noSuchMethod( + _i16.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i18.DerivePathType addressType({required String? address}) => + _i21.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i18.DerivePathType.bip44, - ) as _i18.DerivePathType); + returnValue: _i21.DerivePathType.bip44, + ) as _i21.DerivePathType); @override - _i15.Future<void> recoverFromMnemonic({ + _i16.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -619,47 +632,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { #height: height, }, ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i16.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i16.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i15.Future<bool>.value(false), - ) as _i15.Future<bool>); + returnValue: _i16.Future<bool>.value(false), + ) as _i16.Future<bool>); @override - _i15.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i16.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> refresh() => (super.noSuchMethod( + _i16.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<Map<String, dynamic>> prepareSend({ + _i16.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -675,26 +688,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { }, ), returnValue: - _i15.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i15.Future<Map<String, dynamic>>); + _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i16.Future<Map<String, dynamic>>); @override - _i15.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i16.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i15.Future<String>.value(''), - ) as _i15.Future<String>); + returnValue: _i16.Future<String>.value(''), + ) as _i16.Future<String>); @override - _i15.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i15.Future<bool>.value(false), - ) as _i15.Future<bool>); + returnValue: _i16.Future<bool>.value(false), + ) as _i16.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -712,33 +725,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i15.Future<void> initializeNew() => (super.noSuchMethod( + _i16.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> initializeExisting() => (super.noSuchMethod( + _i16.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i16.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -748,35 +761,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: false, ) as bool); @override - _i15.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i16.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i16.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i15.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i16.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i15.Future<_i9.ElectrumXNode>); + ) as _i16.Future<_i9.ElectrumXNode>); @override - _i15.Future<void> addDerivation({ + _i16.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i18.DerivePathType? derivePathType, + required _i21.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -790,13 +803,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> addDerivations({ + _i16.Future<void> addDerivations({ required int? chain, - required _i18.DerivePathType? derivePathType, + required _i21.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -809,50 +822,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<List<Map<String, dynamic>>> fastFetch( + _i16.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i15.Future<List<Map<String, dynamic>>>.value( + returnValue: _i16.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i15.Future<List<Map<String, dynamic>>>); + ) as _i16.Future<List<Map<String, dynamic>>>); @override - _i15.Future<int> getTxCount({required String? address}) => + _i16.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override - _i15.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i16.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> checkCurrentChangeAddressesForTransactions() => + _i16.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -876,7 +889,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i19.UTXO>? utxos, + List<_i20.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -892,19 +905,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { }, )); @override - _i15.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i19.UTXO>? utxosToUse) => + _i16.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i20.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i15.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i15.Future<Map<String, dynamic>>); + _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i16.Future<Map<String, dynamic>>); @override - _i15.Future<Map<String, dynamic>> buildTransaction({ - required List<_i19.UTXO>? utxosToUse, + _i16.Future<Map<String, dynamic>> buildTransaction({ + required List<_i20.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -921,10 +934,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { }, ), returnValue: - _i15.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i15.Future<Map<String, dynamic>>); + _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i16.Future<Map<String, dynamic>>); @override - _i15.Future<void> fullRescan( + _i16.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -936,11 +949,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<int> estimateFeeFor( + _i16.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -952,8 +965,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { feeRate, ], ), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -972,25 +985,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: 0, ) as int); @override - _i15.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i16.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override - _i15.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i16.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i15.Future<bool>.value(false), - ) as _i15.Future<bool>); + returnValue: _i16.Future<bool>.value(false), + ) as _i16.Future<bool>); @override void initCache( String? walletId, - _i14.Coin? coin, + _i15.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1003,14 +1016,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i15.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i16.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1020,14 +1033,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: 0, ) as int); @override - _i15.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i16.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1037,15 +1050,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: false, ) as bool); @override - _i15.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i16.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1061,15 +1074,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { ), ) as _i11.Balance); @override - _i15.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i16.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1085,15 +1098,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { ), ) as _i11.Balance); @override - _i15.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i16.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1103,12 +1116,55 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i16.Future< + _i13.Tuple4<_i20.Transaction, List<_i20.Output>, List<_i20.Input>, + _i20.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i20.Address>? myAddresses, + _i15.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i16.Future< + _i13.Tuple4<_i20.Transaction, List<_i20.Output>, List<_i20.Input>, + _i20.Address>>.value(_FakeTuple4_11<_i20.Transaction, + List<_i20.Output>, List<_i20.Input>, _i20.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i16.Future< + _i13.Tuple4<_i20.Transaction, List<_i20.Output>, List<_i20.Input>, + _i20.Address>>); } /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i20.LocaleService { +class MockLocaleService extends _i1.Mock implements _i22.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -1124,17 +1180,17 @@ class MockLocaleService extends _i1.Mock implements _i20.LocaleService { returnValue: false, ) as bool); @override - _i15.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i16.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1142,7 +1198,7 @@ class MockLocaleService extends _i1.Mock implements _i20.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], diff --git a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart index 41f874146..5f2b9b7f5 100644 --- a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart +++ b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i17; -import 'dart:ui' as _i19; +import 'dart:async' as _i18; +import 'dart:ui' as _i20; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,21 +13,23 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; -import 'package:stackwallet/models/node_model.dart' as _i22; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i22; +import 'package:stackwallet/models/node_model.dart' as _i24; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i20; -import 'package:stackwallet/services/coins/coin_service.dart' as _i14; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i21; +import 'package:stackwallet/services/coins/coin_service.dart' as _i15; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i15; +import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i23; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i13; -import 'package:stackwallet/utilities/prefs.dart' as _i18; + as _i14; +import 'package:stackwallet/utilities/prefs.dart' as _i19; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -154,9 +156,9 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } -class _FakeSecureStorageInterface_11 extends _i1.SmartFake - implements _i13.SecureStorageInterface { - _FakeSecureStorageInterface_11( +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( Object parent, Invocation parentInvocation, ) : super( @@ -165,9 +167,20 @@ class _FakeSecureStorageInterface_11 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_12 extends _i1.SmartFake - implements _i14.CoinServiceAPI { - _FakeCoinServiceAPI_12( +class _FakeSecureStorageInterface_12 extends _i1.SmartFake + implements _i14.SecureStorageInterface { + _FakeSecureStorageInterface_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_13 extends _i1.SmartFake + implements _i15.CoinServiceAPI { + _FakeCoinServiceAPI_13( Object parent, Invocation parentInvocation, ) : super( @@ -179,7 +192,7 @@ class _FakeCoinServiceAPI_12 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i15.Wallets { +class MockWallets extends _i1.Mock implements _i16.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -246,7 +259,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i16.Coin? coin}) => + List<String> getWalletIdsFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -256,18 +269,18 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Coin, + returnValue: <_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i16.Coin? coin) => + _i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -331,17 +344,17 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( + _i18.Future<void> load(_i19.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> loadAfterStackRestore( - _i18.Prefs? prefs, + _i18.Future<void> loadAfterStackRestore( + _i19.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -352,11 +365,11 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { managers, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -364,7 +377,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -390,19 +403,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i18.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i18.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i17.Future<Map<String, _i2.WalletInfo>>); + ) as _i18.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<bool> renameWallet({ + _i18.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -417,13 +430,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> addExistingStackWallet({ + _i18.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -437,13 +450,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<String?> addNewWallet({ + _i18.Future<String?> addNewWallet({ required String? name, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -456,46 +469,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i18.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i18.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> moveFavorite({ + _i18.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -508,48 +521,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i18.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i18.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<bool> isMnemonicVerified({required String? walletId}) => + _i18.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> setMnemonicVerified({required String? walletId}) => + _i18.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> deleteWallet( + _i18.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -561,20 +574,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i18.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -582,7 +595,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -610,13 +623,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i17.Timer? _timer) => super.noSuchMethod( + set timer(_i18.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -693,59 +706,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i18.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<int> get chainHeight => (super.noSuchMethod( + _i18.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -834,26 +847,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i12.MainDB); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i20.DerivePathType addressType({required String? address}) => + _i23.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i20.DerivePathType.bip44, - ) as _i20.DerivePathType); + returnValue: _i23.DerivePathType.bip44, + ) as _i23.DerivePathType); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -870,47 +883,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i18.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i18.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i18.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -926,26 +939,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -963,33 +976,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -999,35 +1012,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i18.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i17.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i18.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i17.Future<_i9.ElectrumXNode>); + ) as _i18.Future<_i9.ElectrumXNode>); @override - _i17.Future<void> addDerivation({ + _i18.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1041,13 +1054,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addDerivations({ + _i18.Future<void> addDerivations({ required int? chain, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1060,50 +1073,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<List<Map<String, dynamic>>> fastFetch( + _i18.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i17.Future<List<Map<String, dynamic>>>.value( + returnValue: _i18.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i17.Future<List<Map<String, dynamic>>>); + ) as _i18.Future<List<Map<String, dynamic>>>); @override - _i17.Future<int> getTxCount({required String? address}) => + _i18.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i18.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> checkCurrentChangeAddressesForTransactions() => + _i18.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1127,7 +1140,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i21.UTXO>? utxos, + List<_i22.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1143,19 +1156,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, )); @override - _i17.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i21.UTXO>? utxosToUse) => + _i18.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i22.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<Map<String, dynamic>> buildTransaction({ - required List<_i21.UTXO>? utxosToUse, + _i18.Future<Map<String, dynamic>> buildTransaction({ + required List<_i22.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1172,10 +1185,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1187,11 +1200,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1203,8 +1216,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1223,25 +1236,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i18.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void initCache( String? walletId, - _i16.Coin? coin, + _i17.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1254,14 +1267,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i18.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1271,14 +1284,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i18.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1288,15 +1301,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i18.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1312,15 +1325,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1336,15 +1349,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1354,6 +1367,49 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i22.Address>? myAddresses, + _i17.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>.value(_FakeTuple4_11<_i22.Transaction, + List<_i22.Output>, List<_i22.Input>, _i22.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>); } /// A class which mocks [NodeService]. @@ -1361,41 +1417,41 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i13.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i14.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_11( + returnValue: _FakeSecureStorageInterface_12( this, Invocation.getter(#secureStorageInterface), ), - ) as _i13.SecureStorageInterface); + ) as _i14.SecureStorageInterface); @override - List<_i22.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i24.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - List<_i22.NodeModel> get nodes => (super.noSuchMethod( + List<_i24.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateDefaults() => (super.noSuchMethod( + _i18.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setPrimaryNodeFor({ - required _i16.Coin? coin, - required _i22.NodeModel? node, + _i18.Future<void> setPrimaryNodeFor({ + required _i17.Coin? coin, + required _i24.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -1408,44 +1464,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i22.NodeModel? getPrimaryNodeFor({required _i16.Coin? coin}) => + _i24.NodeModel? getPrimaryNodeFor({required _i17.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i22.NodeModel?); + )) as _i24.NodeModel?); @override - List<_i22.NodeModel> getNodesFor(_i16.Coin? coin) => (super.noSuchMethod( + List<_i24.NodeModel> getNodesFor(_i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - _i22.NodeModel? getNodeById({required String? id}) => + _i24.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i22.NodeModel?); + )) as _i24.NodeModel?); @override - List<_i22.NodeModel> failoverNodesFor({required _i16.Coin? coin}) => + List<_i24.NodeModel> failoverNodesFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - _i17.Future<void> add( - _i22.NodeModel? node, + _i18.Future<void> add( + _i24.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -1458,11 +1514,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> delete( + _i18.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -1474,11 +1530,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setEnabledState( + _i18.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -1492,12 +1548,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> edit( - _i22.NodeModel? editedNode, + _i18.Future<void> edit( + _i24.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -1510,20 +1566,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i18.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1531,7 +1587,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1574,23 +1630,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i14.CoinServiceAPI get wallet => (super.noSuchMethod( + _i15.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_12( + returnValue: _FakeCoinServiceAPI_13( this, Invocation.getter(#wallet), ), - ) as _i14.CoinServiceAPI); + ) as _i15.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1623,23 +1679,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1649,16 +1705,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1678,10 +1734,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -1693,19 +1749,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1715,7 +1776,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1731,27 +1792,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1761,33 +1822,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1804,20 +1865,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i18.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1829,11 +1890,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1845,18 +1906,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1864,7 +1925,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1884,7 +1945,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i15.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1895,10 +1956,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1931,23 +1992,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1957,16 +2018,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1986,10 +2047,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2006,7 +2067,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: 0, ) as int); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2022,36 +2083,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2061,15 +2122,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2086,38 +2147,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2129,11 +2190,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2145,24 +2206,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); } diff --git a/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart b/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart index 3e88ef129..f510bde29 100644 --- a/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart +++ b/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i17; -import 'dart:ui' as _i19; +import 'dart:async' as _i18; +import 'dart:ui' as _i20; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,21 +13,23 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; -import 'package:stackwallet/models/node_model.dart' as _i22; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i22; +import 'package:stackwallet/models/node_model.dart' as _i24; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i20; -import 'package:stackwallet/services/coins/coin_service.dart' as _i14; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i21; +import 'package:stackwallet/services/coins/coin_service.dart' as _i15; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i15; +import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i23; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i13; -import 'package:stackwallet/utilities/prefs.dart' as _i18; + as _i14; +import 'package:stackwallet/utilities/prefs.dart' as _i19; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -154,9 +156,9 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } -class _FakeSecureStorageInterface_11 extends _i1.SmartFake - implements _i13.SecureStorageInterface { - _FakeSecureStorageInterface_11( +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( Object parent, Invocation parentInvocation, ) : super( @@ -165,9 +167,20 @@ class _FakeSecureStorageInterface_11 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_12 extends _i1.SmartFake - implements _i14.CoinServiceAPI { - _FakeCoinServiceAPI_12( +class _FakeSecureStorageInterface_12 extends _i1.SmartFake + implements _i14.SecureStorageInterface { + _FakeSecureStorageInterface_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_13 extends _i1.SmartFake + implements _i15.CoinServiceAPI { + _FakeCoinServiceAPI_13( Object parent, Invocation parentInvocation, ) : super( @@ -179,7 +192,7 @@ class _FakeCoinServiceAPI_12 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i15.Wallets { +class MockWallets extends _i1.Mock implements _i16.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -246,7 +259,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i16.Coin? coin}) => + List<String> getWalletIdsFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -256,18 +269,18 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Coin, + returnValue: <_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i16.Coin? coin) => + _i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -331,17 +344,17 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( + _i18.Future<void> load(_i19.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> loadAfterStackRestore( - _i18.Prefs? prefs, + _i18.Future<void> loadAfterStackRestore( + _i19.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -352,11 +365,11 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { managers, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -364,7 +377,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -390,19 +403,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i18.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i18.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i17.Future<Map<String, _i2.WalletInfo>>); + ) as _i18.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<bool> renameWallet({ + _i18.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -417,13 +430,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> addExistingStackWallet({ + _i18.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -437,13 +450,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<String?> addNewWallet({ + _i18.Future<String?> addNewWallet({ required String? name, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -456,46 +469,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i18.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i18.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> moveFavorite({ + _i18.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -508,48 +521,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i18.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i18.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<bool> isMnemonicVerified({required String? walletId}) => + _i18.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> setMnemonicVerified({required String? walletId}) => + _i18.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> deleteWallet( + _i18.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -561,20 +574,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i18.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -582,7 +595,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -610,13 +623,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i17.Timer? _timer) => super.noSuchMethod( + set timer(_i18.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -693,59 +706,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i18.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<int> get chainHeight => (super.noSuchMethod( + _i18.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -834,26 +847,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i12.MainDB); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i20.DerivePathType addressType({required String? address}) => + _i23.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i20.DerivePathType.bip44, - ) as _i20.DerivePathType); + returnValue: _i23.DerivePathType.bip44, + ) as _i23.DerivePathType); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -870,47 +883,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i18.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i18.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i18.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -926,26 +939,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -963,33 +976,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -999,35 +1012,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i18.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i17.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i18.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i17.Future<_i9.ElectrumXNode>); + ) as _i18.Future<_i9.ElectrumXNode>); @override - _i17.Future<void> addDerivation({ + _i18.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1041,13 +1054,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addDerivations({ + _i18.Future<void> addDerivations({ required int? chain, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1060,50 +1073,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<List<Map<String, dynamic>>> fastFetch( + _i18.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i17.Future<List<Map<String, dynamic>>>.value( + returnValue: _i18.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i17.Future<List<Map<String, dynamic>>>); + ) as _i18.Future<List<Map<String, dynamic>>>); @override - _i17.Future<int> getTxCount({required String? address}) => + _i18.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i18.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> checkCurrentChangeAddressesForTransactions() => + _i18.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1127,7 +1140,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i21.UTXO>? utxos, + List<_i22.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1143,19 +1156,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, )); @override - _i17.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i21.UTXO>? utxosToUse) => + _i18.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i22.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<Map<String, dynamic>> buildTransaction({ - required List<_i21.UTXO>? utxosToUse, + _i18.Future<Map<String, dynamic>> buildTransaction({ + required List<_i22.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1172,10 +1185,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1187,11 +1200,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1203,8 +1216,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1223,25 +1236,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i18.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void initCache( String? walletId, - _i16.Coin? coin, + _i17.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1254,14 +1267,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i18.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1271,14 +1284,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i18.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1288,15 +1301,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i18.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1312,15 +1325,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1336,15 +1349,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1354,6 +1367,49 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i22.Address>? myAddresses, + _i17.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>.value(_FakeTuple4_11<_i22.Transaction, + List<_i22.Output>, List<_i22.Input>, _i22.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>); } /// A class which mocks [NodeService]. @@ -1361,41 +1417,41 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i13.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i14.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_11( + returnValue: _FakeSecureStorageInterface_12( this, Invocation.getter(#secureStorageInterface), ), - ) as _i13.SecureStorageInterface); + ) as _i14.SecureStorageInterface); @override - List<_i22.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i24.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - List<_i22.NodeModel> get nodes => (super.noSuchMethod( + List<_i24.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateDefaults() => (super.noSuchMethod( + _i18.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setPrimaryNodeFor({ - required _i16.Coin? coin, - required _i22.NodeModel? node, + _i18.Future<void> setPrimaryNodeFor({ + required _i17.Coin? coin, + required _i24.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -1408,44 +1464,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i22.NodeModel? getPrimaryNodeFor({required _i16.Coin? coin}) => + _i24.NodeModel? getPrimaryNodeFor({required _i17.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i22.NodeModel?); + )) as _i24.NodeModel?); @override - List<_i22.NodeModel> getNodesFor(_i16.Coin? coin) => (super.noSuchMethod( + List<_i24.NodeModel> getNodesFor(_i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - _i22.NodeModel? getNodeById({required String? id}) => + _i24.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i22.NodeModel?); + )) as _i24.NodeModel?); @override - List<_i22.NodeModel> failoverNodesFor({required _i16.Coin? coin}) => + List<_i24.NodeModel> failoverNodesFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - _i17.Future<void> add( - _i22.NodeModel? node, + _i18.Future<void> add( + _i24.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -1458,11 +1514,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> delete( + _i18.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -1474,11 +1530,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setEnabledState( + _i18.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -1492,12 +1548,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> edit( - _i22.NodeModel? editedNode, + _i18.Future<void> edit( + _i24.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -1510,20 +1566,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i18.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1531,7 +1587,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1574,23 +1630,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i14.CoinServiceAPI get wallet => (super.noSuchMethod( + _i15.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_12( + returnValue: _FakeCoinServiceAPI_13( this, Invocation.getter(#wallet), ), - ) as _i14.CoinServiceAPI); + ) as _i15.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1623,23 +1679,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1649,16 +1705,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1678,10 +1734,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -1693,19 +1749,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1715,7 +1776,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1731,27 +1792,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1761,33 +1822,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1804,20 +1865,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i18.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1829,11 +1890,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1845,18 +1906,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1864,7 +1925,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1884,7 +1945,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i15.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1895,10 +1956,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1931,23 +1992,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1957,16 +2018,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1986,10 +2047,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2006,7 +2067,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: 0, ) as int); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2022,36 +2083,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2061,15 +2122,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2086,38 +2147,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2129,11 +2190,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2145,24 +2206,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); } From cbf969ef545bcad68990fbf8a982fa640174f5b8 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 17:42:20 -0600 Subject: [PATCH 026/123] desktop xmr/wow single wallet opening bug fix --- .../my_stack_view/wallet_summary_table.dart | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart index b638d72a1..9b98d4aa8 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart @@ -46,10 +46,15 @@ class _WalletTableState extends ConsumerState<WalletSummaryTable> { VoidCallback? expandOverride; if (providers.length == 1) { - expandOverride = () { - Navigator.of(context).pushNamed( + expandOverride = () async { + final manager = ref.read(providers.first); + if (manager.coin == Coin.monero || + manager.coin == Coin.wownero) { + await manager.initializeExisting(); + } + await Navigator.of(context).pushNamed( DesktopWalletView.routeName, - arguments: ref.read(providers.first).walletId, + arguments: manager.walletId, ); }; } From fb2d05eadd924544e5a8ee229e2bb6f19f7031b7 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Wed, 25 Jan 2023 16:48:50 -0700 Subject: [PATCH 027/123] desktop exchange toggle color fix --- lib/utilities/theme/fruit_sorbet_colors.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utilities/theme/fruit_sorbet_colors.dart b/lib/utilities/theme/fruit_sorbet_colors.dart index 6f0a81e82..3394b3a9c 100644 --- a/lib/utilities/theme/fruit_sorbet_colors.dart +++ b/lib/utilities/theme/fruit_sorbet_colors.dart @@ -327,7 +327,7 @@ class FruitSorbetColors extends StackColorTheme { @override Color get rateTypeToggleDesktopColorOn => const Color(0xFFFFD8CE); @override - Color get rateTypeToggleDesktopColorOff => buttonBackSecondary; + Color get rateTypeToggleDesktopColorOff => popupBG; @override BoxShadow get standardBoxShadow => BoxShadow( From ffda21f51387e678d7dd558033bd559f5c3370d2 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Jan 2023 17:42:20 -0600 Subject: [PATCH 028/123] desktop xmr/wow single wallet opening bug fix --- .../my_stack_view/wallet_summary_table.dart | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart index b638d72a1..9b98d4aa8 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart @@ -46,10 +46,15 @@ class _WalletTableState extends ConsumerState<WalletSummaryTable> { VoidCallback? expandOverride; if (providers.length == 1) { - expandOverride = () { - Navigator.of(context).pushNamed( + expandOverride = () async { + final manager = ref.read(providers.first); + if (manager.coin == Coin.monero || + manager.coin == Coin.wownero) { + await manager.initializeExisting(); + } + await Navigator.of(context).pushNamed( DesktopWalletView.routeName, - arguments: ref.read(providers.first).walletId, + arguments: manager.walletId, ); }; } From 3c9aa827bf80fcf4fa397d296ea107e653e9d264 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 09:18:07 -0600 Subject: [PATCH 029/123] update to versioned desktop secure storage and login key blob --- crypto_plugins/flutter_libmonero | 2 +- lib/utilities/desktop_password_service.dart | 59 +++++++++++++++++++-- pubspec.lock | 4 +- pubspec.yaml | 2 +- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index c1b403ccf..af88796d5 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit c1b403ccf6f4fffc9f7c233038c3df40f997c2b3 +Subproject commit af88796d5e4988c03422320c3842af5cf6c049ef diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart index 9ef83932b..6263eb33b 100644 --- a/lib/utilities/desktop_password_service.dart +++ b/lib/utilities/desktop_password_service.dart @@ -4,9 +4,12 @@ import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/utilities/logger.dart'; const String _kKeyBlobKey = "swbKeyBlobKeyStringID"; +const String _kKeyBlobVersionKey = "swbKeyBlobVersionKeyStringID"; + +const int kLatestBlobVersion = 2; String _getMessageFromException(Object exception) { - if (exception is IncorrectPassphrase) { + if (exception is IncorrectPassphraseOrVersion) { return exception.errMsg(); } if (exception is BadDecryption) { @@ -18,6 +21,9 @@ String _getMessageFromException(Object exception) { if (exception is EncodingError) { return exception.errMsg(); } + if (exception is VersionError) { + return exception.errMsg(); + } return exception.toString(); } @@ -41,7 +47,10 @@ class DPS { } try { - _handler = await StorageCryptoHandler.fromNewPassphrase(passphrase); + _handler = await StorageCryptoHandler.fromNewPassphrase( + passphrase, + kLatestBlobVersion, + ); final box = await Hive.openBox<String>(DB.boxNameDesktopData); await DB.instance.put<String>( @@ -49,6 +58,7 @@ class DPS { key: _kKeyBlobKey, value: await _handler!.getKeyBlob(), ); + await _updateStoredKeyBlobVersion(kLatestBlobVersion); await box.close(); } catch (e, s) { Logging.instance.log( @@ -78,7 +88,24 @@ class DPS { } try { - _handler = await StorageCryptoHandler.fromExisting(passphrase, keyBlob); + final blobVersion = await _getStoredKeyBlobVersion(); + _handler = await StorageCryptoHandler.fromExisting( + passphrase, + keyBlob, + blobVersion, + ); + if (blobVersion < kLatestBlobVersion) { + // update blob + await _handler!.resetPassphrase(passphrase, kLatestBlobVersion); + final box = await Hive.openBox<String>(DB.boxNameDesktopData); + await DB.instance.put<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobKey, + value: await _handler!.getKeyBlob(), + ); + await _updateStoredKeyBlobVersion(kLatestBlobVersion); + await box.close(); + } } catch (e, s) { Logging.instance.log( "${_getMessageFromException(e)}\n$s", @@ -102,7 +129,8 @@ class DPS { } try { - await StorageCryptoHandler.fromExisting(passphrase, keyBlob); + final blobVersion = await _getStoredKeyBlobVersion(); + await StorageCryptoHandler.fromExisting(passphrase, keyBlob, blobVersion); // existing passphrase matches key blob return true; } catch (e, s) { @@ -135,8 +163,10 @@ class DPS { return false; } + final blobVersion = await _getStoredKeyBlobVersion(); + try { - await _handler!.resetPassphrase(passphraseNew); + await _handler!.resetPassphrase(passphraseNew, blobVersion); final box = await Hive.openBox<String>(DB.boxNameDesktopData); await DB.instance.put<String>( @@ -144,6 +174,7 @@ class DPS { key: _kKeyBlobKey, value: await _handler!.getKeyBlob(), ); + await _updateStoredKeyBlobVersion(blobVersion); await box.close(); // successfully updated passphrase @@ -164,4 +195,22 @@ class DPS { ); return keyBlob != null; } + + Future<int> _getStoredKeyBlobVersion() async { + final box = await Hive.openBox<String>(DB.boxNameDesktopData); + final keyBlobVersionString = DB.instance.get<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobVersionKey, + ); + await box.close(); + return int.tryParse(keyBlobVersionString ?? "1") ?? 1; + } + + Future<void> _updateStoredKeyBlobVersion(int version) async { + await DB.instance.put<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobVersionKey, + value: version.toString(), + ); + } } diff --git a/pubspec.lock b/pubspec.lock index 8721ccc48..b5b417fd2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1408,8 +1408,8 @@ packages: dependency: "direct main" description: path: "." - ref: "6ada1204a4e0cf84d932b568e6150550478db69b" - resolved-ref: "6ada1204a4e0cf84d932b568e6150550478db69b" + ref: "93e2687bcc10fc7258c7dab038c363fc9ff8ba5d" + resolved-ref: "93e2687bcc10fc7258c7dab038c363fc9ff8ba5d" url: "https://github.com/cypherstack/stack_wallet_backup.git" source: git version: "0.0.1" diff --git a/pubspec.yaml b/pubspec.yaml index 759fc51f5..e1d2cba49 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,7 +54,7 @@ dependencies: stack_wallet_backup: git: url: https://github.com/cypherstack/stack_wallet_backup.git - ref: 6ada1204a4e0cf84d932b568e6150550478db69b + ref: 93e2687bcc10fc7258c7dab038c363fc9ff8ba5d bip47: git: From b49a1942a644c887f00cd98451772c2b9863474b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 09:18:07 -0600 Subject: [PATCH 030/123] update to versioned desktop secure storage and login key blob --- crypto_plugins/flutter_libmonero | 2 +- lib/utilities/desktop_password_service.dart | 59 +++++++++++++++++++-- pubspec.lock | 4 +- pubspec.yaml | 2 +- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index c1b403ccf..af88796d5 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit c1b403ccf6f4fffc9f7c233038c3df40f997c2b3 +Subproject commit af88796d5e4988c03422320c3842af5cf6c049ef diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart index 9ef83932b..6263eb33b 100644 --- a/lib/utilities/desktop_password_service.dart +++ b/lib/utilities/desktop_password_service.dart @@ -4,9 +4,12 @@ import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/utilities/logger.dart'; const String _kKeyBlobKey = "swbKeyBlobKeyStringID"; +const String _kKeyBlobVersionKey = "swbKeyBlobVersionKeyStringID"; + +const int kLatestBlobVersion = 2; String _getMessageFromException(Object exception) { - if (exception is IncorrectPassphrase) { + if (exception is IncorrectPassphraseOrVersion) { return exception.errMsg(); } if (exception is BadDecryption) { @@ -18,6 +21,9 @@ String _getMessageFromException(Object exception) { if (exception is EncodingError) { return exception.errMsg(); } + if (exception is VersionError) { + return exception.errMsg(); + } return exception.toString(); } @@ -41,7 +47,10 @@ class DPS { } try { - _handler = await StorageCryptoHandler.fromNewPassphrase(passphrase); + _handler = await StorageCryptoHandler.fromNewPassphrase( + passphrase, + kLatestBlobVersion, + ); final box = await Hive.openBox<String>(DB.boxNameDesktopData); await DB.instance.put<String>( @@ -49,6 +58,7 @@ class DPS { key: _kKeyBlobKey, value: await _handler!.getKeyBlob(), ); + await _updateStoredKeyBlobVersion(kLatestBlobVersion); await box.close(); } catch (e, s) { Logging.instance.log( @@ -78,7 +88,24 @@ class DPS { } try { - _handler = await StorageCryptoHandler.fromExisting(passphrase, keyBlob); + final blobVersion = await _getStoredKeyBlobVersion(); + _handler = await StorageCryptoHandler.fromExisting( + passphrase, + keyBlob, + blobVersion, + ); + if (blobVersion < kLatestBlobVersion) { + // update blob + await _handler!.resetPassphrase(passphrase, kLatestBlobVersion); + final box = await Hive.openBox<String>(DB.boxNameDesktopData); + await DB.instance.put<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobKey, + value: await _handler!.getKeyBlob(), + ); + await _updateStoredKeyBlobVersion(kLatestBlobVersion); + await box.close(); + } } catch (e, s) { Logging.instance.log( "${_getMessageFromException(e)}\n$s", @@ -102,7 +129,8 @@ class DPS { } try { - await StorageCryptoHandler.fromExisting(passphrase, keyBlob); + final blobVersion = await _getStoredKeyBlobVersion(); + await StorageCryptoHandler.fromExisting(passphrase, keyBlob, blobVersion); // existing passphrase matches key blob return true; } catch (e, s) { @@ -135,8 +163,10 @@ class DPS { return false; } + final blobVersion = await _getStoredKeyBlobVersion(); + try { - await _handler!.resetPassphrase(passphraseNew); + await _handler!.resetPassphrase(passphraseNew, blobVersion); final box = await Hive.openBox<String>(DB.boxNameDesktopData); await DB.instance.put<String>( @@ -144,6 +174,7 @@ class DPS { key: _kKeyBlobKey, value: await _handler!.getKeyBlob(), ); + await _updateStoredKeyBlobVersion(blobVersion); await box.close(); // successfully updated passphrase @@ -164,4 +195,22 @@ class DPS { ); return keyBlob != null; } + + Future<int> _getStoredKeyBlobVersion() async { + final box = await Hive.openBox<String>(DB.boxNameDesktopData); + final keyBlobVersionString = DB.instance.get<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobVersionKey, + ); + await box.close(); + return int.tryParse(keyBlobVersionString ?? "1") ?? 1; + } + + Future<void> _updateStoredKeyBlobVersion(int version) async { + await DB.instance.put<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobVersionKey, + value: version.toString(), + ); + } } diff --git a/pubspec.lock b/pubspec.lock index 8364e6ec9..43c38602b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1408,8 +1408,8 @@ packages: dependency: "direct main" description: path: "." - ref: "6ada1204a4e0cf84d932b568e6150550478db69b" - resolved-ref: "6ada1204a4e0cf84d932b568e6150550478db69b" + ref: "93e2687bcc10fc7258c7dab038c363fc9ff8ba5d" + resolved-ref: "93e2687bcc10fc7258c7dab038c363fc9ff8ba5d" url: "https://github.com/cypherstack/stack_wallet_backup.git" source: git version: "0.0.1" diff --git a/pubspec.yaml b/pubspec.yaml index ccaa53a4f..05701de28 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,7 +54,7 @@ dependencies: stack_wallet_backup: git: url: https://github.com/cypherstack/stack_wallet_backup.git - ref: 6ada1204a4e0cf84d932b568e6150550478db69b + ref: 93e2687bcc10fc7258c7dab038c363fc9ff8ba5d bip47: git: From 188a9bc0d0e454f5fe4069eec10ba321b90b906b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 10:05:49 -0600 Subject: [PATCH 031/123] update swb ref --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index e1d2cba49..32ab70261 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,7 +54,7 @@ dependencies: stack_wallet_backup: git: url: https://github.com/cypherstack/stack_wallet_backup.git - ref: 93e2687bcc10fc7258c7dab038c363fc9ff8ba5d + ref: e4b08d2b8965a5ae49bd57f598fa9011dd0c25e9 bip47: git: From bb94ad107076ed65fbe279a4b1353de3dd99f452 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 10:05:49 -0600 Subject: [PATCH 032/123] update swb ref --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 05701de28..0d20f2f7e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,7 +54,7 @@ dependencies: stack_wallet_backup: git: url: https://github.com/cypherstack/stack_wallet_backup.git - ref: 93e2687bcc10fc7258c7dab038c363fc9ff8ba5d + ref: e4b08d2b8965a5ae49bd57f598fa9011dd0c25e9 bip47: git: From 26c57b5456238b75a87ca06ab683d405316a38f6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 10:59:15 -0600 Subject: [PATCH 033/123] typecast to generic PaynymWalletInterface --- .../paynym/dialogs/paynym_details_popup.dart | 23 ++++++++-------- lib/pages/paynym/paynym_claim_view.dart | 14 +++++----- .../subwidgets/desktop_paynym_details.dart | 26 +++++++++---------- .../send_view/confirm_transaction_view.dart | 5 ++-- .../wallet_view/desktop_wallet_view.dart | 13 +++++----- .../paynym_follow_toggle_button.dart | 24 ++++++++--------- pubspec.lock | 4 +-- 7 files changed, 54 insertions(+), 55 deletions(-) diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index 295eff134..840e0e1fc 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -14,8 +14,7 @@ import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/route_generator.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -62,10 +61,10 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { ), ); - final wallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + final wallet = manager.wallet as PaynymWalletInterface; if (await wallet.hasConnected(widget.accountLite.code)) { canPop = true; @@ -74,7 +73,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { return; } - final rates = await wallet.fees; + final rates = await manager.fees; Map<String, dynamic> preparedTx; @@ -116,7 +115,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { Navigator.of(context).push( RouteGenerator.getRoute( builder: (_) => ConfirmTransactionView( - walletId: wallet.walletId, + walletId: manager.walletId, routeOnSuccessName: PaynymHomeView.routeName, isPaynymNotificationTransaction: true, transactionInfo: { @@ -132,7 +131,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { ); }, amount: (preparedTx["amount"] as int) + (preparedTx["fee"] as int), - coin: wallet.coin, + coin: manager.coin, ), ); } @@ -140,8 +139,10 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { @override Widget build(BuildContext context) { - final wallet = ref.watch(walletsChangeNotifierProvider.select( - (value) => value.getManager(widget.walletId).wallet as DogecoinWallet)); + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId))); + + final wallet = manager.wallet as PaynymWalletInterface; return DesktopDialog( maxWidth: MediaQuery.of(context).size.width - 32, diff --git a/lib/pages/paynym/paynym_claim_view.dart b/lib/pages/paynym/paynym_claim_view.dart index f141e04a4..23f9d868e 100644 --- a/lib/pages/paynym/paynym_claim_view.dart +++ b/lib/pages/paynym/paynym_claim_view.dart @@ -9,8 +9,7 @@ import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -160,17 +159,18 @@ class _PaynymClaimViewState extends ConsumerState<PaynymClaimView> { ).then((value) => shouldCancel = value == true), ); - // get wallet to access paynym calls - final wallet = ref + final manager = ref .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + .getManager(widget.walletId); + + // get wallet to access paynym calls + final wallet = manager.wallet as PaynymWalletInterface; if (shouldCancel) return; // get payment code final pCode = await wallet.getPaymentCode( - DerivePathTypeExt.primaryFor(wallet.coin)); + DerivePathTypeExt.primaryFor(manager.coin)); if (shouldCancel) return; diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index ac33ce475..61db83d7b 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -12,8 +12,7 @@ import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.d import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -58,10 +57,10 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { ), ); - final wallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + final wallet = manager.wallet as PaynymWalletInterface; if (await wallet.hasConnected(widget.accountLite.code)) { canPop = true; @@ -70,7 +69,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { return; } - final rates = await wallet.fees; + final rates = await manager.fees; Map<String, dynamic> preparedTx; @@ -113,7 +112,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { maxHeight: double.infinity, maxWidth: 580, child: ConfirmTransactionView( - walletId: wallet.walletId, + walletId: manager.walletId, isPaynymNotificationTransaction: true, transactionInfo: { "hex": preparedTx["hex"], @@ -142,7 +141,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { ); }, amount: (preparedTx["amount"] as int) + (preparedTx["fee"] as int), - coin: wallet.coin, + coin: manager.coin, ), ); } @@ -154,10 +153,11 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { @override Widget build(BuildContext context) { - final wallet = ref - .watch(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId))); + + final wallet = manager.wallet as PaynymWalletInterface; + return RoundedWhiteContainer( padding: const EdgeInsets.all(0), child: Column( diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index 8f36ce596..adc7a2e9c 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -12,10 +12,9 @@ import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart'; import 'package:stackwallet/route_generator.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -92,7 +91,7 @@ class _ConfirmTransactionViewState try { String txid; if (widget.isPaynymNotificationTransaction) { - txid = await (manager.wallet as DogecoinWallet) + txid = await (manager.wallet as PaynymWalletInterface) .broadcastNotificationTx(preparedTx: transactionInfo); } else if (widget.isPaynymTransaction) { // diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index c94b61550..8b8a65b58 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -19,10 +19,10 @@ import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/ui/transaction_filter_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -209,14 +209,13 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> { ), ); - // todo make generic and not doge specific - final wallet = (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet); + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + final wallet = manager.wallet as PaynymWalletInterface; final code = - await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(wallet.coin)); + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(manager.coin)); final account = await ref.read(paynymAPIProvider).nym(code.toString()); diff --git a/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart b/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart index a93a4510c..5591a5ff3 100644 --- a/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart +++ b/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart @@ -9,8 +9,7 @@ import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; @@ -59,17 +58,18 @@ class _PaynymFollowToggleButtonState ), ); - final wallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + // get wallet to access paynym calls + final wallet = manager.wallet as PaynymWalletInterface; final followedAccount = await ref .read(paynymAPIProvider) .nym(widget.paymentCodeStringToFollow, true); final myPCode = - await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(wallet.coin)); + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(manager.coin)); PaynymResponse<String> token = await ref.read(paynymAPIProvider).token(myPCode.toString()); @@ -160,17 +160,17 @@ class _PaynymFollowToggleButtonState ), ); - final wallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + final wallet = manager.wallet as PaynymWalletInterface; final followedAccount = await ref .read(paynymAPIProvider) .nym(widget.paymentCodeStringToFollow, true); final myPCode = - await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(wallet.coin)); + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(manager.coin)); PaynymResponse<String> token = await ref.read(paynymAPIProvider).token(myPCode.toString()); diff --git a/pubspec.lock b/pubspec.lock index b5b417fd2..073ef8a47 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1408,8 +1408,8 @@ packages: dependency: "direct main" description: path: "." - ref: "93e2687bcc10fc7258c7dab038c363fc9ff8ba5d" - resolved-ref: "93e2687bcc10fc7258c7dab038c363fc9ff8ba5d" + ref: e4b08d2b8965a5ae49bd57f598fa9011dd0c25e9 + resolved-ref: e4b08d2b8965a5ae49bd57f598fa9011dd0c25e9 url: "https://github.com/cypherstack/stack_wallet_backup.git" source: git version: "0.0.1" From 4f2690f88085d69bfa996ce5061cbceb71b0b8c7 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 11:28:58 -0600 Subject: [PATCH 034/123] show available balance label and linter fixes --- lib/pages/send_view/send_view.dart | 78 +++++++++++++----------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index f687ab9a6..0109a5b53 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -266,9 +266,9 @@ class _SendViewState extends ConsumerState<SendView> { Decimal? balance; if (ref.read(publicPrivateBalanceStateProvider.state).state == "Private") { - balance = await wallet.availablePrivateBalance(); + balance = wallet.availablePrivateBalance(); } else { - balance = await wallet.availablePublicBalance(); + balance = wallet.availablePublicBalance(); } return Format.localizedStringAsFixed( @@ -442,48 +442,38 @@ class _SendViewState extends ConsumerState<SendView> { const SizedBox( width: 6, ), - if (coin != Coin.firo && - coin != Coin.firoTestNet) - Expanded( - child: Text( + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( ref.watch(provider.select( (value) => value.walletName)), - style: STextStyles.titleBold12(context), + style: STextStyles.titleBold12(context) + .copyWith(fontSize: 14), overflow: TextOverflow.ellipsis, maxLines: 1, ), - ), - if (coin == Coin.firo || - coin == Coin.firoTestNet) - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - ref.watch(provider.select( - (value) => value.walletName)), - style: - STextStyles.titleBold12(context) - .copyWith(fontSize: 14), - ), - // const SizedBox( - // height: 2, - // ), + // const SizedBox( + // height: 2, + // ), + if (coin == Coin.firo || + coin == Coin.firoTestNet) Text( "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance", style: STextStyles.label(context) .copyWith(fontSize: 10), ), - ], - ), - if (coin != Coin.firo && - coin != Coin.firoTestNet) - const SizedBox( - width: 10, - ), - if (coin == Coin.firo || - coin == Coin.firoTestNet) - const Spacer(), + if (coin != Coin.firo && + coin != Coin.firoTestNet) + Text( + "Available balance", + style: STextStyles.label(context) + .copyWith(fontSize: 10), + ), + ], + ), + const Spacer(), FutureBuilder( // TODO redo this widget now that its not actually a future future: (coin != Coin.firo && @@ -1072,17 +1062,17 @@ class _SendViewState extends ConsumerState<SendView> { .state) .state == "Private") { - cryptoAmountController.text = - (await firoWallet - .availablePrivateBalance()) - .toStringAsFixed(Constants - .decimalPlacesForCoin(coin)); + cryptoAmountController.text = firoWallet + .availablePrivateBalance() + .toStringAsFixed( + Constants.decimalPlacesForCoin( + coin)); } else { - cryptoAmountController.text = - (await firoWallet - .availablePublicBalance()) - .toStringAsFixed(Constants - .decimalPlacesForCoin(coin)); + cryptoAmountController.text = firoWallet + .availablePublicBalance() + .toStringAsFixed( + Constants.decimalPlacesForCoin( + coin)); } } else { cryptoAmountController.text = (ref From a41c903a96f9bb0b432603fd842b96411304a183 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 11:46:16 -0600 Subject: [PATCH 035/123] mobile paynym send view --- .../paynym/dialogs/paynym_details_popup.dart | 13 +- lib/pages/send_view/send_view.dart | 494 +++++++++--------- lib/route_generator.dart | 13 + 3 files changed, 286 insertions(+), 234 deletions(-) diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index 840e0e1fc..a2aea2a14 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -12,6 +12,7 @@ import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.d import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; +import 'package:stackwallet/pages/send_view/send_view.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; @@ -25,6 +26,7 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/loading_indicator.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; +import 'package:tuple/tuple.dart'; class PaynymDetailsPopup extends ConsumerStatefulWidget { const PaynymDetailsPopup({ @@ -44,7 +46,16 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { bool _showInsufficientFundsInfo = false; Future<void> _onSend() async { - // todo send + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + await Navigator.of(context).pushNamed( + SendView.routeName, + arguments: Tuple3( + manager.walletId, + manager.coin, + widget.accountLite, + ), + ); } Future<void> _onConnectPressed() async { diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index 0109a5b53..81cfa9569 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/models/send_view_auto_fill_data.dart'; import 'package:stackwallet/pages/address_book_views/address_book_view.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; @@ -52,6 +53,7 @@ class SendView extends ConsumerStatefulWidget { this.autoFillData, this.clipboard = const ClipboardWrapper(), this.barcodeScanner = const BarcodeScannerWrapper(), + this.accountLite, }) : super(key: key); static const String routeName = "/sendView"; @@ -61,6 +63,7 @@ class SendView extends ConsumerStatefulWidget { final SendViewAutoFillData? autoFillData; final ClipboardInterface clipboard; final BarcodeScannerInterface barcodeScanner; + final PaynymAccountLite? accountLite; @override ConsumerState<SendView> createState() => _SendViewState(); @@ -278,6 +281,8 @@ class _SendViewState extends ConsumerState<SendView> { return null; } + bool get isPaynymSend => widget.accountLite != null; + @override void initState() { ref.refresh(feeSheetSessionCacheProvider); @@ -307,6 +312,11 @@ class _SendViewState extends ConsumerState<SendView> { _addressToggleFlag = true; } + if (isPaynymSend) { + sendToController.text = widget.accountLite!.nymName; + noteController.text = "PayNym send"; + } + if (coin != Coin.epicCash) { _cryptoFocus.addListener(() { if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) { @@ -599,102 +609,253 @@ class _SendViewState extends ConsumerState<SendView> { height: 16, ), Text( - "Send to", + isPaynymSend ? "Send to PayNym address" : "Send to", style: STextStyles.smallMed12(context), textAlign: TextAlign.left, ), const SizedBox( height: 8, ), - ClipRRect( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - child: TextField( - key: const Key("sendViewAddressFieldKey"), + if (isPaynymSend) + TextField( + key: const Key("sendViewPaynymAddressFieldKey"), controller: sendToController, - readOnly: false, - autocorrect: false, - enableSuggestions: false, - // inputFormatters: <TextInputFormatter>[ - // FilteringTextInputFormatter.allow( - // RegExp("[a-zA-Z0-9]{34}")), - // ], - toolbarOptions: const ToolbarOptions( - copy: false, - cut: false, - paste: true, - selectAll: false, + enabled: false, + readOnly: true, + style: STextStyles.fieldLabel(context), + ), + if (!isPaynymSend) + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, ), - onChanged: (newValue) { - _address = newValue; - _updatePreviewButtonState( - _address, _amountToSend); - - setState(() { - _addressToggleFlag = newValue.isNotEmpty; - }); - }, - focusNode: _addressFocusNode, - style: STextStyles.field(context), - decoration: standardInputDecoration( - "Enter ${coin.ticker} address", - _addressFocusNode, - context, - ).copyWith( - contentPadding: const EdgeInsets.only( - left: 16, - top: 6, - bottom: 8, - right: 5, + child: TextField( + key: const Key("sendViewAddressFieldKey"), + controller: sendToController, + readOnly: false, + autocorrect: false, + enableSuggestions: false, + // inputFormatters: <TextInputFormatter>[ + // FilteringTextInputFormatter.allow( + // RegExp("[a-zA-Z0-9]{34}")), + // ], + toolbarOptions: const ToolbarOptions( + copy: false, + cut: false, + paste: true, + selectAll: false, ), - suffixIcon: Padding( - padding: sendToController.text.isEmpty - ? const EdgeInsets.only(right: 8) - : const EdgeInsets.only(right: 0), - child: UnconstrainedBox( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceAround, - children: [ - _addressToggleFlag - ? TextFieldIconButton( - key: const Key( - "sendViewClearAddressFieldButtonKey"), - onTap: () { - sendToController.text = ""; - _address = ""; - _updatePreviewButtonState( - _address, _amountToSend); - setState(() { - _addressToggleFlag = false; - }); - }, - child: const XIcon(), - ) - : TextFieldIconButton( - key: const Key( - "sendViewPasteAddressFieldButtonKey"), - onTap: () async { - final ClipboardData? data = - await clipboard.getData( - Clipboard.kTextPlain); - if (data?.text != null && - data!.text!.isNotEmpty) { - String content = - data.text!.trim(); - if (content - .contains("\n")) { - content = - content.substring( - 0, - content.indexOf( - "\n")); + onChanged: (newValue) { + _address = newValue; + _updatePreviewButtonState( + _address, _amountToSend); + + setState(() { + _addressToggleFlag = newValue.isNotEmpty; + }); + }, + focusNode: _addressFocusNode, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Enter ${coin.ticker} address", + _addressFocusNode, + context, + ).copyWith( + contentPadding: const EdgeInsets.only( + left: 16, + top: 6, + bottom: 8, + right: 5, + ), + suffixIcon: Padding( + padding: sendToController.text.isEmpty + ? const EdgeInsets.only(right: 8) + : const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + _addressToggleFlag + ? TextFieldIconButton( + key: const Key( + "sendViewClearAddressFieldButtonKey"), + onTap: () { + sendToController.text = ""; + _address = ""; + _updatePreviewButtonState( + _address, + _amountToSend); + setState(() { + _addressToggleFlag = + false; + }); + }, + child: const XIcon(), + ) + : TextFieldIconButton( + key: const Key( + "sendViewPasteAddressFieldButtonKey"), + onTap: () async { + final ClipboardData? data = + await clipboard.getData( + Clipboard + .kTextPlain); + if (data?.text != null && + data! + .text!.isNotEmpty) { + String content = + data.text!.trim(); + if (content + .contains("\n")) { + content = + content.substring( + 0, + content.indexOf( + "\n")); + } + + sendToController.text = + content; + _address = content; + + _updatePreviewButtonState( + _address, + _amountToSend); + setState(() { + _addressToggleFlag = + sendToController + .text + .isNotEmpty; + }); + } + }, + child: sendToController + .text.isEmpty + ? const ClipboardIcon() + : const XIcon(), + ), + if (sendToController.text.isEmpty) + TextFieldIconButton( + key: const Key( + "sendViewAddressBookButtonKey"), + onTap: () { + Navigator.of(context).pushNamed( + AddressBookView.routeName, + arguments: widget.coin, + ); + }, + child: const AddressBookIcon(), + ), + if (sendToController.text.isEmpty) + TextFieldIconButton( + key: const Key( + "sendViewScanQrButtonKey"), + onTap: () async { + try { + // ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = false; + if (FocusScope.of(context) + .hasFocus) { + FocusScope.of(context) + .unfocus(); + await Future<void>.delayed( + const Duration( + milliseconds: 75)); + } + + final qrResult = + await scanner.scan(); + + // Future<void>.delayed( + // const Duration(seconds: 2), + // () => ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = true, + // ); + + Logging.instance.log( + "qrResult content: ${qrResult.rawContent}", + level: LogLevel.Info); + + final results = + AddressUtils.parseUri( + qrResult.rawContent); + + Logging.instance.log( + "qrResult parsed: $results", + level: LogLevel.Info); + + if (results.isNotEmpty && + results["scheme"] == + coin.uriScheme) { + // auto fill address + _address = + results["address"] ?? + ""; + sendToController.text = + _address!; + + // autofill notes field + if (results["message"] != + null) { + noteController.text = + results["message"]!; + } else if (results[ + "label"] != + null) { + noteController.text = + results["label"]!; } + // autofill amount field + if (results["amount"] != + null) { + final amount = + Decimal.parse(results[ + "amount"]!); + cryptoAmountController + .text = + Format + .localizedStringAsFixed( + value: amount, + locale: ref + .read( + localeServiceChangeNotifierProvider) + .locale, + decimalPlaces: Constants + .decimalPlacesForCoin( + coin), + ); + amount.toString(); + _amountToSend = amount; + } + + _updatePreviewButtonState( + _address, + _amountToSend); + setState(() { + _addressToggleFlag = + sendToController + .text.isNotEmpty; + }); + + // now check for non standard encoded basic address + } else if (ref + .read( + walletsChangeNotifierProvider) + .getManager(walletId) + .validateAddress(qrResult + .rawContent)) { + _address = + qrResult.rawContent; sendToController.text = - content; - _address = content; + _address ?? ""; _updatePreviewButtonState( _address, @@ -705,161 +866,28 @@ class _SendViewState extends ConsumerState<SendView> { .text.isNotEmpty; }); } - }, - child: sendToController - .text.isEmpty - ? const ClipboardIcon() - : const XIcon(), - ), - if (sendToController.text.isEmpty) - TextFieldIconButton( - key: const Key( - "sendViewAddressBookButtonKey"), - onTap: () { - Navigator.of(context).pushNamed( - AddressBookView.routeName, - arguments: widget.coin, - ); - }, - child: const AddressBookIcon(), - ), - if (sendToController.text.isEmpty) - TextFieldIconButton( - key: const Key( - "sendViewScanQrButtonKey"), - onTap: () async { - try { - // ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = false; - if (FocusScope.of(context) - .hasFocus) { - FocusScope.of(context) - .unfocus(); - await Future<void>.delayed( - const Duration( - milliseconds: 75)); + } on PlatformException catch (e, s) { + // ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = true; + // here we ignore the exception caused by not giving permission + // to use the camera to scan a qr code + Logging.instance.log( + "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", + level: LogLevel.Warning); } - - final qrResult = - await scanner.scan(); - - // Future<void>.delayed( - // const Duration(seconds: 2), - // () => ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = true, - // ); - - Logging.instance.log( - "qrResult content: ${qrResult.rawContent}", - level: LogLevel.Info); - - final results = - AddressUtils.parseUri( - qrResult.rawContent); - - Logging.instance.log( - "qrResult parsed: $results", - level: LogLevel.Info); - - if (results.isNotEmpty && - results["scheme"] == - coin.uriScheme) { - // auto fill address - _address = - results["address"] ?? ""; - sendToController.text = - _address!; - - // autofill notes field - if (results["message"] != - null) { - noteController.text = - results["message"]!; - } else if (results["label"] != - null) { - noteController.text = - results["label"]!; - } - - // autofill amount field - if (results["amount"] != - null) { - final amount = - Decimal.parse( - results["amount"]!); - cryptoAmountController - .text = - Format - .localizedStringAsFixed( - value: amount, - locale: ref - .read( - localeServiceChangeNotifierProvider) - .locale, - decimalPlaces: Constants - .decimalPlacesForCoin( - coin), - ); - amount.toString(); - _amountToSend = amount; - } - - _updatePreviewButtonState( - _address, _amountToSend); - setState(() { - _addressToggleFlag = - sendToController - .text.isNotEmpty; - }); - - // now check for non standard encoded basic address - } else if (ref - .read( - walletsChangeNotifierProvider) - .getManager(walletId) - .validateAddress( - qrResult.rawContent)) { - _address = - qrResult.rawContent; - sendToController.text = - _address ?? ""; - - _updatePreviewButtonState( - _address, _amountToSend); - setState(() { - _addressToggleFlag = - sendToController - .text.isNotEmpty; - }); - } - } on PlatformException catch (e, s) { - // ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = true; - // here we ignore the exception caused by not giving permission - // to use the camera to scan a qr code - Logging.instance.log( - "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", - level: LogLevel.Warning); - } - }, - child: const QrCodeIcon(), - ) - ], + }, + child: const QrCodeIcon(), + ) + ], + ), ), ), ), ), ), - ), Builder( builder: (_) { final error = _updateInvalidAddressText( diff --git a/lib/route_generator.dart b/lib/route_generator.dart index af88499ba..e83863312 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -6,6 +6,7 @@ import 'package:stackwallet/models/buy/response_objects/quote.dart'; import 'package:stackwallet/models/contact_address_entry.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart'; +import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/models/send_view_auto_fill_data.dart'; import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart'; import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart'; @@ -841,6 +842,18 @@ class RouteGenerator { name: settings.name, ), ); + } else if (args is Tuple3<String, Coin, PaynymAccountLite>) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => SendView( + walletId: args.item1, + coin: args.item2, + accountLite: args.item3, + ), + settings: RouteSettings( + name: settings.name, + ), + ); } return _routeError("${settings.name} invalid args: ${args.toString()}"); From 828c301af7e5cb9fbdbe35f8976b9d9c063f5f4c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 12:16:38 -0600 Subject: [PATCH 036/123] mobile paynym send flow implemented --- .../send_view/confirm_transaction_view.dart | 14 +- lib/pages/send_view/send_view.dart | 487 +++++++++--------- .../mixins/paynym_wallet_interface.dart | 10 +- 3 files changed, 252 insertions(+), 259 deletions(-) diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index adc7a2e9c..f56911a63 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -4,6 +4,7 @@ import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart'; import 'package:stackwallet/pages/send_view/sub_widgets/sending_transaction_dialog.dart'; @@ -94,8 +95,7 @@ class _ConfirmTransactionViewState txid = await (manager.wallet as PaynymWalletInterface) .broadcastNotificationTx(preparedTx: transactionInfo); } else if (widget.isPaynymTransaction) { - // - throw UnimplementedError("paynym send not implemented yet"); + txid = await manager.confirmSend(txData: transactionInfo); } else { final coin = manager.coin; if ((coin == Coin.firo || coin == Coin.firoTestNet) && @@ -333,14 +333,20 @@ class _ConfirmTransactionViewState crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( - "Recipient", + widget.isPaynymTransaction + ? "PayNym recipient" + : "Recipient", style: STextStyles.smallMed12(context), ), const SizedBox( height: 4, ), Text( - "${transactionInfo["address"] ?? "ERROR"}", + widget.isPaynymTransaction + ? (transactionInfo["paynymAccountLite"] + as PaynymAccountLite) + .nymName + : "${transactionInfo["address"] ?? "ERROR"}", style: STextStyles.itemSubtitle12(context), ), ], diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index 81cfa9569..c9216bf0e 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:bip47/bip47.dart'; import 'package:cw_core/monero_transaction_priority.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; @@ -20,6 +21,7 @@ import 'package:stackwallet/providers/wallet/public_private_balance_state_provid import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/services/coins/manager.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/address_utils.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/barcode_scanner_interface.dart'; @@ -162,12 +164,17 @@ class _SendViewState extends ConsumerState<SendView> { } void _updatePreviewButtonState(String? address, Decimal? amount) { - final isValidAddress = ref - .read(walletsChangeNotifierProvider) - .getManager(walletId) - .validateAddress(address ?? ""); - ref.read(previewTxButtonStateProvider.state).state = - (isValidAddress && amount != null && amount > Decimal.zero); + if (isPaynymSend) { + ref.read(previewTxButtonStateProvider.state).state = + (amount != null && amount > Decimal.zero); + } else { + final isValidAddress = ref + .read(walletsChangeNotifierProvider) + .getManager(walletId) + .validateAddress(address ?? ""); + ref.read(previewTxButtonStateProvider.state).state = + (isValidAddress && amount != null && amount > Decimal.zero); + } } late Future<String> _calculateFeesFuture; @@ -281,6 +288,226 @@ class _SendViewState extends ConsumerState<SendView> { return null; } + Future<void> _previewTransaction() async { + // wait for keyboard to disappear + FocusScope.of(context).unfocus(); + await Future<void>.delayed( + const Duration(milliseconds: 100), + ); + final manager = + ref.read(walletsChangeNotifierProvider).getManager(walletId); + + // // TODO: remove the need for this!! + // final bool isOwnAddress = + // await manager.isOwnAddress(_address!); + // if (isOwnAddress && coin != Coin.dogecoinTestNet) { + // await showDialog<dynamic>( + // context: context, + // useSafeArea: false, + // barrierDismissible: true, + // builder: (context) { + // return StackDialog( + // title: "Transaction failed", + // message: + // "Sending to self is currently disabled", + // rightButton: TextButton( + // style: Theme.of(context) + // .extension<StackColors>()! + // .getSecondaryEnabledButtonColor( + // context), + // child: Text( + // "Ok", + // style: STextStyles.button( + // context) + // .copyWith( + // color: Theme.of(context) + // .extension< + // StackColors>()! + // .accentColorDark), + // ), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ); + // }, + // ); + // return; + // } + + final amount = Format.decimalAmountToSatoshis(_amountToSend!, coin); + int availableBalance; + if ((coin == Coin.firo || coin == Coin.firoTestNet)) { + if (ref.read(publicPrivateBalanceStateProvider.state).state == + "Private") { + availableBalance = Format.decimalAmountToSatoshis( + (manager.wallet as FiroWallet).availablePrivateBalance(), coin); + } else { + availableBalance = Format.decimalAmountToSatoshis( + (manager.wallet as FiroWallet).availablePublicBalance(), coin); + } + } else { + availableBalance = + Format.decimalAmountToSatoshis(manager.balance.getSpendable(), coin); + } + + // confirm send all + if (amount == availableBalance) { + final bool? shouldSendAll = await showDialog<bool>( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return StackDialog( + title: "Confirm send all", + message: + "You are about to send your entire balance. Would you like to continue?", + leftButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Cancel", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark), + ), + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + rightButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getPrimaryEnabledButtonStyle(context), + child: Text( + "Yes", + style: STextStyles.button(context), + ), + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ); + }, + ); + + if (shouldSendAll == null || shouldSendAll == false) { + // cancel preview + return; + } + } + + try { + bool wasCancelled = false; + + unawaited( + showDialog<dynamic>( + context: context, + useSafeArea: false, + barrierDismissible: false, + builder: (context) { + return BuildingTransactionDialog( + onCancel: () { + wasCancelled = true; + + Navigator.of(context).pop(); + }, + ); + }, + ), + ); + + Map<String, dynamic> txData; + + if (isPaynymSend) { + final wallet = manager.wallet as PaynymWalletInterface; + final paymentCode = PaymentCode.fromPaymentCode( + widget.accountLite!.code, + wallet.networkType, + ); + final feeRate = ref.read(feeRateTypeStateProvider); + txData = await wallet.preparePaymentCodeSend( + paymentCode: paymentCode, + satoshiAmount: amount, + args: {"feeRate": feeRate}, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && + ref.read(publicPrivateBalanceStateProvider.state).state != + "Private") { + txData = await (manager.wallet as FiroWallet).prepareSendPublic( + address: _address!, + satoshiAmount: amount, + args: {"feeRate": ref.read(feeRateTypeStateProvider)}, + ); + } else { + txData = await manager.prepareSend( + address: _address!, + satoshiAmount: amount, + args: {"feeRate": ref.read(feeRateTypeStateProvider)}, + ); + } + + if (!wasCancelled && mounted) { + // pop building dialog + Navigator.of(context).pop(); + txData["note"] = noteController.text; + if (isPaynymSend) { + txData["paynymAccountLite"] = widget.accountLite!; + } else { + txData["address"] = _address; + } + + unawaited(Navigator.of(context).push( + RouteGenerator.getRoute( + shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute, + builder: (_) => ConfirmTransactionView( + transactionInfo: txData, + walletId: walletId, + isPaynymTransaction: isPaynymSend, + ), + settings: const RouteSettings( + name: ConfirmTransactionView.routeName, + ), + ), + )); + } + } catch (e) { + if (mounted) { + // pop building dialog + Navigator.of(context).pop(); + + unawaited(showDialog<dynamic>( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return StackDialog( + title: "Transaction failed", + message: e.toString(), + rightButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Ok", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark), + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ); + }, + )); + } + } + } + bool get isPaynymSend => widget.accountLite != null; @override @@ -1532,253 +1759,7 @@ class _SendViewState extends ConsumerState<SendView> { onPressed: ref .watch(previewTxButtonStateProvider.state) .state - ? () async { - // wait for keyboard to disappear - FocusScope.of(context).unfocus(); - await Future<void>.delayed( - const Duration(milliseconds: 100), - ); - final manager = ref - .read(walletsChangeNotifierProvider) - .getManager(walletId); - - // // TODO: remove the need for this!! - // final bool isOwnAddress = - // await manager.isOwnAddress(_address!); - // if (isOwnAddress && coin != Coin.dogecoinTestNet) { - // await showDialog<dynamic>( - // context: context, - // useSafeArea: false, - // barrierDismissible: true, - // builder: (context) { - // return StackDialog( - // title: "Transaction failed", - // message: - // "Sending to self is currently disabled", - // rightButton: TextButton( - // style: Theme.of(context) - // .extension<StackColors>()! - // .getSecondaryEnabledButtonColor( - // context), - // child: Text( - // "Ok", - // style: STextStyles.button( - // context) - // .copyWith( - // color: Theme.of(context) - // .extension< - // StackColors>()! - // .accentColorDark), - // ), - // onPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // }, - // ); - // return; - // } - - final amount = - Format.decimalAmountToSatoshis( - _amountToSend!, coin); - int availableBalance; - if ((coin == Coin.firo || - coin == Coin.firoTestNet)) { - if (ref - .read( - publicPrivateBalanceStateProvider - .state) - .state == - "Private") { - availableBalance = - Format.decimalAmountToSatoshis( - (manager.wallet as FiroWallet) - .availablePrivateBalance(), - coin); - } else { - availableBalance = - Format.decimalAmountToSatoshis( - (manager.wallet as FiroWallet) - .availablePublicBalance(), - coin); - } - } else { - availableBalance = - Format.decimalAmountToSatoshis( - manager.balance.getSpendable(), - coin); - } - - // confirm send all - if (amount == availableBalance) { - final bool? shouldSendAll = - await showDialog<bool>( - context: context, - useSafeArea: false, - barrierDismissible: true, - builder: (context) { - return StackDialog( - title: "Confirm send all", - message: - "You are about to send your entire balance. Would you like to continue?", - leftButton: TextButton( - style: Theme.of(context) - .extension<StackColors>()! - .getSecondaryEnabledButtonStyle( - context), - child: Text( - "Cancel", - style: STextStyles.button( - context) - .copyWith( - color: Theme.of(context) - .extension< - StackColors>()! - .accentColorDark), - ), - onPressed: () { - Navigator.of(context) - .pop(false); - }, - ), - rightButton: TextButton( - style: Theme.of(context) - .extension<StackColors>()! - .getPrimaryEnabledButtonStyle( - context), - child: Text( - "Yes", - style: - STextStyles.button(context), - ), - onPressed: () { - Navigator.of(context).pop(true); - }, - ), - ); - }, - ); - - if (shouldSendAll == null || - shouldSendAll == false) { - // cancel preview - return; - } - } - - try { - bool wasCancelled = false; - - unawaited(showDialog<dynamic>( - context: context, - useSafeArea: false, - barrierDismissible: false, - builder: (context) { - return BuildingTransactionDialog( - onCancel: () { - wasCancelled = true; - - Navigator.of(context).pop(); - }, - ); - }, - )); - - Map<String, dynamic> txData; - - if ((coin == Coin.firo || - coin == Coin.firoTestNet) && - ref - .read( - publicPrivateBalanceStateProvider - .state) - .state != - "Private") { - txData = - await (manager.wallet as FiroWallet) - .prepareSendPublic( - address: _address!, - satoshiAmount: amount, - args: { - "feeRate": ref - .read(feeRateTypeStateProvider) - }, - ); - } else { - txData = await manager.prepareSend( - address: _address!, - satoshiAmount: amount, - args: { - "feeRate": ref - .read(feeRateTypeStateProvider) - }, - ); - } - - if (!wasCancelled && mounted) { - // pop building dialog - Navigator.of(context).pop(); - txData["note"] = noteController.text; - txData["address"] = _address; - - unawaited(Navigator.of(context).push( - RouteGenerator.getRoute( - shouldUseMaterialRoute: - RouteGenerator - .useMaterialPageRoute, - builder: (_) => - ConfirmTransactionView( - transactionInfo: txData, - walletId: walletId, - ), - settings: const RouteSettings( - name: ConfirmTransactionView - .routeName, - ), - ), - )); - } - } catch (e) { - if (mounted) { - // pop building dialog - Navigator.of(context).pop(); - - unawaited(showDialog<dynamic>( - context: context, - useSafeArea: false, - barrierDismissible: true, - builder: (context) { - return StackDialog( - title: "Transaction failed", - message: e.toString(), - rightButton: TextButton( - style: Theme.of(context) - .extension<StackColors>()! - .getSecondaryEnabledButtonStyle( - context), - child: Text( - "Ok", - style: STextStyles.button( - context) - .copyWith( - color: Theme.of( - context) - .extension< - StackColors>()! - .accentColorDark), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ); - }, - )); - } - } - } + ? _previewTransaction : null, style: ref .watch(previewTxButtonStateProvider.state) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 1073c3c40..45f33d3be 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -105,6 +105,9 @@ mixin PaynymWalletInterface { _checkChangeAddressForTransactions = checkChangeAddressForTransactions; } + // convenience getter + btc_dart.NetworkType get networkType => _network; + // generate bip32 payment code root Future<bip32.BIP32> getRootNode({ required List<String> mnemonic, @@ -147,7 +150,7 @@ mixin PaynymWalletInterface { return Format.uint8listToString(bytes); } - Future<Future<Map<String, dynamic>>> preparePaymentCodeSend( + Future<Map<String, dynamic>> preparePaymentCodeSend( {required PaymentCode paymentCode, required int satoshiAmount, Map<String, dynamic>? args}) async { @@ -163,7 +166,10 @@ mixin PaynymWalletInterface { ); return _prepareSend( - address: sendToAddress.value, satoshiAmount: satoshiAmount); + address: sendToAddress.value, + satoshiAmount: satoshiAmount, + args: args, + ); } } From 4170ca958f3e0ff861fc7d6d5a1c9408bcf62761 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 15:22:39 -0600 Subject: [PATCH 037/123] include paynym receiving addresses when checking for incoming transaction amounts --- lib/services/mixins/electrum_x_parsing.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index 61bc03beb..23be3d80d 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -19,6 +19,7 @@ mixin ElectrumXParsing { Set<String> receivingAddresses = myAddresses .where((e) => e.subType == AddressSubType.receiving || + e.subType == AddressSubType.paynymReceive || e.subType == AddressSubType.paynymNotification) .map((e) => e.value) .toSet(); From 9cc0d74b16b182ddac0775e3f5c8d0945803b311 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 15:25:53 -0600 Subject: [PATCH 038/123] check paynym receiving addresses based on payment code notification tx history --- .../coins/dogecoin/dogecoin_wallet.dart | 2 + .../mixins/paynym_wallet_interface.dart | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index f5a057500..f6b13f586 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -762,6 +762,8 @@ class DogecoinWallet extends CoinServiceAPI GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); await _checkCurrentReceivingAddressesForTransactions(); + await checkAllCurrentReceivingPaynymAddressesForTransactions(); + final fetchFuture = _refreshTransactions(); final utxosRefreshFuture = _updateUTXOs(); GlobalEventBus.instance diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 45f33d3be..1d194feb9 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -108,6 +108,70 @@ mixin PaynymWalletInterface { // convenience getter btc_dart.NetworkType get networkType => _network; + Future<Address> currentReceivingPaynymAddress(PaymentCode sender) async { + final address = await _db + .getAddresses(_walletId) + .filter() + .group((q) => q + .subTypeEqualTo(AddressSubType.paynymReceive) + .and() + .otherDataEqualTo(sender.toString())) + .sortByDerivationIndexDesc() + .findFirst(); + + if (address == null) { + final generatedAddress = await _generatePaynymReceivingAddress(sender, 0); + await _db.putAddress(generatedAddress); + return currentReceivingPaynymAddress(sender); + } else { + return address; + } + } + + Future<Address> _generatePaynymReceivingAddress( + PaymentCode sender, + int index, + ) async { + final myPrivateKey = + await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); + final paymentAddress = PaymentAddress.initWithPrivateKey( + myPrivateKey, + sender, + index, + ); + final pair = paymentAddress.getReceiveAddressKeyPair(); + final address = generatePaynymReceivingAddressFromKeyPair( + pair: pair, + derivationIndex: index, + derivePathType: DerivePathType.bip44, + fromPaymentCode: sender, + ); + return address; + } + + Future<void> checkCurrentPaynymReceivingAddressForTransactions( + PaymentCode sender) async { + final address = await currentReceivingPaynymAddress(sender); + final txCount = await _getTxCount(address: address.value); + if (txCount > 0) { + // generate next address and add to db + final nextAddress = await _generatePaynymReceivingAddress( + sender, + address.derivationIndex + 1, + ); + await _db.putAddress(nextAddress); + } + } + + Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() async { + final codes = await getAllPaymentCodesFromNotificationTransactions(); + final List<Future<void>> futures = []; + for (final code in codes) { + futures.add(checkCurrentPaynymReceivingAddressForTransactions(code)); + } + await Future.wait(futures); + } + // generate bip32 payment code root Future<bip32.BIP32> getRootNode({ required List<String> mnemonic, From 9b74f52ce9258ed4db45e8f2fc56c6255ea171a7 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Jan 2023 16:17:26 -0600 Subject: [PATCH 039/123] add receiving address derivation to secure storage --- .../coins/dogecoin/dogecoin_wallet.dart | 2 + .../mixins/paynym_wallet_interface.dart | 72 ++++++++++++++++--- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index f6b13f586..462f030ce 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -1118,6 +1118,8 @@ class DogecoinWallet extends CoinServiceAPI fetchBuildTxData: fetchBuildTxData, refresh: refresh, checkChangeAddressForTransactions: checkChangeAddressForTransactions, + addDerivation: addDerivation, + addDerivations: addDerivations, ); } diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 1d194feb9..57a8e534e 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -54,6 +54,18 @@ mixin PaynymWalletInterface { ) _fetchBuildTxData; late final Future<void> Function() _refresh; late final Future<void> Function() _checkChangeAddressForTransactions; + late final Future<void> Function({ + required int chain, + required String address, + required String pubKey, + required String wif, + required DerivePathType derivePathType, + }) _addDerivation; + late final Future<void> Function({ + required int chain, + required DerivePathType derivePathType, + required Map<String, dynamic> derivationsToAdd, + }) _addDerivations; // initializer void initPaynymWalletInterface({ @@ -87,6 +99,20 @@ mixin PaynymWalletInterface { fetchBuildTxData, required Future<void> Function() refresh, required Future<void> Function() checkChangeAddressForTransactions, + required Future<void> Function({ + required int chain, + required String address, + required String pubKey, + required String wif, + required DerivePathType derivePathType, + }) + addDerivation, + required Future<void> Function({ + required int chain, + required DerivePathType derivePathType, + required Map<String, dynamic> derivationsToAdd, + }) + addDerivations, }) { _walletId = walletId; _walletName = walletName; @@ -103,6 +129,8 @@ mixin PaynymWalletInterface { _fetchBuildTxData = fetchBuildTxData; _refresh = refresh; _checkChangeAddressForTransactions = checkChangeAddressForTransactions; + _addDerivation = addDerivation; + _addDerivations = addDerivations; } // convenience getter @@ -140,7 +168,7 @@ mixin PaynymWalletInterface { index, ); final pair = paymentAddress.getReceiveAddressKeyPair(); - final address = generatePaynymReceivingAddressFromKeyPair( + final address = await generatePaynymReceivingAddressFromKeyPair( pair: pair, derivationIndex: index, derivePathType: DerivePathType.bip44, @@ -704,7 +732,7 @@ mixin PaynymWalletInterface { i, // index to use ); - if (receivingGapCounter < maxUnusedAddressGap) { + if (outgoingGapCounter < maxUnusedAddressGap) { final pair = paymentAddress.getSendAddressKeyPair(); final address = generatePaynymSendAddressFromKeyPair( pair: pair, @@ -717,15 +745,15 @@ mixin PaynymWalletInterface { final count = await _getTxCount(address: address.value); if (count > 0) { - receivingGapCounter++; + outgoingGapCounter++; } else { - receivingGapCounter = 0; + outgoingGapCounter = 0; } } - if (outgoingGapCounter < maxUnusedAddressGap) { + if (receivingGapCounter < maxUnusedAddressGap) { final pair = paymentAddress.getReceiveAddressKeyPair(); - final address = generatePaynymReceivingAddressFromKeyPair( + final address = await generatePaynymReceivingAddressFromKeyPair( pair: pair, derivationIndex: i, derivePathType: DerivePathType.bip44, @@ -736,9 +764,9 @@ mixin PaynymWalletInterface { final count = await _getTxCount(address: address.value); if (count > 0) { - outgoingGapCounter++; + receivingGapCounter++; } else { - outgoingGapCounter = 0; + receivingGapCounter = 0; } } } @@ -803,12 +831,12 @@ mixin PaynymWalletInterface { return address; } - Address generatePaynymReceivingAddressFromKeyPair({ + Future<Address> generatePaynymReceivingAddressFromKeyPair({ required btc_dart.ECPair pair, required int derivationIndex, required DerivePathType derivePathType, required PaymentCode fromPaymentCode, - }) { + }) async { final data = btc_dart.PaymentData(pubkey: pair.publicKey); String addressString; @@ -867,6 +895,30 @@ mixin PaynymWalletInterface { otherData: fromPaymentCode.toString(), ); + final myCode = await getPaymentCode(DerivePathType.bip44); + + final bip32NetworkType = bip32.NetworkType( + wif: _network.wif, + bip32: bip32.Bip32Type( + public: _network.bip32.public, + private: _network.bip32.private, + ), + ); + + final bip32.BIP32 node = bip32.BIP32.fromPrivateKey( + pair.privateKey!, + myCode.getChain(), + bip32NetworkType, + ); + + await _addDerivation( + chain: 0, + address: address.value, + derivePathType: DerivePathType.bip44, + pubKey: Format.uint8listToString(node.publicKey), + wif: node.toWIF(), + ); + return address; } From b76c9e6c6b11b62238432c3e62d18cf60d3f2414 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 10:04:15 -0600 Subject: [PATCH 040/123] isar inspector active in debug mode and add single transaction fetch function --- lib/db/main_db.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/db/main_db.dart b/lib/db/main_db.dart index 413951e37..931fb6665 100644 --- a/lib/db/main_db.dart +++ b/lib/db/main_db.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; @@ -28,7 +29,7 @@ class MainDB { AddressSchema, ], directory: (await StackFileSystem.applicationIsarDirectory()).path, - inspector: false, + inspector: kDebugMode, name: "wallet_data", ); return true; @@ -73,6 +74,10 @@ class MainDB { await isar.transactions.putAll(transactions); }); + Future<Transaction?> getTransaction(String walletId, String txid) async { + return isar.transactions.getByTxidWalletId(txid, walletId); + } + // utxos QueryBuilder<UTXO, UTXO, QAfterWhereClause> getUTXOs(String walletId) => isar.utxos.where().walletIdEqualTo(walletId); From 6d7284d216cc497bc174cba9bcb4dcaa67e73d69 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 10:04:55 -0600 Subject: [PATCH 041/123] do not display incoming notification transaction in ui --- lib/services/coins/dogecoin/dogecoin_wallet.dart | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 462f030ce..142817fbd 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -151,8 +151,16 @@ class DogecoinWallet extends CoinServiceAPI Future<List<isar_models.UTXO>> get utxos => db.getUTXOs(walletId).findAll(); @override - Future<List<isar_models.Transaction>> get transactions => - db.getTransactions(walletId).sortByTimestampDesc().findAll(); + Future<List<isar_models.Transaction>> get transactions => db + .getTransactions(walletId) + .filter() + .not() + .group((q) => q + .subTypeEqualTo(isar_models.TransactionSubType.bip47Notification) + .and() + .typeEqualTo(isar_models.TransactionType.incoming)) + .sortByTimestampDesc() + .findAll(); @override Coin get coin => _coin; From 5159a612713e709e23e9620457ae038984acf3a0 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 10:20:26 -0600 Subject: [PATCH 042/123] block paynym notification utxos --- .../coins/dogecoin/dogecoin_wallet.dart | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 142817fbd..9da638e3d 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -1534,15 +1534,34 @@ class DogecoinWallet extends CoinServiceAPI coin: coin, ); - // todo check here if we should mark as blocked + // fetch stored tx to see if paynym notification tx and block utxo + final storedTx = await db.getTransaction( + walletId, + fetchedUtxoList[i][j]["tx_hash"] as String, + ); + + bool shouldBlock = false; + String? blockReason; + + if (storedTx?.subType == + isar_models.TransactionSubType.bip47Notification && + storedTx?.type == isar_models.TransactionType.incoming) { + // probably safe to assume this is an incoming tx as it is a utxo + // belonging to this wallet. The extra check may be redundant but + // just in case... + + shouldBlock = true; + blockReason = "Incoming paynym notification transaction."; + } + final utxo = isar_models.UTXO( walletId: walletId, txid: txn["txid"] as String, vout: fetchedUtxoList[i][j]["tx_pos"] as int, value: fetchedUtxoList[i][j]["value"] as int, name: "", - isBlocked: false, - blockedReason: null, + isBlocked: shouldBlock, + blockedReason: blockReason, isCoinbase: txn["is_coinbase"] as bool? ?? false, blockHash: txn["blockhash"] as String?, blockHeight: fetchedUtxoList[i][j]["height"] as int?, From 8b071e8774f8c076ff08ab25bbc846b8b57029f8 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 10:21:23 -0600 Subject: [PATCH 043/123] ensure paynym notification address is generated and added to database on restore --- lib/services/coins/dogecoin/dogecoin_wallet.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 9da638e3d..8d675dba9 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -538,6 +538,12 @@ class DogecoinWallet extends CoinServiceAPI ...p2pkhChangeAddressArray, ]); + // generate to ensure notification address is in db before refreshing transactions + await getMyNotificationAddress(DerivePathType.bip44); + + // refresh transactions to pick up any received notification transactions + await _refreshTransactions(); + await _updateUTXOs(); await Future.wait([ From 1d9120419ed4f62f47ccf662b17a738b4e6e4a71 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Fri, 27 Jan 2023 09:22:07 -0700 Subject: [PATCH 044/123] fixed sw default theme color --- lib/main.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 8296d739a..493347263 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -344,12 +344,12 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme> case "oceanBreeze": colorTheme = OceanBreezeColors(); break; - case "light": - colorTheme = LightColors(); - break; case "fruitSorbet": - default: colorTheme = FruitSorbetColors(); + break; + case "light": + default: + colorTheme = LightColors(); } loadingCompleter = Completer(); WidgetsBinding.instance.addObserver(this); From 33660467b114255166de70e1870ba2f13551b894 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 10:22:55 -0600 Subject: [PATCH 045/123] add notification address derivation --- lib/services/mixins/paynym_wallet_interface.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 57a8e534e..f2d89e04a 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -1014,6 +1014,14 @@ mixin PaynymWalletInterface { otherData: paymentCode.toString(), ); + await _addDerivation( + chain: 0, + address: address.value, + derivePathType: DerivePathType.bip44, + pubKey: Format.uint8listToString(node.publicKey), + wif: node.toWIF(), + ); + await _db.putAddress(address); return address; } From 0d775660c79f3fecae68284b3ca9709c5b6f0fbd Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 10:37:15 -0600 Subject: [PATCH 046/123] update featured paynyms --- lib/utilities/featured_paynyms.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/utilities/featured_paynyms.dart b/lib/utilities/featured_paynyms.dart index 5abff9f2a..2a99bc459 100644 --- a/lib/utilities/featured_paynyms.dart +++ b/lib/utilities/featured_paynyms.dart @@ -1,12 +1,12 @@ abstract class FeaturedPaynyms { - // TODO: replace with actual values - static const String samouraiWalletDevFund = - "PM8TJYkuSdYXJnwDBq8ChfinfXv3srxhQrx3eoEwbSw51wMjdo9JJ2DsycwT3gt3zHQ7cV1grvabMmmf1Btj6fY7tgkgSz9B8MZuR3kjYfgMLMURJCXN"; + // TODO: replace with actual value + // static const String samouraiWalletDevFund = + // "PM8TJYkuSdYXJnwDBq8ChfinfXv3srxhQrx3eoEwbSw51wMjdo9JJ2DsycwT3gt3zHQ7cV1grvabMmmf1Btj6fY7tgkgSz9B8MZuR3kjYfgMLMURJCXN"; static const String stackWallet = - "PM8TJYkuSdYXJnwDBq8ChfinfXv3srxhQrx3eoEwbSw51wMjdo9JJ2DsycwT3gt3zHQ7cV1grvabMmmf1Btj6fY7tgkgSz9B8MZuR3kjYfgMLMURJCXN"; + "PM8TJPdEeH3A77h4xJYQeXPWix2W5yAJrzVQ8ggET1n92utnc57FXCoH94Z2wUSJNfGwkX1kNDTCQLkHecVsjQHGkDE8MUyWE4xWJcc1EDDYCeSSBfLL"; static Map<String, String> get featured => { "Stack Wallet": stackWallet, - "Samourai Wallet Dev Fund": samouraiWalletDevFund, + // "Samourai Wallet Dev Fund": samouraiWalletDevFund, }; } From 466e2dd2de85bab28f1b9a1db6c5c9f10966601f Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 10:46:38 -0600 Subject: [PATCH 047/123] raw tx electrumx fetch fix --- lib/electrumx_rpc/electrumx.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/electrumx_rpc/electrumx.dart b/lib/electrumx_rpc/electrumx.dart index c34b760e4..a06cc7365 100644 --- a/lib/electrumx_rpc/electrumx.dart +++ b/lib/electrumx_rpc/electrumx.dart @@ -544,6 +544,10 @@ class ElectrumX { verbose, ], ); + if (!verbose) { + return {"rawtx": response["result"] as String}; + } + return Map<String, dynamic>.from(response["result"] as Map); } catch (e) { rethrow; From ae7163a40f2d50c88b269e9146a2ae2e5e4dd9b0 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 11:19:44 -0600 Subject: [PATCH 048/123] add singel address getter by value --- lib/db/main_db.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/db/main_db.dart b/lib/db/main_db.dart index 931fb6665..53b6397ab 100644 --- a/lib/db/main_db.dart +++ b/lib/db/main_db.dart @@ -48,6 +48,10 @@ class MainDB { await isar.addresses.putAll(addresses); }); + Future<Address?> getAddress(String walletId, String address) async { + return isar.addresses.getByValueWalletId(address, walletId); + } + Future<void> updateAddress(Address oldAddress, Address newAddress) => isar.writeTxn(() async { newAddress.id = oldAddress.id; From 47acad29a5e3070b125157598db6ee62e7fa8c67 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 11:20:12 -0600 Subject: [PATCH 049/123] isar index violation error fix --- lib/services/mixins/paynym_wallet_interface.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index f2d89e04a..4da65408b 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -306,8 +306,13 @@ mixin PaynymWalletInterface { derivePathType: DerivePathType.bip44, toPaymentCode: pCode, ); - await _db.putAddress(address); + final storedAddress = await _db.getAddress(_walletId, address.value); + if (storedAddress == null) { + await _db.putAddress(address); + } else { + await _db.updateAddress(storedAddress, address); + } final count = await _getTxCount(address: address.value); // return address if unused, otherwise continue to next index if (count == 0) { From 2dd8a5b190ca772bff6592f57f789b9028b3b98a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 12:22:30 -0600 Subject: [PATCH 050/123] no such transaction exception --- lib/electrumx_rpc/electrumx.dart | 11 ++++++++++- lib/exceptions/electrumx/no_such_transaction.dart | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 lib/exceptions/electrumx/no_such_transaction.dart diff --git a/lib/electrumx_rpc/electrumx.dart b/lib/electrumx_rpc/electrumx.dart index a06cc7365..a2326345d 100644 --- a/lib/electrumx_rpc/electrumx.dart +++ b/lib/electrumx_rpc/electrumx.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:decimal/decimal.dart'; import 'package:stackwallet/electrumx_rpc/rpc.dart'; +import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/prefs.dart'; import 'package:uuid/uuid.dart'; @@ -132,7 +133,15 @@ class ElectrumX { final response = await _rpcClient!.request(jsonRequestString); if (response["error"] != null) { - throw Exception("JSONRPC response error: $response"); + if (response["error"] + .toString() + .contains("No such mempool or blockchain transaction")) { + throw NoSuchTransactionException( + "No such mempool or blockchain transaction: ${args.first}"); + } + + throw Exception( + "JSONRPC response \ncommand: $command \nargs: $args \nerror: $response"); } currentFailoverIndex = -1; diff --git a/lib/exceptions/electrumx/no_such_transaction.dart b/lib/exceptions/electrumx/no_such_transaction.dart new file mode 100644 index 000000000..a2bea262b --- /dev/null +++ b/lib/exceptions/electrumx/no_such_transaction.dart @@ -0,0 +1,5 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class NoSuchTransactionException extends SWException { + NoSuchTransactionException(super.message); +} From 451edbfc6741531912c2c9fad6c9b96884fa5b1a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 12:49:25 -0600 Subject: [PATCH 051/123] handle dropped mempool/blockchain transactions --- lib/electrumx_rpc/electrumx.dart | 4 +++- .../electrumx/no_such_transaction.dart | 4 +++- .../coins/dogecoin/dogecoin_wallet.dart | 8 +++++++ lib/services/notifications_service.dart | 5 ++++- .../transaction_notification_tracker.dart | 21 +++++++++++++++++++ 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/electrumx_rpc/electrumx.dart b/lib/electrumx_rpc/electrumx.dart index a2326345d..6667c3de5 100644 --- a/lib/electrumx_rpc/electrumx.dart +++ b/lib/electrumx_rpc/electrumx.dart @@ -137,7 +137,9 @@ class ElectrumX { .toString() .contains("No such mempool or blockchain transaction")) { throw NoSuchTransactionException( - "No such mempool or blockchain transaction: ${args.first}"); + "No such mempool or blockchain transaction", + args.first.toString(), + ); } throw Exception( diff --git a/lib/exceptions/electrumx/no_such_transaction.dart b/lib/exceptions/electrumx/no_such_transaction.dart index a2bea262b..0c7bedeae 100644 --- a/lib/exceptions/electrumx/no_such_transaction.dart +++ b/lib/exceptions/electrumx/no_such_transaction.dart @@ -1,5 +1,7 @@ import 'package:stackwallet/exceptions/sw_exception.dart'; class NoSuchTransactionException extends SWException { - NoSuchTransactionException(super.message); + final String txid; + + NoSuchTransactionException(super.message, this.txid); } diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 8d675dba9..073d050c9 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -14,6 +14,7 @@ import 'package:isar/isar.dart'; import 'package:stackwallet/db/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; @@ -611,6 +612,13 @@ class DogecoinWallet extends CoinServiceAPI } } return needsRefresh; + } on NoSuchTransactionException catch (e) { + // TODO: move direct transactions elsewhere + await db.isar.writeTxn(() async { + await db.isar.transactions.deleteByTxidWalletId(e.txid, walletId); + }); + await txTracker.deleteTransaction(e.txid); + return true; } catch (e, s) { Logging.instance.log( "Exception caught in refreshIfThereIsNewData: $e\n$s", diff --git a/lib/services/notifications_service.dart b/lib/services/notifications_service.dart index 2368adeab..2bfe0e12f 100644 --- a/lib/services/notifications_service.dart +++ b/lib/services/notifications_service.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/notification_model.dart'; @@ -169,12 +170,14 @@ class NotificationsService extends ChangeNotifier { } // replaces the current notification with the updated one - add(updatedNotification, true); + await add(updatedNotification, true); } } else { // TODO: check non electrumx coins } } + } on NoSuchTransactionException catch (e, s) { + await _deleteWatchedTxNotification(notification); } catch (e, s) { Logging.instance.log("$e $s", level: LogLevel.Error); } diff --git a/lib/services/transaction_notification_tracker.dart b/lib/services/transaction_notification_tracker.dart index 696465e85..6a2cce2c7 100644 --- a/lib/services/transaction_notification_tracker.dart +++ b/lib/services/transaction_notification_tracker.dart @@ -54,4 +54,25 @@ class TransactionNotificationTracker { key: "notifiedConfirmedTransactions", value: notifiedConfirmedTransactions); } + + Future<void> deleteTransaction(String txid) async { + final notifiedPendingTransactions = DB.instance.get<dynamic>( + boxName: walletId, key: "notifiedPendingTransactions") as Map? ?? + {}; + final notifiedConfirmedTransactions = DB.instance.get<dynamic>( + boxName: walletId, key: "notifiedConfirmedTransactions") as Map? ?? + {}; + + notifiedPendingTransactions.remove(txid); + notifiedConfirmedTransactions.remove(txid); + + await DB.instance.put<dynamic>( + boxName: walletId, + key: "notifiedConfirmedTransactions", + value: notifiedConfirmedTransactions); + await DB.instance.put<dynamic>( + boxName: walletId, + key: "notifiedPendingTransactions", + value: notifiedPendingTransactions); + } } From 04854582ae786c1f23de9372b3df356420db438d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 13:09:58 -0600 Subject: [PATCH 052/123] desktop first start MainDB load fix --- lib/main.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 8296d739a..2a8335110 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -254,6 +254,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme> _desktopHasPassword = await ref.read(storageCryptoHandlerProvider).hasPassword(); } + await MainDB.instance.initMainDB(); } Future<void> load() async { @@ -267,8 +268,6 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme> await loadShared(); } - await MainDB.instance.initMainDB(); - _notificationsService = ref.read(notificationsProvider); _nodeService = ref.read(nodeServiceChangeNotifierProvider); _tradesService = ref.read(tradesServiceProvider); From c8783bb032fb0bf909c9422375a0b2e34132db58 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 13:10:35 -0600 Subject: [PATCH 053/123] ignore duplicate unblinded codes --- lib/services/mixins/paynym_wallet_interface.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 4da65408b..a3b44951f 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -702,7 +702,10 @@ mixin PaynymWalletInterface { transaction: tx, myNotificationAddress: myAddress, ); - if (unBlinded != null) { + if (unBlinded != null && + unBlindedList + .where((e) => e.toString() == unBlinded.toString()) + .isEmpty) { unBlindedList.add(unBlinded); } } From 6094a767d743f28f35461f6f5ac6173aadee1568 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 14:10:23 -0600 Subject: [PATCH 054/123] desktop rescanning navigation fix --- .../sub_widgets/rescanning_dialog.dart | 67 ++++++++++++------- .../wallet_network_settings_view.dart | 12 ++-- 2 files changed, 48 insertions(+), 31 deletions(-) diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart index da39b1017..0435d023b 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart @@ -2,6 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; class RescanningDialog extends StatefulWidget { @@ -21,9 +24,12 @@ class _RescanningDialogState extends State<RescanningDialog> late AnimationController? _spinController; late Animation<double> _spinAnimation; + late final bool isDesktop; + // late final VoidCallback onCancel; @override void initState() { + isDesktop = Util.isDesktop; // onCancel = widget.onCancel; _spinController = AnimationController( @@ -53,33 +59,42 @@ class _RescanningDialogState extends State<RescanningDialog> onWillPop: () async { return false; }, - child: StackDialog( - title: "Rescanning blockchain", - message: "This may take a while. Please do not exit this screen.", - icon: RotationTransition( - turns: _spinAnimation, - child: SvgPicture.asset( - Assets.svg.arrowRotate3, - width: 24, - height: 24, - color: Theme.of(context).extension<StackColors>()!.accentColorDark, - ), + child: ConditionalParent( + condition: isDesktop, + builder: (child) => DesktopDialog( + maxHeight: 200, + maxWidth: 500, + child: child, + ), + child: StackDialog( + title: "Rescanning blockchain", + message: "This may take a while. Please do not exit this screen.", + icon: RotationTransition( + turns: _spinAnimation, + child: SvgPicture.asset( + Assets.svg.arrowRotate3, + width: 24, + height: 24, + color: + Theme.of(context).extension<StackColors>()!.accentColorDark, + ), + ), + // rightButton: TextButton( + // style: Theme.of(context).textButtonTheme.style?.copyWith( + // backgroundColor: MaterialStateProperty.all<Color>( + // CFColors.buttonGray, + // ), + // ), + // child: Text( + // "Cancel", + // style: STextStyles.itemSubtitle12(context), + // ), + // onPressed: () { + // Navigator.of(context).pop(); + // onCancel.call(); + // }, + // ), ), - // rightButton: TextButton( - // style: Theme.of(context).textButtonTheme.style?.copyWith( - // backgroundColor: MaterialStateProperty.all<Color>( - // CFColors.buttonGray, - // ), - // ), - // child: Text( - // "Cancel", - // style: STextStyles.itemSubtitle12(context), - // ), - // onPressed: () { - // Navigator.of(context).pop(); - // onCancel.call(); - // }, - // ), ), ); } diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart index cc552279c..21e0f2d49 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart @@ -76,6 +76,8 @@ class _WalletNetworkSettingsViewState StreamSubscription<dynamic>? _blocksRemainingSubscription; // late StreamSubscription _nodeStatusSubscription; + late final bool isDesktop; + late double _percent; late int _blocksRemaining; bool _advancedIsExpanded = false; @@ -114,7 +116,7 @@ class _WalletNetworkSettingsViewState if (mounted) { // pop rescanning dialog - Navigator.pop(context); + Navigator.of(context, rootNavigator: isDesktop).pop(); // show success await showDialog<dynamic>( @@ -132,7 +134,7 @@ class _WalletNetworkSettingsViewState style: STextStyles.itemSubtitle12(context), ), onPressed: () { - Navigator.of(context).pop(); + Navigator.of(context, rootNavigator: isDesktop).pop(); }, ), ), @@ -143,7 +145,7 @@ class _WalletNetworkSettingsViewState if (mounted) { // pop rescanning dialog - Navigator.pop(context); + Navigator.of(context, rootNavigator: isDesktop).pop(); // show error await showDialog<dynamic>( @@ -162,7 +164,7 @@ class _WalletNetworkSettingsViewState style: STextStyles.itemSubtitle12(context), ), onPressed: () { - Navigator.of(context).pop(); + Navigator.of(context, rootNavigator: isDesktop).pop(); }, ), ), @@ -183,6 +185,7 @@ class _WalletNetworkSettingsViewState @override void initState() { + isDesktop = Util.isDesktop; _currentSyncStatus = widget.initialSyncStatus; // _currentNodeStatus = widget.initialNodeStatus; if (_currentSyncStatus == WalletSyncStatus.synced) { @@ -270,7 +273,6 @@ class _WalletNetworkSettingsViewState @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; - final bool isDesktop = Util.isDesktop; final progressLength = isDesktop ? 430.0 From c7446f1946d3e056dcb101870dc2586bc3059594 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 14:43:00 -0600 Subject: [PATCH 055/123] receiving address fix --- .../mixins/paynym_wallet_interface.dart | 64 ++++++++++++------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index a3b44951f..16d65c6cf 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -140,10 +140,9 @@ mixin PaynymWalletInterface { final address = await _db .getAddresses(_walletId) .filter() - .group((q) => q - .subTypeEqualTo(AddressSubType.paynymReceive) - .and() - .otherDataEqualTo(sender.toString())) + .subTypeEqualTo(AddressSubType.paynymReceive) + .and() + .otherDataEqualTo(sender.toString()) .sortByDerivationIndexDesc() .findFirst(); @@ -160,12 +159,15 @@ mixin PaynymWalletInterface { PaymentCode sender, int index, ) async { - final myPrivateKey = - await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); + final myPrivateKey = await deriveReceivingPrivateKey( + mnemonic: await _getMnemonic(), + index: index, + ); + final paymentAddress = PaymentAddress.initWithPrivateKey( myPrivateKey, sender, - index, + 0, ); final pair = paymentAddress.getReceiveAddressKeyPair(); final address = await generatePaynymReceivingAddressFromKeyPair( @@ -216,6 +218,15 @@ mixin PaynymWalletInterface { return node.privateKey!; } + Future<Uint8List> deriveReceivingPrivateKey({ + required List<String> mnemonic, + required int index, + }) async { + final root = await getRootNode(mnemonic: mnemonic); + final node = root.derivePath(kPaynymDerivePath).derive(index); + return node.privateKey!; + } + /// fetch or generate this wallet's bip47 payment code Future<PaymentCode> getPaymentCode( DerivePathType derivePathType, @@ -722,8 +733,12 @@ mixin PaynymWalletInterface { const maxCount = 2147483647; assert(maxNumberOfIndexesToCheck < maxCount); - final myPrivateKey = - await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); + final mnemonic = await _getMnemonic(); + + final mySendPrivateKey = + await deriveNotificationPrivateKey(mnemonic: mnemonic); + final receivingNode = + (await getRootNode(mnemonic: mnemonic)).derivePath(kPaynymDerivePath); List<Address> addresses = []; int receivingGapCounter = 0; @@ -734,14 +749,13 @@ mixin PaynymWalletInterface { (receivingGapCounter < maxUnusedAddressGap || outgoingGapCounter < maxUnusedAddressGap); i++) { - final paymentAddress = PaymentAddress.initWithPrivateKey( - myPrivateKey, - other, - i, // index to use - ); - if (outgoingGapCounter < maxUnusedAddressGap) { - final pair = paymentAddress.getSendAddressKeyPair(); + final paymentAddressSending = PaymentAddress.initWithPrivateKey( + mySendPrivateKey, + other, + i, // index to use + ); + final pair = paymentAddressSending.getSendAddressKeyPair(); final address = generatePaynymSendAddressFromKeyPair( pair: pair, derivationIndex: i, @@ -753,14 +767,20 @@ mixin PaynymWalletInterface { final count = await _getTxCount(address: address.value); if (count > 0) { - outgoingGapCounter++; - } else { outgoingGapCounter = 0; + } else { + outgoingGapCounter++; } } if (receivingGapCounter < maxUnusedAddressGap) { - final pair = paymentAddress.getReceiveAddressKeyPair(); + final myReceivingPrivateKey = receivingNode.derive(i).privateKey!; + final paymentAddressReceiving = PaymentAddress.initWithPrivateKey( + myReceivingPrivateKey, + other, + 0, + ); + final pair = paymentAddressReceiving.getReceiveAddressKeyPair(); final address = await generatePaynymReceivingAddressFromKeyPair( pair: pair, derivationIndex: i, @@ -772,13 +792,13 @@ mixin PaynymWalletInterface { final count = await _getTxCount(address: address.value); if (count > 0) { - receivingGapCounter++; - } else { receivingGapCounter = 0; + } else { + receivingGapCounter++; } } } - await _db.putAddresses(addresses); + await _db.updateOrPutAddresses(addresses); } Address generatePaynymSendAddressFromKeyPair({ From b09b3d0e1f7aec3354a3f01fe922b2407386f54a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 14:43:38 -0600 Subject: [PATCH 056/123] restore all paynym history function --- lib/services/coins/dogecoin/dogecoin_wallet.dart | 6 ++++++ lib/services/mixins/paynym_wallet_interface.dart | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 073d050c9..2db5ee516 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -545,6 +545,12 @@ class DogecoinWallet extends CoinServiceAPI // refresh transactions to pick up any received notification transactions await _refreshTransactions(); + // restore paynym transactions + await restoreAllHistory( + maxUnusedAddressGap: maxUnusedAddressGap, + maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + ); + await _updateUTXOs(); await Future.wait([ diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 16d65c6cf..ee86b3e79 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -724,6 +724,20 @@ mixin PaynymWalletInterface { return unBlindedList; } + Future<void> restoreAllHistory({ + required int maxUnusedAddressGap, + required int maxNumberOfIndexesToCheck, + }) async { + final codes = await getAllPaymentCodesFromNotificationTransactions(); + final List<Future<void>> futures = []; + for (final code in codes) { + futures.add(restoreHistoryWith( + code, maxUnusedAddressGap, maxNumberOfIndexesToCheck)); + } + + await Future.wait(futures); + } + Future<void> restoreHistoryWith( PaymentCode other, int maxUnusedAddressGap, From d59d25cb04fede317e143c4b377c74805fd94b31 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 14:44:00 -0600 Subject: [PATCH 057/123] add convenience function to add or update a list of addresses --- lib/db/main_db.dart | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/db/main_db.dart b/lib/db/main_db.dart index 53b6397ab..90293171c 100644 --- a/lib/db/main_db.dart +++ b/lib/db/main_db.dart @@ -48,6 +48,27 @@ class MainDB { await isar.addresses.putAll(addresses); }); + Future<void> updateOrPutAddresses(List<Address> addresses) async { + await isar.writeTxn(() async { + for (final address in addresses) { + final storedAddress = await isar.addresses + .getByValueWalletId(address.value, address.walletId); + + if (storedAddress == null) { + await isar.addresses.put(address); + } else { + address.id = storedAddress.id; + await storedAddress.transactions.load(); + final txns = storedAddress.transactions.toList(); + await isar.addresses.delete(storedAddress.id); + await isar.addresses.put(address); + address.transactions.addAll(txns); + await address.transactions.save(); + } + } + }); + } + Future<Address?> getAddress(String walletId, String address) async { return isar.addresses.getByValueWalletId(address, walletId); } From 6c678e577b04d9769b1150bf1f9f8a44f376de6b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 14:44:53 -0600 Subject: [PATCH 058/123] disable whirlpool button --- .../sub_widgets/wallet_navigation_bar.dart | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart index c663b8ba0..6f8438770 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart @@ -62,41 +62,41 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> { child: Column( mainAxisSize: MainAxisSize.min, children: [ - AnimatedOpacity( - opacity: scale, - duration: duration, - child: GestureDetector( - onTap: () {}, - child: Container( - padding: const EdgeInsets.all(16), - width: 146, - decoration: BoxDecoration( - color: - Theme.of(context).extension<StackColors>()!.popupBG, - boxShadow: [ - Theme.of(context) - .extension<StackColors>()! - .standardBoxShadow - ], - borderRadius: BorderRadius.circular( - widget.height / 2.0, - ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Whirlpool", - style: STextStyles.w600_12(context), - ), - ], - ), - ), - ), - ), - const SizedBox( - height: 8, - ), + // AnimatedOpacity( + // opacity: scale, + // duration: duration, + // child: GestureDetector( + // onTap: () {}, + // child: Container( + // padding: const EdgeInsets.all(16), + // width: 146, + // decoration: BoxDecoration( + // color: + // Theme.of(context).extension<StackColors>()!.popupBG, + // boxShadow: [ + // Theme.of(context) + // .extension<StackColors>()! + // .standardBoxShadow + // ], + // borderRadius: BorderRadius.circular( + // widget.height / 2.0, + // ), + // ), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Text( + // "Whirlpool", + // style: STextStyles.w600_12(context), + // ), + // ], + // ), + // ), + // ), + // ), + // const SizedBox( + // height: 8, + // ), AnimatedOpacity( opacity: scale, duration: duration, From 3105c21c3543791751ab4d9fa452673c1d5a1560 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 15:03:03 -0600 Subject: [PATCH 059/123] move paynym interface from doge to btc --- .../coins/bitcoin/bitcoin_wallet.dart | 136 ++++++++++-------- .../coins/dogecoin/dogecoin_wallet.dart | 69 ++++----- 2 files changed, 113 insertions(+), 92 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 82e5f646d..eda84d027 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -13,6 +13,7 @@ import 'package:isar/isar.dart'; import 'package:stackwallet/db/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; @@ -23,6 +24,7 @@ import 'package:stackwallet/services/event_bus/events/global/updated_in_backgrou import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -138,7 +140,7 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { } class BitcoinWallet extends CoinServiceAPI - with WalletCache, WalletDB, ElectrumXParsing { + with WalletCache, WalletDB, ElectrumXParsing, PaynymWalletInterface { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); @@ -178,8 +180,16 @@ class BitcoinWallet extends CoinServiceAPI Future<List<isar_models.UTXO>> get utxos => db.getUTXOs(walletId).findAll(); @override - Future<List<isar_models.Transaction>> get transactions => - db.getTransactions(walletId).sortByTimestampDesc().findAll(); + Future<List<isar_models.Transaction>> get transactions => db + .getTransactions(walletId) + .filter() + .not() + .group((q) => q + .subTypeEqualTo(isar_models.TransactionSubType.bip47Notification) + .and() + .typeEqualTo(isar_models.TransactionType.incoming)) + .sortByTimestampDesc() + .findAll(); @override Future<String> get currentReceivingAddress async => @@ -673,6 +683,18 @@ class BitcoinWallet extends CoinServiceAPI ...p2shChangeAddressArray, ]); + // generate to ensure notification address is in db before refreshing transactions + await getMyNotificationAddress(DerivePathType.bip44); + + // refresh transactions to pick up any received notification transactions + await _refreshTransactions(); + + // restore paynym transactions + await restoreAllHistory( + maxUnusedAddressGap: maxUnusedAddressGap, + maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + ); + await _updateUTXOs(); await Future.wait([ @@ -737,6 +759,13 @@ class BitcoinWallet extends CoinServiceAPI } } return needsRefresh; + } on NoSuchTransactionException catch (e) { + // TODO: move direct transactions elsewhere + await db.isar.writeTxn(() async { + await db.isar.transactions.deleteByTxidWalletId(e.txid, walletId); + }); + await txTracker.deleteTransaction(e.txid); + return true; } catch (e, s) { Logging.instance.log( "Exception caught in refreshIfThereIsNewData: $e\n$s", @@ -906,6 +935,8 @@ class BitcoinWallet extends CoinServiceAPI GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); await _checkCurrentReceivingAddressesForTransactions(); + await checkAllCurrentReceivingPaynymAddressesForTransactions(); + final fetchFuture = _refreshTransactions(); final utxosRefreshFuture = _updateUTXOs(); GlobalEventBus.instance @@ -1264,6 +1295,25 @@ class BitcoinWallet extends CoinServiceAPI _secureStore = secureStore; initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); + initPaynymWalletInterface( + walletId: walletId, + walletName: walletName, + network: _network, + coin: coin, + db: db, + electrumXClient: electrumXClient, + getMnemonic: () => mnemonic, + getChainHeight: () => chainHeight, + getCurrentChangeAddress: () => currentChangeAddress, + estimateTxFee: estimateTxFee, + prepareSend: prepareSend, + getTxCount: getTxCount, + fetchBuildTxData: fetchBuildTxData, + refresh: refresh, + checkChangeAddressForTransactions: _checkChangeAddressForTransactions, + addDerivation: addDerivation, + addDerivations: addDerivations, + ); } @override @@ -1324,62 +1374,11 @@ class BitcoinWallet extends CoinServiceAPI .getAddresses(walletId) .filter() .not() - .typeEqualTo(isar_models.AddressType.unknown) - .and() - .not() .typeEqualTo(isar_models.AddressType.nonWallet) .and() - .group((q) => q - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .or() - .subTypeEqualTo(isar_models.AddressSubType.change)) + .not() + .subTypeEqualTo(isar_models.AddressSubType.nonWallet) .findAll(); - // final List<String> allAddresses = []; - // final receivingAddresses = DB.instance.get<dynamic>( - // boxName: walletId, key: 'receivingAddressesP2WPKH') as List<dynamic>; - // final changeAddresses = DB.instance.get<dynamic>( - // boxName: walletId, key: 'changeAddressesP2WPKH') as List<dynamic>; - // final receivingAddressesP2PKH = DB.instance.get<dynamic>( - // boxName: walletId, key: 'receivingAddressesP2PKH') as List<dynamic>; - // final changeAddressesP2PKH = - // DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2PKH') - // as List<dynamic>; - // final receivingAddressesP2SH = DB.instance.get<dynamic>( - // boxName: walletId, key: 'receivingAddressesP2SH') as List<dynamic>; - // final changeAddressesP2SH = - // DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH') - // as List<dynamic>; - // - // for (var i = 0; i < receivingAddresses.length; i++) { - // if (!allAddresses.contains(receivingAddresses[i])) { - // allAddresses.add(receivingAddresses[i] as String); - // } - // } - // for (var i = 0; i < changeAddresses.length; i++) { - // if (!allAddresses.contains(changeAddresses[i])) { - // allAddresses.add(changeAddresses[i] as String); - // } - // } - // for (var i = 0; i < receivingAddressesP2PKH.length; i++) { - // if (!allAddresses.contains(receivingAddressesP2PKH[i])) { - // allAddresses.add(receivingAddressesP2PKH[i] as String); - // } - // } - // for (var i = 0; i < changeAddressesP2PKH.length; i++) { - // if (!allAddresses.contains(changeAddressesP2PKH[i])) { - // allAddresses.add(changeAddressesP2PKH[i] as String); - // } - // } - // for (var i = 0; i < receivingAddressesP2SH.length; i++) { - // if (!allAddresses.contains(receivingAddressesP2SH[i])) { - // allAddresses.add(receivingAddressesP2SH[i] as String); - // } - // } - // for (var i = 0; i < changeAddressesP2SH.length; i++) { - // if (!allAddresses.contains(changeAddressesP2SH[i])) { - // allAddresses.add(changeAddressesP2SH[i] as String); - // } - // } return allAddresses; } @@ -1754,15 +1753,34 @@ class BitcoinWallet extends CoinServiceAPI coin: coin, ); - // todo check here if we should mark as blocked + // fetch stored tx to see if paynym notification tx and block utxo + final storedTx = await db.getTransaction( + walletId, + fetchedUtxoList[i][j]["tx_hash"] as String, + ); + + bool shouldBlock = false; + String? blockReason; + + if (storedTx?.subType == + isar_models.TransactionSubType.bip47Notification && + storedTx?.type == isar_models.TransactionType.incoming) { + // probably safe to assume this is an incoming tx as it is a utxo + // belonging to this wallet. The extra check may be redundant but + // just in case... + + shouldBlock = true; + blockReason = "Incoming paynym notification transaction."; + } + final utxo = isar_models.UTXO( walletId: walletId, txid: txn["txid"] as String, vout: fetchedUtxoList[i][j]["tx_pos"] as int, value: fetchedUtxoList[i][j]["value"] as int, name: "", - isBlocked: false, - blockedReason: null, + isBlocked: shouldBlock, + blockedReason: blockReason, isCoinbase: txn["is_coinbase"] as bool? ?? false, blockHash: txn["blockhash"] as String?, blockHeight: fetchedUtxoList[i][j]["height"] as int?, diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 2db5ee516..90d2764ac 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -25,7 +25,6 @@ import 'package:stackwallet/services/event_bus/events/global/updated_in_backgrou import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; -import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -127,7 +126,7 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { } class DogecoinWallet extends CoinServiceAPI - with WalletCache, WalletDB, ElectrumXParsing, PaynymWalletInterface { + with WalletCache, WalletDB, ElectrumXParsing { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); final _prefs = Prefs.instance; @@ -539,17 +538,18 @@ class DogecoinWallet extends CoinServiceAPI ...p2pkhChangeAddressArray, ]); - // generate to ensure notification address is in db before refreshing transactions - await getMyNotificationAddress(DerivePathType.bip44); - - // refresh transactions to pick up any received notification transactions - await _refreshTransactions(); - - // restore paynym transactions - await restoreAllHistory( - maxUnusedAddressGap: maxUnusedAddressGap, - maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, - ); + // paynym stuff + // // generate to ensure notification address is in db before refreshing transactions + // await getMyNotificationAddress(DerivePathType.bip44); + // + // // refresh transactions to pick up any received notification transactions + // await _refreshTransactions(); + // + // // restore paynym transactions + // await restoreAllHistory( + // maxUnusedAddressGap: maxUnusedAddressGap, + // maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + // ); await _updateUTXOs(); @@ -790,7 +790,8 @@ class DogecoinWallet extends CoinServiceAPI GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); await _checkCurrentReceivingAddressesForTransactions(); - await checkAllCurrentReceivingPaynymAddressesForTransactions(); + // paynym stuff + // await checkAllCurrentReceivingPaynymAddressesForTransactions(); final fetchFuture = _refreshTransactions(); final utxosRefreshFuture = _updateUTXOs(); @@ -1130,25 +1131,27 @@ class DogecoinWallet extends CoinServiceAPI _secureStore = secureStore; initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); - initPaynymWalletInterface( - walletId: walletId, - walletName: walletName, - network: network, - coin: coin, - db: db, - electrumXClient: electrumXClient, - getMnemonic: () => mnemonic, - getChainHeight: () => chainHeight, - getCurrentChangeAddress: () => currentChangeAddress, - estimateTxFee: estimateTxFee, - prepareSend: prepareSend, - getTxCount: getTxCount, - fetchBuildTxData: fetchBuildTxData, - refresh: refresh, - checkChangeAddressForTransactions: checkChangeAddressForTransactions, - addDerivation: addDerivation, - addDerivations: addDerivations, - ); + + // paynym stuff + // initPaynymWalletInterface( + // walletId: walletId, + // walletName: walletName, + // network: network, + // coin: coin, + // db: db, + // electrumXClient: electrumXClient, + // getMnemonic: () => mnemonic, + // getChainHeight: () => chainHeight, + // getCurrentChangeAddress: () => currentChangeAddress, + // estimateTxFee: estimateTxFee, + // prepareSend: prepareSend, + // getTxCount: getTxCount, + // fetchBuildTxData: fetchBuildTxData, + // refresh: refresh, + // checkChangeAddressForTransactions: checkChangeAddressForTransactions, + // addDerivation: addDerivation, + // addDerivations: addDerivations, + // ); } @override From 39856745258bca471e185a768b42531d293d8b0c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Jan 2023 18:18:58 -0600 Subject: [PATCH 060/123] dirty payment code obfuscation --- .../coins/bitcoin/bitcoin_wallet.dart | 1 + .../mixins/paynym_wallet_interface.dart | 74 ++++++++++++++++--- .../flutter_secure_storage_interface.dart | 18 +++++ 3 files changed, 83 insertions(+), 10 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index eda84d027..83188746e 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1302,6 +1302,7 @@ class BitcoinWallet extends CoinServiceAPI coin: coin, db: db, electrumXClient: electrumXClient, + secureStorage: secureStore, getMnemonic: () => mnemonic, getChainHeight: () => chainHeight, getCurrentChangeAddress: () => currentChangeAddress, diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index ee86b3e79..3a9642cf0 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:math'; import 'dart:typed_data'; import 'package:bip32/bip32.dart' as bip32; @@ -18,6 +19,7 @@ import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:tuple/tuple.dart'; @@ -32,6 +34,7 @@ mixin PaynymWalletInterface { late final Coin _coin; late final MainDB _db; late final ElectrumX _electrumXClient; + late final SecureStorageInterface _secureStorage; // passed in wallet functions late final Future<List<String>> Function() _getMnemonic; @@ -75,6 +78,7 @@ mixin PaynymWalletInterface { required Coin coin, required MainDB db, required ElectrumX electrumXClient, + required SecureStorageInterface secureStorage, required Future<List<String>> Function() getMnemonic, required Future<int> Function() getChainHeight, required Future<String> Function() getCurrentChangeAddress, @@ -120,6 +124,7 @@ mixin PaynymWalletInterface { _coin = coin; _db = db; _electrumXClient = electrumXClient; + _secureStorage = secureStorage; _getMnemonic = getMnemonic; _getChainHeight = getChainHeight; _getCurrentChangeAddress = getCurrentChangeAddress; @@ -137,12 +142,15 @@ mixin PaynymWalletInterface { btc_dart.NetworkType get networkType => _network; Future<Address> currentReceivingPaynymAddress(PaymentCode sender) async { + final key = await lookupKey(sender.toString()); final address = await _db .getAddresses(_walletId) .filter() .subTypeEqualTo(AddressSubType.paynymReceive) .and() - .otherDataEqualTo(sender.toString()) + .otherDataEqualTo(key) + .and() + .otherDataIsNotNull() .sortByDerivationIndexDesc() .findFirst(); @@ -232,8 +240,9 @@ mixin PaynymWalletInterface { DerivePathType derivePathType, ) async { final address = await getMyNotificationAddress(derivePathType); + final pCodeString = await paymentCodeStringByKey(address.otherData!); final paymentCode = PaymentCode.fromPaymentCode( - address.otherData!, + pCodeString!, _network, ); return paymentCode; @@ -287,12 +296,15 @@ mixin PaynymWalletInterface { const maxCount = 2147483647; for (int i = startIndex; i < maxCount; i++) { + final key = await lookupKey(pCode.toString()); final address = await _db .getAddresses(_walletId) .filter() .subTypeEqualTo(AddressSubType.paynymSend) .and() - .otherDataEqualTo(pCode.toString()) + .otherDataEqualTo(key) + .and() + .otherDataIsNotNull() .and() .derivationIndexEqualTo(i) .findFirst(); @@ -311,7 +323,7 @@ mixin PaynymWalletInterface { ).getSendAddressKeyPair(); // add address to local db - final address = generatePaynymSendAddressFromKeyPair( + final address = await generatePaynymSendAddressFromKeyPair( pair: pair, derivationIndex: i, derivePathType: DerivePathType.bip44, @@ -770,7 +782,7 @@ mixin PaynymWalletInterface { i, // index to use ); final pair = paymentAddressSending.getSendAddressKeyPair(); - final address = generatePaynymSendAddressFromKeyPair( + final address = await generatePaynymSendAddressFromKeyPair( pair: pair, derivationIndex: i, derivePathType: DerivePathType.bip44, @@ -815,12 +827,12 @@ mixin PaynymWalletInterface { await _db.updateOrPutAddresses(addresses); } - Address generatePaynymSendAddressFromKeyPair({ + Future<Address> generatePaynymSendAddressFromKeyPair({ required btc_dart.ECPair pair, required int derivationIndex, required DerivePathType derivePathType, required PaymentCode toPaymentCode, - }) { + }) async { final data = btc_dart.PaymentData(pubkey: pair.publicKey); String addressString; @@ -867,7 +879,7 @@ mixin PaynymWalletInterface { derivationIndex: derivationIndex, type: AddressType.nonWallet, subType: AddressSubType.paynymSend, - otherData: toPaymentCode.toString(), + otherData: await storeCode(toPaymentCode.toString()), ); return address; @@ -934,7 +946,7 @@ mixin PaynymWalletInterface { derivationIndex: derivationIndex, type: addrType, subType: AddressSubType.paynymReceive, - otherData: fromPaymentCode.toString(), + otherData: await storeCode(fromPaymentCode.toString()), ); final myCode = await getPaymentCode(DerivePathType.bip44); @@ -1053,7 +1065,7 @@ mixin PaynymWalletInterface { derivationIndex: 0, type: type, subType: AddressSubType.paynymNotification, - otherData: paymentCode.toString(), + otherData: await storeCode(paymentCode.toString()), ); await _addDerivation( @@ -1068,4 +1080,46 @@ mixin PaynymWalletInterface { return address; } } + + /// look up a key that corresponds to a payment code string + Future<String?> lookupKey(String paymentCodeString) async { + final keys = + (await _secureStorage.keys).where((e) => e.startsWith(kPCodeKeyPrefix)); + for (final key in keys) { + final value = await _secureStorage.read(key: key); + if (value == paymentCodeString) { + return key; + } + } + return null; + } + + /// fetch a payment code string + Future<String?> paymentCodeStringByKey(String key) async { + final value = await _secureStorage.read(key: key); + return value; + } + + /// store payment code string and return the generated key used + Future<String> storeCode(String paymentCodeString) async { + final key = _generateKey(); + await _secureStorage.write(key: key, value: paymentCodeString); + return key; + } + + /// generate a new payment code string storage key + String _generateKey() { + final bytes = _randomBytes(24); + return "$kPCodeKeyPrefix${bytes.toHex}"; + } + + // https://github.com/AaronFeickert/stack_wallet_backup/blob/master/lib/secure_storage.dart#L307-L311 + /// Generate cryptographically-secure random bytes + Uint8List _randomBytes(int n) { + final Random rng = Random.secure(); + return Uint8List.fromList( + List<int>.generate(n, (_) => rng.nextInt(0xFF + 1))); + } } + +const String kPCodeKeyPrefix = "pCode_key_"; diff --git a/lib/utilities/flutter_secure_storage_interface.dart b/lib/utilities/flutter_secure_storage_interface.dart index 539f17847..16fa98760 100644 --- a/lib/utilities/flutter_secure_storage_interface.dart +++ b/lib/utilities/flutter_secure_storage_interface.dart @@ -46,6 +46,8 @@ abstract class SecureStorageInterface { MacOsOptions? mOptions, WindowsOptions? wOptions, }); + + Future<List<String>> get keys; } class DesktopSecureStore { @@ -110,6 +112,10 @@ class DesktopSecureStore { await isar.encryptedStringValues.deleteByKey(key); }); } + + Future<List<String>> get keys async { + return await isar.encryptedStringValues.where().keyProperty().findAll(); + } } /// all *Options params ignored on desktop @@ -229,6 +235,15 @@ class SecureStorageWrapper implements SecureStorageInterface { ); } } + + @override + Future<List<String>> get keys async { + if (_isDesktop) { + return (_store as DesktopSecureStore).keys; + } else { + return (await (_store as FlutterSecureStorage).readAll()).keys.toList(); + } + } } // Mock class for testing purposes @@ -305,4 +320,7 @@ class FakeSecureStorage implements SecureStorageInterface { @override dynamic get store => throw UnimplementedError(); + + @override + Future<List<String>> get keys => Future(() => _store.keys.toList()); } From d4cbf035fee48c62f68c6bc3d54099d4a55d009f Mon Sep 17 00:00:00 2001 From: Diego Salazar <diego@cypherstack.com> Date: Fri, 27 Jan 2023 20:13:20 -0700 Subject: [PATCH 061/123] Update pubspec.yaml --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index e4438d113..2e3a80f77 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.35+112 +version: 1.5.36+113 environment: sdk: ">=2.17.0 <3.0.0" From 85d69c0cb29330e46c559bd2f070e5e93a0e4203 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 08:28:14 -0600 Subject: [PATCH 062/123] check all outputs for potential notification tx --- lib/services/mixins/electrum_x_parsing.dart | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index 23be3d80d..c0b572b20 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -189,14 +189,16 @@ mixin ElectrumXParsing { TransactionSubType txSubType = TransactionSubType.none; if (this is PaynymWalletInterface && outs.length > 1 && ins.isNotEmpty) { - List<String>? scriptChunks = outs[1].scriptPubKeyAsm?.split(" "); - if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { - final blindedPaymentCode = scriptChunks![1]; - final bytes = blindedPaymentCode.fromHex; + for (int i = 0; i < outs.length; i++) { + List<String>? scriptChunks = outs[i].scriptPubKeyAsm?.split(" "); + if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { + final blindedPaymentCode = scriptChunks![1]; + final bytes = blindedPaymentCode.fromHex; - // https://en.bitcoin.it/wiki/BIP_0047#Sending - if (bytes.length == 80 && bytes.first == 1) { - txSubType = TransactionSubType.bip47Notification; + // https://en.bitcoin.it/wiki/BIP_0047#Sending + if (bytes.length == 80 && bytes.first == 1) { + txSubType = TransactionSubType.bip47Notification; + } } } } From 17cbc390e4f90ce7d97ca4692b6d42d8003a7130 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 08:28:54 -0600 Subject: [PATCH 063/123] pass in correct values --- .../coins/bitcoin/bitcoin_wallet.dart | 2 ++ .../mixins/paynym_wallet_interface.dart | 20 ++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 83188746e..1f32a945a 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1314,6 +1314,8 @@ class BitcoinWallet extends CoinServiceAPI checkChangeAddressForTransactions: _checkChangeAddressForTransactions, addDerivation: addDerivation, addDerivations: addDerivations, + dustLimitP2PKH: DUST_LIMIT_P2PKH, + minConfirms: MINIMUM_CONFIRMATIONS, ); } diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 3a9642cf0..2292f3ec5 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -15,7 +15,6 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; @@ -35,6 +34,8 @@ mixin PaynymWalletInterface { late final MainDB _db; late final ElectrumX _electrumXClient; late final SecureStorageInterface _secureStorage; + late final int _dustLimitP2PKH; + late final int _minConfirms; // passed in wallet functions late final Future<List<String>> Function() _getMnemonic; @@ -79,6 +80,8 @@ mixin PaynymWalletInterface { required MainDB db, required ElectrumX electrumXClient, required SecureStorageInterface secureStorage, + required int dustLimitP2PKH, + required int minConfirms, required Future<List<String>> Function() getMnemonic, required Future<int> Function() getChainHeight, required Future<String> Function() getCurrentChangeAddress, @@ -125,6 +128,8 @@ mixin PaynymWalletInterface { _db = db; _electrumXClient = electrumXClient; _secureStorage = secureStorage; + _dustLimitP2PKH = dustLimitP2PKH; + _minConfirms = minConfirms; _getMnemonic = getMnemonic; _getChainHeight = getChainHeight; _getCurrentChangeAddress = getCurrentChangeAddress; @@ -353,7 +358,7 @@ mixin PaynymWalletInterface { int additionalOutputs = 0, List<UTXO>? utxos, }) async { - const amountToSend = DUST_LIMIT; + final amountToSend = _dustLimitP2PKH; final List<UTXO> availableOutputs = utxos ?? await _db.getUTXOs(_walletId).findAll(); final List<UTXO> spendableOutputs = []; @@ -362,8 +367,8 @@ mixin PaynymWalletInterface { // Build list of spendable outputs and totaling their satoshi amount for (var i = 0; i < availableOutputs.length; i++) { if (availableOutputs[i].isBlocked == false && - availableOutputs[i].isConfirmed( - await _getChainHeight(), MINIMUM_CONFIRMATIONS) == + availableOutputs[i] + .isConfirmed(await _getChainHeight(), _minConfirms) == true) { spendableOutputs.add(availableOutputs[i]); spendableSatoshiValue += availableOutputs[i].value; @@ -440,13 +445,13 @@ mixin PaynymWalletInterface { feeForWithChange = vSizeForWithChange * 1000; } - if (satoshisBeingUsed - amountToSend > feeForNoChange + DUST_LIMIT) { + if (satoshisBeingUsed - amountToSend > feeForNoChange + _dustLimitP2PKH) { // try to add change output due to "left over" amount being greater than // the estimated fee + the dust limit int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; // check estimates are correct and build notification tx - if (changeAmount >= DUST_LIMIT && + if (changeAmount >= _dustLimitP2PKH && satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { final txn = await _createNotificationTx( targetPaymentCodeString: targetPaymentCodeString, @@ -572,7 +577,8 @@ mixin PaynymWalletInterface { ); // todo: modify address once segwit support is in our bip47 - txb.addOutput(targetPaymentCode.notificationAddressP2PKH(), DUST_LIMIT); + txb.addOutput( + targetPaymentCode.notificationAddressP2PKH(), _dustLimitP2PKH); txb.addOutput(opReturnScript, 0); // TODO: add possible change output and mark output as dangerous From 6e54ddec865843fb0674bf11e84d8051add5dacd Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 09:13:30 -0600 Subject: [PATCH 064/123] wallet bottom nav bar fixes --- .../sub_widgets/wallet_navigation_bar.dart | 117 +++++++++--------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart index a50c7bb3c..4e6be9e97 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart @@ -360,62 +360,6 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> { ), ), ), - if (ref.watch(walletsChangeNotifierProvider.select((value) => - value.getManager(widget.walletId).hasPaynymSupport))) - RawMaterialButton( - constraints: const BoxConstraints( - minWidth: 66, - ), - onPressed: () { - if (scale == 0) { - setState(() { - scale = 1; - }); - } else if (scale == 1) { - setState(() { - scale = 0; - }); - } - }, - splashColor: - Theme.of(context).extension<StackColors>()!.highlight, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - widget.height / 2.0, - ), - ), - child: Container( - color: Colors.transparent, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 2.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Spacer(), - const SizedBox( - height: 2, - ), - SvgPicture.asset( - Assets.svg.bars, - width: 20, - height: 20, - ), - const SizedBox( - height: 6, - ), - Text( - "More", - style: STextStyles.buttonSmall(context), - ), - const Spacer(), - ], - ), - ), - ), - ), - const SizedBox( - width: 12, - ), if (widget.coin.hasBuySupport) RawMaterialButton( constraints: const BoxConstraints( @@ -455,10 +399,65 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> { ), ), ), - if (widget.coin.hasBuySupport) - const SizedBox( - width: 12, + if (ref.watch(walletsChangeNotifierProvider.select((value) => + value.getManager(widget.walletId).hasPaynymSupport))) + RawMaterialButton( + constraints: const BoxConstraints( + minWidth: 66, + ), + onPressed: () { + if (scale == 0) { + setState(() { + scale = 1; + }); + } else if (scale == 1) { + setState(() { + scale = 0; + }); + } + }, + splashColor: + Theme.of(context).extension<StackColors>()!.highlight, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + widget.height / 2.0, + ), + ), + child: Container( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 2.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer(), + const SizedBox( + height: 2, + ), + SvgPicture.asset( + Assets.svg.bars, + width: 20, + height: 20, + color: Theme.of(context) + .extension<StackColors>()! + .bottomNavIconIcon, + ), + const SizedBox( + height: 6, + ), + Text( + "More", + style: STextStyles.buttonSmall(context), + ), + const Spacer(), + ], + ), + ), + ), ), + const SizedBox( + width: 12, + ), ], ), ), From a41f80ac557d78a19432cae09c1c4adfc48ea65c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 11:06:28 -0600 Subject: [PATCH 065/123] add height change notify --- lib/services/coins/bitcoin/bitcoin_wallet.dart | 8 ++++++++ lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 8 ++++++++ lib/services/coins/dogecoin/dogecoin_wallet.dart | 8 ++++++++ lib/services/coins/epiccash/epiccash_wallet.dart | 8 ++++++++ lib/services/coins/firo/firo_wallet.dart | 8 ++++++++ lib/services/coins/litecoin/litecoin_wallet.dart | 8 ++++++++ lib/services/coins/namecoin/namecoin_wallet.dart | 8 ++++++++ lib/services/coins/particl/particl_wallet.dart | 8 ++++++++ 8 files changed, 64 insertions(+) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 1f32a945a..32c24686b 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -251,6 +251,14 @@ class BitcoinWallet extends CoinServiceAPI final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 969eb1815..a84c8f09e 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -217,6 +217,14 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 90d2764ac..7dc3bc6f9 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -226,6 +226,14 @@ class DogecoinWallet extends CoinServiceAPI final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index 86ed2979b..d6505889b 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -1416,6 +1416,14 @@ class EpicCashWallet extends CoinServiceAPI }); await updateCachedChainHeight(latestHeight!); + if (latestHeight! > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return latestHeight!; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index ec63db186..7758d4e0c 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -4897,6 +4897,14 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index be93d478f..779a9ba54 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -241,6 +241,14 @@ class LitecoinWallet extends CoinServiceAPI final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 2cf0e8ef5..f074ca0ef 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -236,6 +236,14 @@ class NamecoinWallet extends CoinServiceAPI final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 4f822d87a..e4e419892 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -231,6 +231,14 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", From 225aec176306dacf91770b5abd2751c8930463d0 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 12:03:23 -0600 Subject: [PATCH 066/123] update ui transaction state fix --- .../sub_widgets/transactions_list.dart | 29 +++++++++---------- .../all_transactions_view.dart | 8 +++-- .../transaction_details_view.dart | 4 +-- .../dogecoin/current_height_provider.dart | 6 ---- lib/widgets/transaction_card.dart | 4 +-- 5 files changed, 23 insertions(+), 28 deletions(-) delete mode 100644 lib/providers/blockchain/dogecoin/current_height_provider.dart diff --git a/lib/pages/wallet_view/sub_widgets/transactions_list.dart b/lib/pages/wallet_view/sub_widgets/transactions_list.dart index 71f56ccad..360b3028b 100644 --- a/lib/pages/wallet_view/sub_widgets/transactions_list.dart +++ b/lib/pages/wallet_view/sub_widgets/transactions_list.dart @@ -5,7 +5,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/pages/exchange_view/trade_details_view.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart'; -import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart'; import 'package:stackwallet/providers/global/trades_service_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/route_generator.dart'; @@ -85,7 +84,13 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { children: [ TransactionCard( // this may mess with combined firo transactions - key: Key(tx.txid + tx.type.name + tx.address.value.toString()), // + key: Key(tx.txid + + tx.type.name + + tx.address.value.toString() + + ref + .watch(widget.managerProvider + .select((value) => value.currentHeight)) + .toString()), // transaction: tx, walletId: widget.walletId, ), @@ -180,7 +185,13 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { ), child: TransactionCard( // this may mess with combined firo transactions - key: Key(tx.txid + tx.type.name + tx.address.value.toString()), // + key: Key(tx.txid + + tx.type.name + + tx.address.value.toString() + + ref + .watch(widget.managerProvider + .select((value) => value.currentHeight)) + .toString()), // transaction: tx, walletId: widget.walletId, ), @@ -188,13 +199,6 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { } } - void updateHeightProvider(Manager manager) { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - ref.read(currentHeightProvider(manager.coin).state).state = - manager.currentHeight; - }); - } - @override void initState() { managerProvider = widget.managerProvider; @@ -203,14 +207,9 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { @override Widget build(BuildContext context) { - // final managerProvider = ref - // .watch(walletsChangeNotifierProvider) - // .getManagerProvider(widget.walletId); - final manager = ref.watch(walletsChangeNotifierProvider .select((value) => value.getManager(widget.walletId))); - updateHeightProvider(manager); return FutureBuilder( future: manager.transactions, builder: (fbContext, AsyncSnapshot<List<Transaction>> snapshot) { diff --git a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart index 6ebb5bd1c..c9ba6181b 100644 --- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart +++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart @@ -10,7 +10,6 @@ import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart'; -import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart'; import 'package:stackwallet/providers/global/address_book_service_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/ui/transaction_filter_provider.dart'; @@ -131,7 +130,9 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> { // check if address book name contains contains |= contacts .where((e) => - e.addresses.where((a) => a.address == tx.address).isNotEmpty && + e.addresses + .where((a) => a.address == tx.address.value?.value) + .isNotEmpty && e.name.toLowerCase().contains(keyword)) .isNotEmpty; @@ -853,7 +854,8 @@ class _DesktopTransactionCardRowState prefix = ""; } - final currentHeight = ref.watch(currentHeightProvider(coin).state).state; + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); return Material( color: Theme.of(context).extension<StackColors>()!.popupBG, diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index f2755f547..af82a250d 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -11,7 +11,6 @@ import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/dialogs/cancelling_transaction_progress_dialog.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart'; import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; -import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart'; import 'package:stackwallet/providers/global/address_book_service_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'; @@ -298,7 +297,8 @@ class _TransactionDetailsViewState @override Widget build(BuildContext context) { - final currentHeight = ref.watch(currentHeightProvider(coin).state).state; + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); return ConditionalParent( condition: !isDesktop, diff --git a/lib/providers/blockchain/dogecoin/current_height_provider.dart b/lib/providers/blockchain/dogecoin/current_height_provider.dart deleted file mode 100644 index 22b6711db..000000000 --- a/lib/providers/blockchain/dogecoin/current_height_provider.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:dart_numerics/dart_numerics.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; - -final currentHeightProvider = - StateProvider.family<int, Coin>((ref, coin) => int64MaxValue); diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart index 031234142..1b19a2380 100644 --- a/lib/widgets/transaction_card.dart +++ b/lib/widgets/transaction_card.dart @@ -6,7 +6,6 @@ import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; -import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -121,7 +120,8 @@ class _TransactionCardState extends ConsumerState<TransactionCard> { } } - final currentHeight = ref.watch(currentHeightProvider(coin).state).state; + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); return Material( color: Theme.of(context).extension<StackColors>()!.popupBG, From bed518d061a49b1f80b27aaa3e5574705d11cf42 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 13:40:40 -0600 Subject: [PATCH 067/123] ensure fiat amount validation updates on fiat type changed --- lib/pages/buy_view/buy_form.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 3ec462ca7..a882c1475 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -122,12 +122,12 @@ class _BuyFormState extends ConsumerState<BuyForm> { setState(() { _amountOutOfRangeErrorString = "Invalid amount"; }); - } else if (value > maxFiat) { + } else if (value > maxFiat && buyWithFiat) { setState(() { _amountOutOfRangeErrorString = "Maximum amount: ${maxFiat.toStringAsFixed(2)}"; }); - } else if (value < minFiat) { + } else if (value < minFiat && buyWithFiat) { setState(() { _amountOutOfRangeErrorString = "Minimum amount: ${minFiat.toStringAsFixed(2)}"; @@ -280,6 +280,7 @@ class _BuyFormState extends ConsumerState<BuyForm> { minFiat = fiat.minAmount != minFiat ? fiat.minAmount : minFiat; maxFiat = fiat.maxAmount != maxFiat ? fiat.maxAmount : maxFiat; }); + validateAmount(); }, ); } From 13721df803bfbc1a75d02f45602fdfe8ad2e8c83 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 13:42:19 -0600 Subject: [PATCH 068/123] ensure fiat amount validation updates on use fiat amount selected --- lib/pages/buy_view/buy_form.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index a882c1475..a46238188 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -958,6 +958,7 @@ class _BuyFormState extends ConsumerState<BuyForm> { setState(() { buyWithFiat = !buyWithFiat; }); + validateAmount(); }, ) ], From 4f58483e82223e34b2356e5bd2bc2c27f33979c3 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 14:08:21 -0600 Subject: [PATCH 069/123] show min/max crypto amounts returned by simplex api on quote request --- lib/pages/buy_view/buy_form.dart | 49 ++++++++++++----------- lib/services/buy/buy_response.dart | 6 ++- lib/services/buy/simplex/simplex_api.dart | 21 ++++++++-- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index a46238188..051afcf71 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -531,25 +531,25 @@ class _BuyFormState extends ConsumerState<BuyForm> { } } else { // Error; probably amount out of bounds - String errorMessage = "${quoteResponse.exception?.errorMessage}"; - if (errorMessage.contains('must be between')) { - errorMessage = errorMessage.substring( - errorMessage.indexOf('getQuote exception: ') + 20, - errorMessage.indexOf(", value: null")); - _BuyFormState.boundedCryptoTicker = errorMessage.substring( - errorMessage.indexOf('The ') + 4, - errorMessage.indexOf(' amount must be between')); - _BuyFormState.minCrypto = Decimal.parse(errorMessage.substring( - errorMessage.indexOf('must be between ') + 16, - errorMessage.indexOf(' and '))); - _BuyFormState.maxCrypto = Decimal.parse(errorMessage.substring( - errorMessage.indexOf("$minCrypto and ") + "$minCrypto and ".length, - errorMessage.length)); - if (Decimal.parse(_buyAmountController.text) > - _BuyFormState.maxCrypto) { - _buyAmountController.text = _BuyFormState.maxCrypto.toString(); - } - } + // String errorMessage = "${quoteResponse.exception?.errorMessage}"; + // if (errorMessage.contains('must be between')) { + // errorMessage = errorMessage.substring( + // errorMessage.indexOf('getQuote exception: ') + 20, + // errorMessage.indexOf(", value: null")); + // _BuyFormState.boundedCryptoTicker = errorMessage.substring( + // errorMessage.indexOf('The ') + 4, + // errorMessage.indexOf(' amount must be between')); + // _BuyFormState.minCrypto = Decimal.parse(errorMessage.substring( + // errorMessage.indexOf('must be between ') + 16, + // errorMessage.indexOf(' and '))); + // _BuyFormState.maxCrypto = Decimal.parse(errorMessage.substring( + // errorMessage.indexOf("$minCrypto and ") + "$minCrypto and ".length, + // errorMessage.length)); + // if (Decimal.parse(_buyAmountController.text) > + // _BuyFormState.maxCrypto) { + // _buyAmountController.text = _BuyFormState.maxCrypto.toString(); + // } + // } await showDialog<dynamic>( context: context, barrierDismissible: true, @@ -571,7 +571,7 @@ class _BuyFormState extends ConsumerState<BuyForm> { height: 24, ), Text( - errorMessage, + quoteResponse.exception!.errorMessage, style: STextStyles.smallMed14(context), ), const SizedBox( @@ -633,10 +633,11 @@ class _BuyFormState extends ConsumerState<BuyForm> { level: LogLevel.Warning, ); return BuyResponse( - exception: BuyException( - response.toString(), - BuyExceptionType.generic, - ), + exception: response.exception ?? + BuyException( + response.toString(), + BuyExceptionType.generic, + ), ); } } diff --git a/lib/services/buy/buy_response.dart b/lib/services/buy/buy_response.dart index 3198d0a19..6510ece4c 100644 --- a/lib/services/buy/buy_response.dart +++ b/lib/services/buy/buy_response.dart @@ -1,4 +1,8 @@ -enum BuyExceptionType { generic, serializeResponseError } +enum BuyExceptionType { + generic, + serializeResponseError, + cryptoAmountOutOfRange, +} class BuyException implements Exception { String errorMessage; diff --git a/lib/services/buy/simplex/simplex_api.dart b/lib/services/buy/simplex/simplex_api.dart index 4060567f0..85b4d5d9e 100644 --- a/lib/services/buy/simplex/simplex_api.dart +++ b/lib/services/buy/simplex/simplex_api.dart @@ -210,7 +210,20 @@ class SimplexAPI { BuyResponse<SimplexQuote> _parseQuote(dynamic jsonArray) { try { - String cryptoAmount = "${jsonArray['digital_money']['amount']}"; + // final Map<String, dynamic> lol = + // Map<String, dynamic>.from(jsonArray as Map); + + String? cryptoAmount = jsonArray['digital_money']?['amount'] as String?; + + if (cryptoAmount == null) { + String error = jsonArray['error'] as String; + return BuyResponse( + exception: BuyException( + error, + BuyExceptionType.cryptoAmountOutOfRange, + ), + ); + } SimplexQuote quote = jsonArray['quote'] as SimplexQuote; final SimplexQuote _quote = SimplexQuote( @@ -277,9 +290,9 @@ class SimplexAPI { } final jsonArray = jsonDecode(res.body); // TODO check if valid json if (jsonArray.containsKey('error') as bool) { - if (jsonArray['error'] == true || jsonArray['error'] == 'true') { - throw Exception(jsonArray['message']); - } + if (jsonArray['error'] == true || jsonArray['error'] == 'true') { + throw Exception(jsonArray['message']); + } } SimplexOrder _order = SimplexOrder( From 1f7bd41d8eb23dc0039432941279fccf49151c6f Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 14:15:44 -0600 Subject: [PATCH 070/123] update tests mock calls --- test/widget_tests/transaction_card_test.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/widget_tests/transaction_card_test.dart b/test/widget_tests/transaction_card_test.dart index 0ab7e4477..84b6372d5 100644 --- a/test/widget_tests/transaction_card_test.dart +++ b/test/widget_tests/transaction_card_test.dart @@ -80,6 +80,8 @@ void main() { when(wallets.getManager("wallet-id")) .thenAnswer((realInvocation) => Manager(wallet)); + + when(wallet.storedChainHeight).thenAnswer((_) => 6000000); // await tester.pumpWidget( ProviderScope( @@ -173,6 +175,7 @@ void main() { .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00)); when(wallet.coin).thenAnswer((_) => Coin.firo); + when(wallet.storedChainHeight).thenAnswer((_) => 6000000); when(wallets.getManager("wallet-id")) .thenAnswer((realInvocation) => Manager(wallet)); @@ -271,6 +274,8 @@ void main() { when(wallets.getManager("wallet-id")) .thenAnswer((realInvocation) => Manager(wallet)); + when(wallet.storedChainHeight).thenAnswer((_) => 6000000); + await tester.pumpWidget( ProviderScope( overrides: [ @@ -358,6 +363,8 @@ void main() { when(wallets.getManager("wallet id")) .thenAnswer((realInvocation) => Manager(wallet)); + when(wallet.storedChainHeight).thenAnswer((_) => 6000000); + mockingjay .when(() => navigator.pushNamed("/transactionDetails", arguments: Tuple3(tx, Coin.firo, "wallet id"))) @@ -395,6 +402,7 @@ void main() { verify(mockPrefs.currency).called(2); verify(mockLocaleService.locale).called(4); verify(wallet.coin.ticker).called(2); + verify(wallet.storedChainHeight).called(2); verifyNoMoreInteractions(wallet); verifyNoMoreInteractions(mockLocaleService); From 29bf67b2ce1611b9c5c3646c88e094ab15f8ad69 Mon Sep 17 00:00:00 2001 From: Diego Salazar <diego@cypherstack.com> Date: Mon, 30 Jan 2023 14:18:45 -0700 Subject: [PATCH 071/123] Update pubspec.yaml --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 2e3a80f77..49574720d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.36+113 +version: 1.5.36+114 environment: sdk: ">=2.17.0 <3.0.0" From 69435f48079db2c196fcee66b26db399e319910c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 15:34:21 -0600 Subject: [PATCH 072/123] rename and fix text button style update bug --- .../subviews/add_address_book_entry_view.dart | 4 +- .../subviews/contact_details_view.dart | 2 +- lib/pages/buy_view/buy_form.dart | 4 +- .../exchange_step_views/step_2_view.dart | 4 +- .../exchange_view/trade_details_view.dart | 2 +- lib/pages/paynym/dialogs/paynym_qr_popup.dart | 2 +- .../subwidgets/desktop_paynym_details.dart | 2 +- lib/pages/receive_view/receive_view.dart | 2 +- lib/pages/send_view/send_view.dart | 2 +- .../global_settings_view/about_view.dart | 2 +- .../advanced_views/debug_view.dart | 4 +- .../manage_nodes_views/coin_nodes_view.dart | 2 +- .../stack_backup_views/auto_backup_view.dart | 4 +- .../wallet_network_settings_view.dart | 4 +- .../transaction_details_view.dart | 2 +- lib/pages/wallet_view/wallet_view.dart | 2 +- .../wallets_view/sub_widgets/all_wallets.dart | 2 +- .../subwidgets/desktop_address_card.dart | 4 +- .../subwidgets/desktop_contact_details.dart | 2 +- .../subwidgets/desktop_step_2.dart | 4 +- .../subwidgets/desktop_choose_from_stack.dart | 2 +- .../subwidgets/desktop_trade_history.dart | 2 +- .../desktop_favorite_wallets.dart | 2 +- .../my_stack_view/my_wallets.dart | 2 +- .../sub_widgets/contact_list_item.dart | 2 +- .../wallet_view/sub_widgets/desktop_send.dart | 2 +- .../recent_desktop_transactions.dart | 2 +- .../password/desktop_login_view.dart | 2 +- .../backup_and_restore_settings.dart | 2 +- .../settings_menu/desktop_about_view.dart | 2 +- .../custom_buttons/blue_text_button.dart | 55 ++++++++++++++----- lib/widgets/node_card.dart | 4 +- 32 files changed, 81 insertions(+), 54 deletions(-) diff --git a/lib/pages/address_book_views/subviews/add_address_book_entry_view.dart b/lib/pages/address_book_views/subviews/add_address_book_entry_view.dart index 36191e0b7..caffb65c7 100644 --- a/lib/pages/address_book_views/subviews/add_address_book_entry_view.dart +++ b/lib/pages/address_book_views/subviews/add_address_book_entry_view.dart @@ -584,7 +584,7 @@ class _AddAddressBookEntryViewState "Address ${i + 1}", style: STextStyles.smallMed12(context), ), - BlueTextButton( + CustomTextButton( onTap: () { _removeForm(forms[i].id); }, @@ -601,7 +601,7 @@ class _AddAddressBookEntryViewState const SizedBox( height: 16, ), - BlueTextButton( + CustomTextButton( onTap: () { _addForm(); scrollController.animateTo( diff --git a/lib/pages/address_book_views/subviews/contact_details_view.dart b/lib/pages/address_book_views/subviews/contact_details_view.dart index ff15420ca..4f417c9a5 100644 --- a/lib/pages/address_book_views/subviews/contact_details_view.dart +++ b/lib/pages/address_book_views/subviews/contact_details_view.dart @@ -311,7 +311,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> { "Addresses", style: STextStyles.itemSubtitle(context), ), - BlueTextButton( + CustomTextButton( text: "Add new", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 051afcf71..30bd05106 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -953,7 +953,7 @@ class _BuyFormState extends ConsumerState<BuyForm> { Theme.of(context).extension<StackColors>()!.textDark3, ), ), - BlueTextButton( + CustomTextButton( text: buyWithFiat ? "Use crypto amount" : "Use fiat amount", onTap: () { setState(() { @@ -1129,7 +1129,7 @@ class _BuyFormState extends ConsumerState<BuyForm> { ), ), if (isStackCoin(selectedCrypto?.ticker)) - BlueTextButton( + CustomTextButton( text: "Choose from stack", onTap: () { try { diff --git a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart index 238499c5f..081709c31 100644 --- a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart +++ b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart @@ -189,7 +189,7 @@ class _Step2ViewState extends ConsumerState<Step2View> { style: STextStyles.smallMed12(context), ), if (isStackCoin(model.receiveTicker)) - BlueTextButton( + CustomTextButton( text: "Choose from stack", onTap: () { try { @@ -448,7 +448,7 @@ class _Step2ViewState extends ConsumerState<Step2View> { style: STextStyles.smallMed12(context), ), if (isStackCoin(model.sendTicker)) - BlueTextButton( + CustomTextButton( text: "Choose from stack", onTap: () { try { diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart index 9d8a1d223..4e42ff888 100644 --- a/lib/pages/exchange_view/trade_details_view.dart +++ b/lib/pages/exchange_view/trade_details_view.dart @@ -516,7 +516,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> { const SizedBox( height: 10, ), - BlueTextButton( + CustomTextButton( text: "View transaction", onTap: () { final Coin coin = diff --git a/lib/pages/paynym/dialogs/paynym_qr_popup.dart b/lib/pages/paynym/dialogs/paynym_qr_popup.dart index 4ff6d9ca0..e712884b1 100644 --- a/lib/pages/paynym/dialogs/paynym_qr_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_qr_popup.dart @@ -118,7 +118,7 @@ class PaynymQrPopup extends StatelessWidget { const SizedBox( height: 6, ), - BlueTextButton( + CustomTextButton( text: "Copy", textSize: isDesktop ? 18 : 10, onTap: () async { diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index 61db83d7b..5076e2450 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -324,7 +324,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { const SizedBox( height: 8, ), - BlueTextButton( + CustomTextButton( text: "Copy", onTap: () async { await Clipboard.setData( diff --git a/lib/pages/receive_view/receive_view.dart b/lib/pages/receive_view/receive_view.dart index c43964779..b6ae7c70a 100644 --- a/lib/pages/receive_view/receive_view.dart +++ b/lib/pages/receive_view/receive_view.dart @@ -233,7 +233,7 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> { const SizedBox( height: 20, ), - BlueTextButton( + CustomTextButton( text: "Create new QR code", onTap: () async { unawaited(Navigator.of(context).push( diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index c9216bf0e..c472bcc11 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -1304,7 +1304,7 @@ class _SendViewState extends ConsumerState<SendView> { style: STextStyles.smallMed12(context), textAlign: TextAlign.left, ), - BlueTextButton( + CustomTextButton( text: "Send all ${coin.ticker}", onTap: () async { if (coin == Coin.firo || diff --git a/lib/pages/settings_views/global_settings_view/about_view.dart b/lib/pages/settings_views/global_settings_view/about_view.dart index a1e78ba7d..bf0f4a507 100644 --- a/lib/pages/settings_views/global_settings_view/about_view.dart +++ b/lib/pages/settings_views/global_settings_view/about_view.dart @@ -484,7 +484,7 @@ class AboutView extends ConsumerWidget { const SizedBox( height: 4, ), - BlueTextButton( + CustomTextButton( text: "https://stackwallet.com", onTap: () { launchUrl( diff --git a/lib/pages/settings_views/global_settings_view/advanced_views/debug_view.dart b/lib/pages/settings_views/global_settings_view/advanced_views/debug_view.dart index 5c12fb1ad..d86dbe272 100644 --- a/lib/pages/settings_views/global_settings_view/advanced_views/debug_view.dart +++ b/lib/pages/settings_views/global_settings_view/advanced_views/debug_view.dart @@ -282,7 +282,7 @@ class _DebugViewState extends ConsumerState<DebugView> { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BlueTextButton( + CustomTextButton( text: "Save Debug Info to clipboard", onTap: () async { try { @@ -350,7 +350,7 @@ class _DebugViewState extends ConsumerState<DebugView> { }, ), const Spacer(), - BlueTextButton( + CustomTextButton( text: "Save logs to file", onTap: () async { final systemfile = SWBFileSystem(); diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart index 91e6871f3..85d28eb66 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart @@ -92,7 +92,7 @@ class _CoinNodesViewState extends ConsumerState<CoinNodesView> { ), textAlign: TextAlign.left, ), - BlueTextButton( + CustomTextButton( text: "Add new node", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart index 85fd9c1e9..6a43d963e 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart @@ -327,7 +327,7 @@ class _AutoBackupViewState extends ConsumerState<AutoBackupView> { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BlueTextButton( + CustomTextButton( text: "Back up now", onTap: () { ref.read(autoSWBServiceProvider).doBackup(); @@ -448,7 +448,7 @@ class _AutoBackupViewState extends ConsumerState<AutoBackupView> { height: 20, ), Center( - child: BlueTextButton( + child: CustomTextButton( text: "Edit Auto Backup", onTap: () async { Navigator.of(context) diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart index 21e0f2d49..526ef0e79 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart @@ -749,7 +749,7 @@ class _WalletNetworkSettingsViewState ? STextStyles.desktopTextExtraExtraSmall(context) : STextStyles.smallMed12(context), ), - BlueTextButton( + CustomTextButton( text: "Add new node", onTap: () { Navigator.of(context).pushNamed( @@ -880,7 +880,7 @@ class _WalletNetworkSettingsViewState top: 16, bottom: 6, ), - child: BlueTextButton( + child: CustomTextButton( text: "Rescan", onTap: () async { await Navigator.of(context).push( diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index af82a250d..5b737a939 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -1092,7 +1092,7 @@ class _TransactionDetailsViewState height: 8, ), if (coin != Coin.epicCash) - BlueTextButton( + CustomTextButton( text: "Open in block explorer", onTap: () async { final uri = diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart index fd5473b11..04817a843 100644 --- a/lib/pages/wallet_view/wallet_view.dart +++ b/lib/pages/wallet_view/wallet_view.dart @@ -649,7 +649,7 @@ class _WalletViewState extends ConsumerState<WalletView> { .textDark3, ), ), - BlueTextButton( + CustomTextButton( text: "See all", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/pages/wallets_view/sub_widgets/all_wallets.dart b/lib/pages/wallets_view/sub_widgets/all_wallets.dart index eae7374bf..b63e8eb6e 100644 --- a/lib/pages/wallets_view/sub_widgets/all_wallets.dart +++ b/lib/pages/wallets_view/sub_widgets/all_wallets.dart @@ -24,7 +24,7 @@ class AllWallets extends StatelessWidget { color: Theme.of(context).extension<StackColors>()!.textDark, ), ), - BlueTextButton( + CustomTextButton( text: "Add new", onTap: () { Navigator.of(context).pushNamed(AddWalletView.routeName); diff --git a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart index ad9310df2..518e593b0 100644 --- a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart +++ b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart @@ -66,7 +66,7 @@ class DesktopAddressCard extends StatelessWidget { ), Row( children: [ - BlueTextButton( + CustomTextButton( text: "Copy", onTap: () { clipboard.setData( @@ -87,7 +87,7 @@ class DesktopAddressCard extends StatelessWidget { if (contactId != "default") Consumer( builder: (context, ref, child) { - return BlueTextButton( + return CustomTextButton( text: "Edit", onTap: () async { ref.refresh( diff --git a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_contact_details.dart index 98fce4a0b..4b2eb33a8 100644 --- a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_contact_details.dart +++ b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_contact_details.dart @@ -182,7 +182,7 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> { style: STextStyles.desktopTextExtraExtraSmall(context), ), - BlueTextButton( + CustomTextButton( text: "Add new", onTap: () async { ref.refresh( diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart index 027de6cd7..c959e0f45 100644 --- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart +++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart @@ -300,7 +300,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> { ), if (isStackCoin(ref.watch(desktopExchangeModelProvider .select((value) => value!.receiveTicker)))) - BlueTextButton( + CustomTextButton( text: "Choose from stack", onTap: selectRecipientAddressFromStack, ), @@ -432,7 +432,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> { ), if (isStackCoin(ref.watch(desktopExchangeModelProvider .select((value) => value!.sendTicker)))) - BlueTextButton( + CustomTextButton( text: "Choose from stack", onTap: selectRefundAddressFromStack, ), diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart index 3216949b0..2c1d8a44d 100644 --- a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart +++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart @@ -221,7 +221,7 @@ class _DesktopChooseFromStackState const SizedBox( width: 80, ), - BlueTextButton( + CustomTextButton( text: "Select wallet", onTap: () async { final address = diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart index 296847d71..b87ca6c6b 100644 --- a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart +++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart @@ -72,7 +72,7 @@ class _DesktopTradeHistoryState extends ConsumerState<DesktopTradeHistory> { "Recent trades", style: STextStyles.desktopTextExtraExtraSmall(context), ), - BlueTextButton( + CustomTextButton( text: "See all", onTap: () { Navigator.of(context) diff --git a/lib/pages_desktop_specific/my_stack_view/desktop_favorite_wallets.dart b/lib/pages_desktop_specific/my_stack_view/desktop_favorite_wallets.dart index 91130fe19..5694c66ed 100644 --- a/lib/pages_desktop_specific/my_stack_view/desktop_favorite_wallets.dart +++ b/lib/pages_desktop_specific/my_stack_view/desktop_favorite_wallets.dart @@ -39,7 +39,7 @@ class DesktopFavoriteWallets extends ConsumerWidget { .textFieldActiveSearchIconRight, ), ), - BlueTextButton( + CustomTextButton( text: "Edit", onTap: () { Navigator.of(context).pushNamed(ManageFavoritesView.routeName); diff --git a/lib/pages_desktop_specific/my_stack_view/my_wallets.dart b/lib/pages_desktop_specific/my_stack_view/my_wallets.dart index 41d0f0ce5..1dd345f74 100644 --- a/lib/pages_desktop_specific/my_stack_view/my_wallets.dart +++ b/lib/pages_desktop_specific/my_stack_view/my_wallets.dart @@ -38,7 +38,7 @@ class _MyWalletsState extends ConsumerState<MyWallets> { ), ), const Spacer(), - BlueTextButton( + CustomTextButton( text: "Add new wallet", onTap: () { Navigator.of( diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart index 1277c5c0f..7ae3c51e4 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart @@ -133,7 +133,7 @@ class _ContactListItemState extends ConsumerState<ContactListItem> { ], ), ), - BlueTextButton( + CustomTextButton( text: "Select wallet", onTap: () { Navigator.of(context).pop(e); diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart index c4f7eee34..cc63c67a8 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart @@ -987,7 +987,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> { ), textAlign: TextAlign.left, ), - BlueTextButton( + CustomTextButton( text: "Send all ${coin.ticker}", onTap: sendAllTapped, ), diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart index 59e01f0b7..dca501e25 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart @@ -37,7 +37,7 @@ class _RecentDesktopTransactionsState .textFieldActiveSearchIconLeft, ), ), - BlueTextButton( + CustomTextButton( text: "See all", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/pages_desktop_specific/password/desktop_login_view.dart b/lib/pages_desktop_specific/password/desktop_login_view.dart index 67eab0903..05ad2d2ad 100644 --- a/lib/pages_desktop_specific/password/desktop_login_view.dart +++ b/lib/pages_desktop_specific/password/desktop_login_view.dart @@ -261,7 +261,7 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> { const SizedBox( height: 60, ), - BlueTextButton( + CustomTextButton( text: "Forgot password?", textSize: 20, onTap: () { diff --git a/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart index 37b40b004..e3f086746 100644 --- a/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart +++ b/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart @@ -450,7 +450,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> { STextStyles.itemSubtitle( context), ), - BlueTextButton( + CustomTextButton( text: "Back up now", onTap: () { ref diff --git a/lib/pages_desktop_specific/settings/settings_menu/desktop_about_view.dart b/lib/pages_desktop_specific/settings/settings_menu/desktop_about_view.dart index 18988cb68..242fbfd9f 100644 --- a/lib/pages_desktop_specific/settings/settings_menu/desktop_about_view.dart +++ b/lib/pages_desktop_specific/settings/settings_menu/desktop_about_view.dart @@ -678,7 +678,7 @@ class DesktopAboutView extends ConsumerWidget { const SizedBox( height: 2, ), - BlueTextButton( + CustomTextButton( text: "https://stackwallet.com", onTap: () { diff --git a/lib/widgets/custom_buttons/blue_text_button.dart b/lib/widgets/custom_buttons/blue_text_button.dart index 7877ddcde..8be6bb937 100644 --- a/lib/widgets/custom_buttons/blue_text_button.dart +++ b/lib/widgets/custom_buttons/blue_text_button.dart @@ -1,17 +1,17 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:stackwallet/providers/ui/color_theme_provider.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; -class BlueTextButton extends ConsumerStatefulWidget { - const BlueTextButton({ +class _CustomTextButton extends StatefulWidget { + const _CustomTextButton({ Key? key, required this.text, + required this.enabledColor, + required this.disabledColor, this.onTap, this.enabled = true, this.textSize, @@ -21,12 +21,14 @@ class BlueTextButton extends ConsumerStatefulWidget { final VoidCallback? onTap; final bool enabled; final double? textSize; + final Color enabledColor; + final Color disabledColor; @override - ConsumerState<BlueTextButton> createState() => _BlueTextButtonState(); + State<_CustomTextButton> createState() => _CustomTextButtonState(); } -class _BlueTextButtonState extends ConsumerState<BlueTextButton> +class _CustomTextButtonState extends State<_CustomTextButton> with SingleTickerProviderStateMixin { AnimationController? controller; Animation<dynamic>? animation; @@ -37,18 +39,14 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton> @override void initState() { if (widget.enabled) { - color = ref.read(colorThemeProvider.state).state.buttonTextBorderless; + color = widget.enabledColor; controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 100), ); animation = ColorTween( - begin: ref.read(colorThemeProvider.state).state.buttonTextBorderless, - end: ref - .read(colorThemeProvider.state) - .state - .buttonTextBorderless - .withOpacity(0.4), + begin: widget.enabledColor, + end: widget.enabledColor.withOpacity(0.4), ).animate(controller!); animation!.addListener(() { @@ -57,7 +55,7 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton> }); }); } else { - color = ref.read(colorThemeProvider.state).state.textSubtitle1; + color = widget.disabledColor; } super.initState(); @@ -116,3 +114,32 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton> ); } } + +class CustomTextButton extends StatelessWidget { + const CustomTextButton({ + Key? key, + required this.text, + this.onTap, + this.enabled = true, + this.textSize, + }) : super(key: key); + + final String text; + final VoidCallback? onTap; + final bool enabled; + final double? textSize; + + @override + Widget build(BuildContext context) { + return _CustomTextButton( + key: UniqueKey(), + text: text, + enabledColor: + Theme.of(context).extension<StackColors>()!.buttonTextBorderless, + disabledColor: Theme.of(context).extension<StackColors>()!.textSubtitle1, + enabled: enabled, + textSize: textSize, + onTap: onTap, + ); + } +} diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart index e366cd713..4e51e0d0d 100644 --- a/lib/widgets/node_card.dart +++ b/lib/widgets/node_card.dart @@ -261,7 +261,7 @@ class _NodeCardState extends ConsumerState<NodeCard> { const SizedBox( width: 66, ), - BlueTextButton( + CustomTextButton( text: "Connect", enabled: _status == "Disconnected", onTap: () async { @@ -285,7 +285,7 @@ class _NodeCardState extends ConsumerState<NodeCard> { const SizedBox( width: 48, ), - BlueTextButton( + CustomTextButton( text: "Details", onTap: () { Navigator.of(context).pushNamed( From 2f1853ef924b57c2a04ccc180daffdcc47ea48a0 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 30 Jan 2023 15:38:01 -0600 Subject: [PATCH 073/123] update default stackwallet paynym code --- lib/utilities/featured_paynyms.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utilities/featured_paynyms.dart b/lib/utilities/featured_paynyms.dart index 2a99bc459..a04fa9a7d 100644 --- a/lib/utilities/featured_paynyms.dart +++ b/lib/utilities/featured_paynyms.dart @@ -3,7 +3,7 @@ abstract class FeaturedPaynyms { // static const String samouraiWalletDevFund = // "PM8TJYkuSdYXJnwDBq8ChfinfXv3srxhQrx3eoEwbSw51wMjdo9JJ2DsycwT3gt3zHQ7cV1grvabMmmf1Btj6fY7tgkgSz9B8MZuR3kjYfgMLMURJCXN"; static const String stackWallet = - "PM8TJPdEeH3A77h4xJYQeXPWix2W5yAJrzVQ8ggET1n92utnc57FXCoH94Z2wUSJNfGwkX1kNDTCQLkHecVsjQHGkDE8MUyWE4xWJcc1EDDYCeSSBfLL"; + "PM8TJdQcNk27JpxGRtNR7Hnh8VkJk4Nf17BthLx89fM3iX3UL2YshyaiTAvKgTCVvpgsAgY1DbojkAaUd3Rcn48NEn4uUBuqkaSddgKL8TPAAEQXNuE6"; static Map<String, String> get featured => { "Stack Wallet": stackWallet, From 83cf471b6fcd203662f1823722f4b81f9e13ca06 Mon Sep 17 00:00:00 2001 From: Diego Salazar <diego@cypherstack.com> Date: Mon, 30 Jan 2023 15:03:12 -0700 Subject: [PATCH 074/123] Update pubspec.yaml --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 49574720d..5ab5c8b80 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.36+114 +version: 1.5.36+115 environment: sdk: ">=2.17.0 <3.0.0" From bcb8f2cd413f706a206fb7e363acad1428b29865 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 08:41:40 -0600 Subject: [PATCH 075/123] "choose from stack" fixes --- crypto_plugins/flutter_libepiccash | 2 +- lib/pages/buy_view/buy_form.dart | 8 ++++++-- .../exchange_view/exchange_step_views/step_2_view.dart | 4 ++-- .../exchange_steps/subwidgets/desktop_step_2.dart | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index 0309140a9..9a150d8cd 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit 0309140a95a51388df0effcc39ff0a25b2752b29 +Subproject commit 9a150d8cd2c3625424b0059e6b7306f3659fdbe0 diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 30bd05106..feea9579d 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -1130,7 +1130,7 @@ class _BuyFormState extends ConsumerState<BuyForm> { ), if (isStackCoin(selectedCrypto?.ticker)) CustomTextButton( - text: "Choose from stack", + text: "Choose from Stack", onTap: () { try { final coin = coinFromTickerCaseInsensitive( @@ -1153,7 +1153,11 @@ class _BuyFormState extends ConsumerState<BuyForm> { _receiveAddressController.text = await manager.currentReceivingAddress; - setState(() {}); + setState(() { + _addressToggleFlag = + _receiveAddressController.text.isNotEmpty; + }); + validateAmount(); } }); } catch (e, s) { diff --git a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart index 081709c31..86db9171a 100644 --- a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart +++ b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart @@ -190,7 +190,7 @@ class _Step2ViewState extends ConsumerState<Step2View> { ), if (isStackCoin(model.receiveTicker)) CustomTextButton( - text: "Choose from stack", + text: "Choose from Stack", onTap: () { try { final coin = @@ -449,7 +449,7 @@ class _Step2ViewState extends ConsumerState<Step2View> { ), if (isStackCoin(model.sendTicker)) CustomTextButton( - text: "Choose from stack", + text: "Choose from Stack", onTap: () { try { final coin = diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart index c959e0f45..c4371d4e8 100644 --- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart +++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart @@ -301,7 +301,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> { if (isStackCoin(ref.watch(desktopExchangeModelProvider .select((value) => value!.receiveTicker)))) CustomTextButton( - text: "Choose from stack", + text: "Choose from Stack", onTap: selectRecipientAddressFromStack, ), ], @@ -433,7 +433,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> { if (isStackCoin(ref.watch(desktopExchangeModelProvider .select((value) => value!.sendTicker)))) CustomTextButton( - text: "Choose from stack", + text: "Choose from Stack", onTap: selectRefundAddressFromStack, ), ], From 92076bf12ad444588dcbe493764fd6bf5c8b339c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 09:17:25 -0600 Subject: [PATCH 076/123] add image assets --- assets/svg/robot-head.svg | 3 +++ assets/svg/whirlpool.svg | 3 +++ lib/utilities/assets.dart | 2 ++ pubspec.yaml | 2 ++ 4 files changed, 10 insertions(+) create mode 100644 assets/svg/robot-head.svg create mode 100644 assets/svg/whirlpool.svg diff --git a/assets/svg/robot-head.svg b/assets/svg/robot-head.svg new file mode 100644 index 000000000..b6810c227 --- /dev/null +++ b/assets/svg/robot-head.svg @@ -0,0 +1,3 @@ +<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M10.4173 5.41699V5.91699H10.9173H14.1257C15.1181 5.91699 15.9173 6.71825 15.9173 7.70866V15.5003C15.9173 16.2377 15.3213 16.8337 14.584 16.8337H5.41732C4.67997 16.8337 4.08398 16.2377 4.08398 15.5003V7.70866C4.08398 6.71866 4.88565 5.91699 5.87565 5.91699H9.08398H9.58398V5.41699V3.58366C9.58398 3.35506 9.77205 3.16699 10.0007 3.16699C10.2292 3.16699 10.4173 3.35506 10.4173 3.58366V5.41699ZM8.16732 15.0837H8.58398H8.66732H9.08398H10.9173H11.334H11.4173H11.834H13.6673H14.1673V14.5837V13.667V13.167H13.6673H11.834H11.4173H11.334H10.9173H9.08398H8.66732H8.58398H8.16732H6.33398H5.83398V13.667V14.5837V15.0837H6.33398H8.16732ZM1.33398 10.0003C1.33398 9.89019 1.37745 9.7852 1.45595 9.70663C1.53524 9.62741 1.64114 9.58366 1.75065 9.58366H2.16732V14.0837H1.75065C1.64023 14.0837 1.53452 14.0398 1.45609 13.9614C1.37774 13.8831 1.33398 13.7775 1.33398 13.667V10.0003ZM5.60482 10.0003C5.60482 10.9095 6.34144 11.6462 7.25065 11.6462C8.15987 11.6462 8.89648 10.9095 8.89648 10.0003C8.89648 9.09111 8.15987 8.35449 7.25065 8.35449C6.34144 8.35449 5.60482 9.09111 5.60482 10.0003ZM11.1048 10.0003C11.1048 10.9101 11.8409 11.6462 12.7507 11.6462C13.6599 11.6462 14.3965 10.9095 14.3965 10.0003C14.3965 9.09111 13.6599 8.35449 12.7507 8.35449C11.8416 8.35449 11.1048 9.09037 11.1048 10.0003ZM18.2507 9.58366C18.3599 9.58366 18.4652 9.62719 18.5445 9.70648C18.6238 9.78578 18.6673 9.89112 18.6673 10.0003V13.667C18.6673 13.7774 18.6235 13.8831 18.5451 13.9616C18.4667 14.0399 18.3612 14.0837 18.2507 14.0837H17.834V9.58366H18.2507Z" fill="#8E9192" stroke="#8E9192"/> +</svg> diff --git a/assets/svg/whirlpool.svg b/assets/svg/whirlpool.svg new file mode 100644 index 000000000..cf075308f --- /dev/null +++ b/assets/svg/whirlpool.svg @@ -0,0 +1,3 @@ +<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M6.16811 18.29C4.45149 18.089 3.04304 17.5064 1.84171 16.5006C1.52855 16.2383 1.08929 15.7904 0.868214 15.5078C0.795124 15.4144 0.815885 15.4205 1.16357 15.5943C2.17257 16.0986 3.56529 16.3941 4.67986 16.3404C5.4666 16.3025 6.00361 16.1827 6.16709 16.0087C6.30087 15.8663 6.24663 15.772 5.85013 15.458C4.68271 14.5333 3.91789 13.4633 3.48109 12.1436C2.95876 10.5655 3.03006 8.85291 3.68121 7.33745C3.85982 6.92178 4.22353 6.25056 4.46108 5.89825C5.0569 5.01461 6.02359 4.09702 7.04772 3.443C7.53459 3.13207 8.67134 2.57608 9.28978 2.34638C10.1175 2.03895 11.0493 1.81907 11.9322 1.72278C12.5152 1.6592 13.8654 1.6973 14.3766 1.79177C15.7252 2.04096 16.8058 2.50254 17.8199 3.26249C18.1679 3.52329 18.8273 4.15363 19.0478 4.43636L19.1673 4.58953L18.7556 4.39158C17.6907 3.87949 16.4125 3.60951 15.2969 3.66106C13.9736 3.72218 13.4271 3.9979 13.8908 4.37051C14.4654 4.83219 14.718 5.05501 14.9678 5.32051C16.047 6.46745 16.6696 7.8829 16.8049 9.49648C16.8912 10.527 16.6998 11.6803 16.2805 12.6564C15.6851 14.0423 14.7972 15.1697 13.573 16.0943C13.0338 16.5014 12.6196 16.756 11.9526 17.09C10.795 17.6696 9.68552 18.033 8.49122 18.2239C8.12694 18.2821 6.49683 18.3285 6.16811 18.29ZM10.567 12.7788C11.6493 12.5494 12.5288 11.6694 12.7584 10.586C12.824 10.2766 12.8238 9.72298 12.7584 9.41267C12.6408 8.85789 12.4049 8.43337 11.9758 8.00424C11.3957 7.42417 10.7838 7.17097 9.95841 7.16954C9.16291 7.16743 8.43295 7.4925 7.88801 8.0894C7.39072 8.63413 7.14979 9.25773 7.14979 10.0002C7.14979 10.8011 7.40895 11.4213 7.98385 11.9962C8.40667 12.419 8.83591 12.6598 9.37601 12.7773C9.67249 12.8418 10.2667 12.8425 10.5673 12.7794L10.567 12.7788Z" fill="#8E9192"/> +</svg> diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart index 5a0427782..bef07a1d7 100644 --- a/lib/utilities/assets.dart +++ b/lib/utilities/assets.dart @@ -194,6 +194,8 @@ class _SVG { String get exitDesktop => "assets/svg/exit-desktop.svg"; String get keys => "assets/svg/keys.svg"; String get arrowDown => "assets/svg/arrow-down.svg"; + String get robotHead => "assets/svg/robot-head.svg"; + String get whirlPool => "assets/svg/whirlpool.svg"; String get ellipse1 => "assets/svg/Ellipse-43.svg"; String get ellipse2 => "assets/svg/Ellipse-42.svg"; diff --git a/pubspec.yaml b/pubspec.yaml index 5ab5c8b80..5e131a27a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -309,6 +309,8 @@ flutter: - assets/svg/plus-circle.svg - assets/svg/circle-plus-filled.svg - assets/svg/configuration.svg + - assets/svg/robot-head.svg + - assets/svg/whirlpool.svg # coin icons - assets/svg/coin_icons/Bitcoin.svg - assets/svg/coin_icons/Litecoin.svg From 69934fb87103c7b647d4ba690b1077cece21a57c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 09:42:55 -0600 Subject: [PATCH 077/123] clean up transaction list item ui state update key --- .../sub_widgets/transactions_list.dart | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/lib/pages/wallet_view/sub_widgets/transactions_list.dart b/lib/pages/wallet_view/sub_widgets/transactions_list.dart index 360b3028b..0c48e69b6 100644 --- a/lib/pages/wallet_view/sub_widgets/transactions_list.dart +++ b/lib/pages/wallet_view/sub_widgets/transactions_list.dart @@ -20,6 +20,8 @@ import 'package:stackwallet/widgets/trade_card.dart'; import 'package:stackwallet/widgets/transaction_card.dart'; import 'package:tuple/tuple.dart'; +import '../../../utilities/enums/coin_enum.dart'; + class TransactionsList extends ConsumerStatefulWidget { const TransactionsList({ Key? key, @@ -67,11 +69,18 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { BuildContext context, Transaction tx, BorderRadius? radius, + Coin coin, ) { final matchingTrades = ref .read(tradesServiceProvider) .trades .where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid); + + final isConfirmed = tx.isConfirmed( + ref.watch( + widget.managerProvider.select((value) => value.currentHeight)), + coin.requiredConfirmations); + if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) { final trade = matchingTrades.first; return Container( @@ -84,13 +93,9 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { children: [ TransactionCard( // this may mess with combined firo transactions - key: Key(tx.txid + - tx.type.name + - tx.address.value.toString() + - ref - .watch(widget.managerProvider - .select((value) => value.currentHeight)) - .toString()), // + key: isConfirmed + ? Key(tx.txid + tx.type.name + tx.address.value.toString()) + : UniqueKey(), // transaction: tx, walletId: widget.walletId, ), @@ -185,13 +190,9 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { ), child: TransactionCard( // this may mess with combined firo transactions - key: Key(tx.txid + - tx.type.name + - tx.address.value.toString() + - ref - .watch(widget.managerProvider - .select((value) => value.currentHeight)) - .toString()), // + key: isConfirmed + ? Key(tx.txid + tx.type.name + tx.address.value.toString()) + : UniqueKey(), transaction: tx, walletId: widget.walletId, ), @@ -263,7 +264,7 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { radius = _borderRadiusFirst; } final tx = _transactions2[index]; - return itemBuilder(context, tx, radius); + return itemBuilder(context, tx, radius, manager.coin); }, separatorBuilder: (context, index) { return Container( @@ -290,7 +291,7 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { radius = _borderRadiusFirst; } final tx = _transactions2[index]; - return itemBuilder(context, tx, radius); + return itemBuilder(context, tx, radius, manager.coin); }, ), ); From 3940c88e448f8eb972c139652b331b2f05ce4ed6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 10:03:16 -0600 Subject: [PATCH 078/123] fix notifTx fee calculate bug --- lib/services/mixins/paynym_wallet_interface.dart | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 2292f3ec5..e1fe7cbee 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -438,11 +438,13 @@ mixin PaynymWalletInterface { feeRatePerKB: selectedTxFeeRate, ); - if (feeForNoChange < vSizeForNoChange * 1000) { - feeForNoChange = vSizeForNoChange * 1000; - } - if (feeForWithChange < vSizeForWithChange * 1000) { - feeForWithChange = vSizeForWithChange * 1000; + if (_coin == Coin.dogecoin || _coin == Coin.dogecoinTestNet) { + if (feeForNoChange < vSizeForNoChange * 1000) { + feeForNoChange = vSizeForNoChange * 1000; + } + if (feeForWithChange < vSizeForWithChange * 1000) { + feeForWithChange = vSizeForWithChange * 1000; + } } if (satoshisBeingUsed - amountToSend > feeForNoChange + _dustLimitP2PKH) { From c06c3935cae3f815a0074435f48e0d836f194b91 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 10:37:03 -0600 Subject: [PATCH 079/123] handle fee rounding error --- lib/services/mixins/paynym_wallet_interface.dart | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index e1fe7cbee..c979e80da 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -455,7 +455,7 @@ mixin PaynymWalletInterface { // check estimates are correct and build notification tx if (changeAmount >= _dustLimitP2PKH && satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { - final txn = await _createNotificationTx( + var txn = await _createNotificationTx( targetPaymentCodeString: targetPaymentCodeString, utxosToUse: utxoObjectsToUse, utxoSigningData: utxoSigningData, @@ -464,6 +464,18 @@ mixin PaynymWalletInterface { int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; + // make sure minimum fee is accurate if that is being used + if (txn.item2 - feeBeingPaid == 1) { + changeAmount -= 1; + feeBeingPaid += 1; + txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: changeAmount, + ); + } + Map<String, dynamic> transactionObject = { "hex": txn.item1, "recipientPaynym": targetPaymentCodeString, From 0a264a97c5c16bef80b087f72fe8c9cf82976d08 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 10:37:53 -0600 Subject: [PATCH 080/123] pass p2pkh change address to paynym interface --- .../coins/bitcoin/bitcoin_wallet.dart | 62 ++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 32c24686b..ad8e9f5da 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -218,6 +218,19 @@ class BitcoinWallet extends CoinServiceAPI .findFirst()) ?? await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); + Future<String> get currentChangeAddressP2PKH async => + (await _currentChangeAddressP2PKH).value; + + Future<isar_models.Address> get _currentChangeAddressP2PKH async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0, DerivePathType.bip44); + @override Future<void> exit() async { _hasCalledExit = true; @@ -1313,13 +1326,14 @@ class BitcoinWallet extends CoinServiceAPI secureStorage: secureStore, getMnemonic: () => mnemonic, getChainHeight: () => chainHeight, - getCurrentChangeAddress: () => currentChangeAddress, + getCurrentChangeAddress: () => currentChangeAddressP2PKH, estimateTxFee: estimateTxFee, prepareSend: prepareSend, getTxCount: getTxCount, fetchBuildTxData: fetchBuildTxData, refresh: refresh, - checkChangeAddressForTransactions: _checkChangeAddressForTransactions, + checkChangeAddressForTransactions: + _checkP2PKHChangeAddressForTransactions, addDerivation: addDerivation, addDerivations: addDerivations, dustLimitP2PKH: DUST_LIMIT_P2PKH, @@ -1966,6 +1980,50 @@ class BitcoinWallet extends CoinServiceAPI } } + Future<void> _checkP2PKHChangeAddressForTransactions() async { + try { + final currentChange = await _currentChangeAddressP2PKH; + final int txCount = await getTxCount(address: currentChange.value); + Logging.instance.log( + 'Number of txs for current change address $currentChange: $txCount', + level: LogLevel.Info); + + if (txCount >= 1 || currentChange.derivationIndex < 0) { + // First increment the change index + final newChangeIndex = currentChange.derivationIndex + 1; + + // Use new index to derive a new change address + final newChangeAddress = await _generateAddressForChain( + 1, newChangeIndex, DerivePathType.bip44); + + final existing = await db + .getAddresses(walletId) + .filter() + .valueEqualTo(newChangeAddress.value) + .findFirst(); + if (existing == null) { + // Add that new change address + await db.putAddress(newChangeAddress); + } else { + // we need to update the address + await db.updateAddress(existing, newChangeAddress); + } + // keep checking until address with no tx history is set as current + await _checkP2PKHChangeAddressForTransactions(); + } + } on SocketException catch (se, s) { + Logging.instance.log( + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $se\n$s", + level: LogLevel.Error); + return; + } catch (e, s) { + Logging.instance.log( + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $e\n$s", + level: LogLevel.Error); + rethrow; + } + } + Future<void> _checkCurrentReceivingAddressesForTransactions() async { try { // for (final type in DerivePathType.values) { From dcd7f312a5f1ead7e4cce9352baf04629572291b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 11:09:21 -0600 Subject: [PATCH 081/123] dynamics... --- lib/services/buy/simplex/simplex_api.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/buy/simplex/simplex_api.dart b/lib/services/buy/simplex/simplex_api.dart index 85b4d5d9e..37417fcbf 100644 --- a/lib/services/buy/simplex/simplex_api.dart +++ b/lib/services/buy/simplex/simplex_api.dart @@ -213,7 +213,7 @@ class SimplexAPI { // final Map<String, dynamic> lol = // Map<String, dynamic>.from(jsonArray as Map); - String? cryptoAmount = jsonArray['digital_money']?['amount'] as String?; + double? cryptoAmount = jsonArray['digital_money']?['amount'] as double?; if (cryptoAmount == null) { String error = jsonArray['error'] as String; From 57dd5669063a4b316da623b9fb174c8034ef8c4d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 11:11:42 -0600 Subject: [PATCH 082/123] paynym bot head icon --- .../wallet_view/sub_widgets/wallet_navigation_bar.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart index 4e6be9e97..379362dbc 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart @@ -177,6 +177,14 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> { "Paynym", style: STextStyles.w600_12(context), ), + const SizedBox( + width: 16, + ), + SvgPicture.asset( + Assets.svg.robotHead, + height: 20, + width: 20, + ), ], ), ), From 95ff076d3d7a6c4befc0fc8e0fff50cac25d00fa Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 11:35:58 -0600 Subject: [PATCH 083/123] add paynym bot image background --- assets/images/unclaimed.png | Bin 0 -> 773687 bytes lib/pages/paynym/paynym_claim_view.dart | 2 +- lib/utilities/assets.dart | 1 + pubspec.yaml | 1 + 4 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 assets/images/unclaimed.png diff --git a/assets/images/unclaimed.png b/assets/images/unclaimed.png new file mode 100644 index 0000000000000000000000000000000000000000..f99d4ab2a03643c930aa8251c8b4fefa85cceb2d GIT binary patch literal 773687 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:LG> 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�CGq^HS^u=s-2g>P#&!u_QWGj3Gjy#6H8`-1~ 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≷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 ISo*~L2b57TrT_o{ literal 0 HcmV?d00001 diff --git a/lib/pages/paynym/paynym_claim_view.dart b/lib/pages/paynym/paynym_claim_view.dart index 23f9d868e..326983a78 100644 --- a/lib/pages/paynym/paynym_claim_view.dart +++ b/lib/pages/paynym/paynym_claim_view.dart @@ -117,7 +117,7 @@ class _PaynymClaimViewState extends ConsumerState<PaynymClaimView> { ), Image( image: AssetImage( - Assets.png.stack, + Assets.png.unclaimedPaynym, ), width: MediaQuery.of(context).size.width / 2, ), diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart index bef07a1d7..5bb7c3edb 100644 --- a/lib/utilities/assets.dart +++ b/lib/utilities/assets.dart @@ -264,6 +264,7 @@ class _PNG { const _PNG(); String get stack => "assets/images/stack.png"; + String get unclaimedPaynym => "assets/images/unclaimed.png"; String get splash => "assets/images/splash.png"; String get monero => "assets/images/monero.png"; diff --git a/pubspec.yaml b/pubspec.yaml index 5e131a27a..fb8b264d4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -205,6 +205,7 @@ flutter: - assets/svg/circle-check.svg - assets/svg/clipboard.svg - assets/images/stack.png + - assets/images/unclaimed.png - assets/images/monero.png - assets/images/wownero.png - assets/images/firo.png From 2e7d55bda4c546632f5a23677472320925e8ce1e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 12:17:32 -0600 Subject: [PATCH 084/123] btc notification tx fix --- lib/services/mixins/paynym_wallet_interface.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index c979e80da..a8354b75f 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -588,6 +588,8 @@ mixin PaynymWalletInterface { txb.addInput( utxo.txid, txPointIndex, + null, + utxoSigningData[utxo.txid]["output"] as Uint8List, ); // todo: modify address once segwit support is in our bip47 @@ -606,15 +608,18 @@ mixin PaynymWalletInterface { txb.sign( vin: 0, keyPair: myKeyPair, + witnessValue: utxo.value, + witnessScript: utxoSigningData[utxo.txid]["redeemScript"] as Uint8List?, ); // sign rest of possible inputs - for (var i = 1; i < utxosToUse.length - 1; i++) { + for (var i = 1; i < utxosToUse.length; i++) { final txid = utxosToUse[i].txid; txb.sign( vin: i, keyPair: utxoSigningData[txid]["keyPair"] as btc_dart.ECPair, - // witnessValue: utxosToUse[i].value, + witnessValue: utxosToUse[i].value, + witnessScript: utxoSigningData[utxo.txid]["redeemScript"] as Uint8List?, ); } From 1e92f96ff13406e41cbd6c1980be9467215553c8 Mon Sep 17 00:00:00 2001 From: Diego Salazar <diego@cypherstack.com> Date: Tue, 31 Jan 2023 11:29:04 -0700 Subject: [PATCH 085/123] Update pubspec.yaml --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index fb8b264d4..6cba3b460 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.36+115 +version: 1.5.36+117 environment: sdk: ">=2.17.0 <3.0.0" From 6df782647eb5a05ea7eb9d09c09954d4d210978e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 13:44:56 -0600 Subject: [PATCH 086/123] btc send exact value of output fix --- lib/services/coins/bitcoin/bitcoin_wallet.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index ad8e9f5da..5f18f3273 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -2360,7 +2360,10 @@ class BitcoinWallet extends CoinServiceAPI ], satoshiAmounts: [ satoshiAmountToSend, - satoshisBeingUsed - satoshiAmountToSend - 1 + // this can cause a problem where the output value is negative so commenting out for now + // satoshisBeingUsed - satoshiAmountToSend - 1 + // and using dust limit instead + DUST_LIMIT, ], // dust limit is the minimum amount a change output should be ))["vSize"] as int; @@ -2825,6 +2828,7 @@ class BitcoinWallet extends CoinServiceAPI // Add transaction output for (var i = 0; i < recipients.length; i++) { + print("OURPUT VALUW: ${satoshiAmounts[i]}"); txb.addOutput(recipients[i], satoshiAmounts[i]); } From 95d1f3c17e5bdd46d8a14d347970d247ef4f22ad Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 14:09:45 -0600 Subject: [PATCH 087/123] check all outputs for payment codes --- .../mixins/paynym_wallet_interface.dart | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index a8354b75f..f420e8a67 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -696,8 +696,26 @@ mixin PaynymWalletInterface { } try { - final blindedCode = - transaction.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1]; + Uint8List? blindedCodeBytes; + + for (int i = 0; i < transaction.outputs.length; i++) { + List<String>? scriptChunks = + transaction.outputs.elementAt(1).scriptPubKeyAsm?.split(" "); + if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { + final blindedPaymentCode = scriptChunks![1]; + final bytes = blindedPaymentCode.fromHex; + + // https://en.bitcoin.it/wiki/BIP_0047#Sending + if (bytes.length == 80 && bytes.first == 1) { + blindedCodeBytes = bytes; + } + } + } + + // transaction does not contain a payment code + if (blindedCodeBytes == null) { + return null; + } final designatedInput = transaction.inputs.first; @@ -718,7 +736,7 @@ mixin PaynymWalletInterface { final mask = PaymentCode.getMask(S.ecdhSecret(), rev); - final unBlindedPayload = PaymentCode.blind(blindedCode.fromHex, mask); + final unBlindedPayload = PaymentCode.blind(blindedCodeBytes, mask); final unBlindedPaymentCode = PaymentCode.initFromPayload(unBlindedPayload); From 6a0673bec5023986dc26d49e2549d9e8de280699 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 14:40:54 -0600 Subject: [PATCH 088/123] EXTRACT FUNCTION FOR PARSING BLINDED PAYMENT CODE FROM A TRANSACTION --- .../mixins/paynym_wallet_interface.dart | 18 +++---------- lib/utilities/bip47_utils.dart | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 lib/utilities/bip47_utils.dart diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index f420e8a67..3db2f453f 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -16,6 +16,7 @@ import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dar import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; +import 'package:stackwallet/utilities/bip47_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; @@ -696,21 +697,8 @@ mixin PaynymWalletInterface { } try { - Uint8List? blindedCodeBytes; - - for (int i = 0; i < transaction.outputs.length; i++) { - List<String>? scriptChunks = - transaction.outputs.elementAt(1).scriptPubKeyAsm?.split(" "); - if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { - final blindedPaymentCode = scriptChunks![1]; - final bytes = blindedPaymentCode.fromHex; - - // https://en.bitcoin.it/wiki/BIP_0047#Sending - if (bytes.length == 80 && bytes.first == 1) { - blindedCodeBytes = bytes; - } - } - } + final blindedCodeBytes = + Bip47Utils.getBlindedPaymentCodeBytesFrom(transaction); // transaction does not contain a payment code if (blindedCodeBytes == null) { diff --git a/lib/utilities/bip47_utils.dart b/lib/utilities/bip47_utils.dart new file mode 100644 index 000000000..2f1622cb7 --- /dev/null +++ b/lib/utilities/bip47_utils.dart @@ -0,0 +1,27 @@ +import 'dart:typed_data'; + +import 'package:bip47/src/util.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; + +abstract class Bip47Utils { + /// looks at tx outputs and returns a blinded payment code if found + static Uint8List? getBlindedPaymentCodeBytesFrom(Transaction transaction) { + Uint8List? blindedCodeBytes; + + for (int i = 0; i < transaction.outputs.length; i++) { + List<String>? scriptChunks = + transaction.outputs.elementAt(i).scriptPubKeyAsm?.split(" "); + if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { + final blindedPaymentCode = scriptChunks![1]; + final bytes = blindedPaymentCode.fromHex; + + // https://en.bitcoin.it/wiki/BIP_0047#Sending + if (bytes.length == 80 && bytes.first == 1) { + blindedCodeBytes = bytes; + } + } + } + + return blindedCodeBytes; + } +} From a25c03cb5c23cab37a805147a3e105297d11780b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 16:21:09 -0600 Subject: [PATCH 089/123] modify bip47 utils --- lib/utilities/bip47_utils.dart | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/utilities/bip47_utils.dart b/lib/utilities/bip47_utils.dart index 2f1622cb7..6433f4e1d 100644 --- a/lib/utilities/bip47_utils.dart +++ b/lib/utilities/bip47_utils.dart @@ -1,24 +1,34 @@ import 'dart:typed_data'; import 'package:bip47/src/util.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/output.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; abstract class Bip47Utils { /// looks at tx outputs and returns a blinded payment code if found static Uint8List? getBlindedPaymentCodeBytesFrom(Transaction transaction) { + for (int i = 0; i < transaction.outputs.length; i++) { + final bytes = getBlindedPaymentCodeBytesFromOutput( + transaction.outputs.elementAt(i)); + if (bytes != null) { + return bytes; + } + } + + return null; + } + + static Uint8List? getBlindedPaymentCodeBytesFromOutput(Output output) { Uint8List? blindedCodeBytes; - for (int i = 0; i < transaction.outputs.length; i++) { - List<String>? scriptChunks = - transaction.outputs.elementAt(i).scriptPubKeyAsm?.split(" "); - if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { - final blindedPaymentCode = scriptChunks![1]; - final bytes = blindedPaymentCode.fromHex; + List<String>? scriptChunks = output.scriptPubKeyAsm?.split(" "); + if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { + final blindedPaymentCode = scriptChunks![1]; + final bytes = blindedPaymentCode.fromHex; - // https://en.bitcoin.it/wiki/BIP_0047#Sending - if (bytes.length == 80 && bytes.first == 1) { - blindedCodeBytes = bytes; - } + // https://en.bitcoin.it/wiki/BIP_0047#Sending + if (bytes.length == 80 && bytes.first == 1) { + blindedCodeBytes = bytes; } } From 19bf4c0df6f833ec6968eb16abf72f92effd23e4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 17:26:10 -0600 Subject: [PATCH 090/123] scan following/followers for paynym history --- .../coins/bitcoin/bitcoin_wallet.dart | 30 +++++- .../mixins/paynym_wallet_interface.dart | 92 ++++++++++++++++--- 2 files changed, 106 insertions(+), 16 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 5f18f3273..2d2f5b590 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -40,6 +40,7 @@ import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; +import 'package:stackwallet/utilities/paynym_is_api.dart'; import 'package:stackwallet/utilities/prefs.dart'; import 'package:tuple/tuple.dart'; import 'package:uuid/uuid.dart'; @@ -704,16 +705,28 @@ class BitcoinWallet extends CoinServiceAPI ...p2shChangeAddressArray, ]); - // generate to ensure notification address is in db before refreshing transactions - await getMyNotificationAddress(DerivePathType.bip44); + // get own payment code + final myCode = await getPaymentCode(DerivePathType.bip44); // refresh transactions to pick up any received notification transactions await _refreshTransactions(); + final Set<String> codesToCheck = {}; + final nym = await PaynymIsApi().nym(myCode.toString()); + if (nym.value != null) { + for (final follower in nym.value!.followers) { + codesToCheck.add(follower.code); + } + for (final following in nym.value!.following) { + codesToCheck.add(following.code); + } + } + // restore paynym transactions await restoreAllHistory( maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + paymentCodeStrings: codesToCheck, ); await _updateUTXOs(); @@ -940,6 +953,17 @@ class BitcoinWallet extends CoinServiceAPI GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId)); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.1, walletId)); + final myCode = await getPaymentCode(DerivePathType.bip44); + final Set<String> codesToCheck = {}; + final nym = await PaynymIsApi().nym(myCode.toString()); + if (nym.value != null) { + for (final follower in nym.value!.followers) { + codesToCheck.add(follower.code); + } + for (final following in nym.value!.following) { + codesToCheck.add(following.code); + } + } final currentHeight = await chainHeight; const storedHeight = 1; //await storedChainHeight; @@ -976,6 +1000,7 @@ class BitcoinWallet extends CoinServiceAPI .fire(RefreshPercentChangedEvent(0.80, walletId)); await fetchFuture; + await checkForNotificationTransactionsTo(codesToCheck); await getAllTxsToWatch(); GlobalEventBus.instance .fire(RefreshPercentChangedEvent(0.90, walletId)); @@ -2828,7 +2853,6 @@ class BitcoinWallet extends CoinServiceAPI // Add transaction output for (var i = 0; i < recipients.length; i++) { - print("OURPUT VALUW: ${satoshiAmounts[i]}"); txb.addOutput(recipients[i], satoshiAmounts[i]); } diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 3db2f453f..a257a7d1e 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -749,33 +749,99 @@ mixin PaynymWalletInterface { .subTypeEqualTo(TransactionSubType.bip47Notification) .findAll(); - List<PaymentCode> unBlindedList = []; + List<PaymentCode> codes = []; for (final tx in txns) { - final unBlinded = await unBlindedPaymentCodeFromTransaction( - transaction: tx, - myNotificationAddress: myAddress, - ); - if (unBlinded != null && - unBlindedList - .where((e) => e.toString() == unBlinded.toString()) - .isEmpty) { - unBlindedList.add(unBlinded); + // tx is sent so we can check the address's otherData for the code String + if (tx.type == TransactionType.outgoing && + tx.address.value?.otherData != null) { + final codeString = + await paymentCodeStringByKey(tx.address.value!.otherData!); + if (codeString != null && + codes.where((e) => e.toString() == codeString).isEmpty) { + codes.add(PaymentCode.fromPaymentCode(codeString, _network)); + } + } else { + // otherwise we need to un blind the code + final unBlinded = await unBlindedPaymentCodeFromTransaction( + transaction: tx, + myNotificationAddress: myAddress, + ); + if (unBlinded != null && + codes.where((e) => e.toString() == unBlinded.toString()).isEmpty) { + codes.add(unBlinded); + } } } - return unBlindedList; + return codes; + } + + Future<void> checkForNotificationTransactionsTo( + Set<String> otherCodeStrings) async { + final sentNotificationTransactions = await _db + .getTransactions(_walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .and() + .typeEqualTo(TransactionType.outgoing) + .findAll(); + + final List<PaymentCode> codes = []; + for (final codeString in otherCodeStrings) { + codes.add(PaymentCode.fromPaymentCode(codeString, _network)); + } + + for (final tx in sentNotificationTransactions) { + if (tx.address.value != null && tx.address.value!.otherData == null) { + final oldAddress = + await _db.getAddress(_walletId, tx.address.value!.value); + for (final code in codes) { + final notificationAddress = code.notificationAddressP2PKH(); + if (notificationAddress == oldAddress!.value) { + final address = Address( + walletId: _walletId, + value: notificationAddress, + publicKey: [], + derivationIndex: 0, + type: oldAddress.type, + subType: AddressSubType.paynymNotification, + otherData: await storeCode(code.toString()), + ); + await _db.updateAddress(oldAddress, address); + } + } + } + } } Future<void> restoreAllHistory({ required int maxUnusedAddressGap, required int maxNumberOfIndexesToCheck, + required Set<String> paymentCodeStrings, }) async { final codes = await getAllPaymentCodesFromNotificationTransactions(); + final List<PaymentCode> extraCodes = []; + for (final codeString in paymentCodeStrings) { + if (codes.where((e) => e.toString() == codeString).isEmpty) { + final extraCode = PaymentCode.fromPaymentCode(codeString, _network); + if (extraCode.isValid()) { + extraCodes.add(extraCode); + } + } + } + + codes.addAll(extraCodes); + final List<Future<void>> futures = []; for (final code in codes) { - futures.add(restoreHistoryWith( - code, maxUnusedAddressGap, maxNumberOfIndexesToCheck)); + futures.add( + restoreHistoryWith( + code, + maxUnusedAddressGap, + maxNumberOfIndexesToCheck, + ), + ); } await Future.wait(futures); From 7e05abec43a3f316c0bc77af9c99153dafe41684 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 17:46:30 -0600 Subject: [PATCH 091/123] show green "connected" in paynym details ui --- .../paynym/dialogs/paynym_details_popup.dart | 41 +++++++++++++++++-- .../subwidgets/desktop_paynym_details.dart | 39 ++++++++++++++++-- lib/utilities/text_styles.dart | 35 ++++++++++++++++ 3 files changed, 109 insertions(+), 6 deletions(-) diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index a2aea2a14..83860280b 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -181,9 +181,44 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { const SizedBox( width: 12, ), - Text( - widget.accountLite.nymName, - style: STextStyles.w600_12(context), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.accountLite.nymName, + style: STextStyles.w600_12(context), + ), + FutureBuilder( + future: + wallet.hasConnected(widget.accountLite.code), + builder: (context, AsyncSnapshot<bool> snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.data == true) { + return Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 2, + ), + Text( + "Connected", + style: STextStyles.w500_10(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorGreen, + ), + ) + ], + ); + } else { + return Container(); + } + }, + ), + ], ), ], ), diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index 5076e2450..fd89999d6 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -176,9 +176,42 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { const SizedBox( width: 12, ), - Text( - widget.accountLite.nymName, - style: STextStyles.desktopTextSmall(context), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.accountLite.nymName, + style: STextStyles.desktopTextSmall(context), + ), + FutureBuilder( + future: wallet.hasConnected(widget.accountLite.code), + builder: (context, AsyncSnapshot<bool> snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.data == true) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 2, + ), + Text( + "Connected", + style: STextStyles.desktopTextSmall(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorGreen, + ), + ) + ], + ); + } else { + return Container(); + } + }, + ), + ], ), ], ), diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart index 8b756e984..6af4f6d9c 100644 --- a/lib/utilities/text_styles.dart +++ b/lib/utilities/text_styles.dart @@ -967,6 +967,41 @@ class STextStyles { } } + static TextStyle w500_10(BuildContext context) { + switch (_theme(context).themeType) { + case ThemeType.light: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + case ThemeType.oceanBreeze: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + case ThemeType.dark: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + case ThemeType.oledBlack: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + case ThemeType.fruitSorbet: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + } + } + static TextStyle syncPercent(BuildContext context) { switch (_theme(context).themeType) { case ThemeType.light: From a00340b46497b3246547e23aceb12db919c4b3c6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 17:46:56 -0600 Subject: [PATCH 092/123] fix hasConnected to return true for sent notification transactions --- lib/services/mixins/paynym_wallet_interface.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index a257a7d1e..9300e10a2 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -681,6 +681,13 @@ mixin PaynymWalletInterface { if (paymentCodeString == unBlindedPaymentCode.toString()) { return true; } + + if (tx.address.value?.otherData != null) { + final code = await paymentCodeStringByKey(tx.address.value!.otherData!); + if (code == paymentCodeString) { + return true; + } + } } // otherwise return no From e5464a9c3c8a91ba3b3beb54152d3e5030b2d468 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 18:14:06 -0600 Subject: [PATCH 093/123] pop buy to wallets as well as exchange --- lib/pages/home_view/home_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/home_view/home_view.dart b/lib/pages/home_view/home_view.dart index 5a09203cb..9ba14c692 100644 --- a/lib/pages/home_view/home_view.dart +++ b/lib/pages/home_view/home_view.dart @@ -50,7 +50,7 @@ class _HomeViewState extends ConsumerState<HomeView> { Future<bool> _onWillPop() async { // go to home view when tapping back on the main exchange view - if (ref.read(homeViewPageIndexStateProvider.state).state == 1) { + if (ref.read(homeViewPageIndexStateProvider.state).state != 0) { ref.read(homeViewPageIndexStateProvider.state).state = 0; return false; } From a05121b62ed8ddba2ab65da7fe98f3138595bb53 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 18:31:14 -0600 Subject: [PATCH 094/123] update sorbet theme images --- assets/svg/fruitSorbet/buy-coins-icon.svg | 21 ++++++++++++++------- assets/svg/fruitSorbet/exchange-2.svg | 4 ++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/assets/svg/fruitSorbet/buy-coins-icon.svg b/assets/svg/fruitSorbet/buy-coins-icon.svg index 5788e2bf0..63b214e40 100644 --- a/assets/svg/fruitSorbet/buy-coins-icon.svg +++ b/assets/svg/fruitSorbet/buy-coins-icon.svg @@ -1,11 +1,18 @@ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_908_22491)"> <g opacity="0.4"> -<path d="M22.2 6C23.3297 5.37187 24 4.59422 24 3.75C24 1.67906 19.9688 0 15 0C9.98906 0 6 1.67906 6 3.75C6 4.59422 6.67031 5.37187 7.8 6C7.80937 6.00469 7.81758 6.00937 7.82578 6.01406C7.83398 6.01875 7.84219 6.02344 7.85156 6.02813C8.23125 6.00938 8.61094 6 9 6C11.6344 6 14.0906 6.44062 15.9422 7.21406C16.1203 7.28906 16.2984 7.36875 16.4672 7.44844C18.8062 7.28906 20.8359 6.75469 22.2 6Z" fill="#232323"/> -<path d="M19.9435 12.9151C19.7958 12.9551 19.6477 12.9951 19.5 13.0359V13.5C20.7602 13.5 21.9296 13.8885 22.8951 14.5522C23.5995 14.0172 24 13.4028 24 12.75V11.0906C23.4141 11.5734 22.7063 11.9672 21.9422 12.2859C21.3382 12.5376 20.6447 12.7253 19.9435 12.9151Z" fill="#232323"/> -<path d="M18.3703 8.74688C19.0031 9.37969 19.5 10.2234 19.5 11.25V11.4984C20.4328 11.2734 21.2625 10.9781 21.9469 10.6359C21.9739 10.6209 22.0009 10.6021 22.0279 10.5833C22.0852 10.5432 22.1426 10.5032 22.2 10.5C23.3297 9.87187 24 9.09375 24 8.25V6.59063C23.4141 7.07344 22.7063 7.46719 21.9422 7.78594C20.9109 8.2125 19.6969 8.54063 18.3703 8.74688Z" fill="#232323"/> +<path d="M22.2 6C23.3297 5.37187 24 4.59422 24 3.75C24 1.67906 19.9688 0 15 0C9.98906 0 6 1.67906 6 3.75C6 4.59422 6.67031 5.37187 7.8 6C7.80937 6.00469 7.81758 6.00937 7.82578 6.01406C7.83398 6.01875 7.84219 6.02344 7.85156 6.02813C8.23125 6.00938 8.61094 6 9 6C11.6344 6 14.0906 6.44062 15.9422 7.21406C16.1203 7.28906 16.2984 7.36875 16.4672 7.44844C18.8062 7.28906 20.8359 6.75469 22.2 6Z" fill="#D12B41"/> +<path d="M19.9435 12.9151C19.7958 12.9551 19.6477 12.9951 19.5 13.0359V13.5C20.7602 13.5 21.9296 13.8885 22.8951 14.5522C23.5995 14.0172 24 13.4028 24 12.75V11.0906C23.4141 11.5734 22.7063 11.9672 21.9422 12.2859C21.3382 12.5376 20.6447 12.7253 19.9435 12.9151Z" fill="#D12B41"/> +<path d="M18.3703 8.74688C19.0031 9.37969 19.5 10.2234 19.5 11.25V11.4984C20.4328 11.2734 21.2625 10.9781 21.9469 10.6359C21.9739 10.6209 22.0009 10.6021 22.0279 10.5833C22.0852 10.5432 22.1426 10.5032 22.2 10.5C23.3297 9.87187 24 9.09375 24 8.25V6.59063C23.4141 7.07344 22.7063 7.46719 21.9422 7.78594C20.9109 8.2125 19.6969 8.54063 18.3703 8.74688Z" fill="#D12B41"/> </g> -<path d="M16.2 13.5C17.3297 12.8719 18 12.0938 18 11.25C18 9.17813 13.9688 7.5 9 7.5C4.02938 7.5 0 9.17813 0 11.25C0 12.0938 0.669375 12.8719 1.79953 13.5C1.85443 13.5031 1.91057 13.5415 1.96782 13.5807C1.9966 13.6004 2.02567 13.6203 2.055 13.6359C3.70594 14.4703 6.20625 15 9 15C11.9438 15 14.5594 14.4094 16.2 13.5Z" fill="#232323"/> -<path d="M14.8788 15.6729C13.1948 16.2046 11.1571 16.5 9 16.5C6.36562 16.5 3.91125 16.0594 2.05922 15.2859C1.29469 14.9672 0.583594 14.5734 0 14.0906V15.75C0 16.5938 0.669375 17.3719 1.79953 18C3.44109 18.9094 6.05625 19.5 9 19.5C10.6471 19.5 12.1916 19.3159 13.5211 18.9937C13.6261 17.7367 14.1186 16.5898 14.8788 15.6729Z" fill="#232323"/> -<path d="M13.5862 20.5191C13.7529 21.4936 14.1547 22.3879 14.731 23.1415C13.1742 23.6778 11.1771 24 9 24C4.02938 24 0 22.3219 0 20.25V18.5906C0.583594 19.0734 1.29469 19.4672 2.05922 19.7859C3.91125 20.5594 6.36562 21 9 21C10.6307 21 12.1932 20.8312 13.5862 20.5191Z" fill="#232323"/> -<path d="M24 19.5C24 21.9844 21.9844 24 19.5 24C17.0156 24 15 21.9844 15 19.5C15 17.0156 17.0156 15 19.5 15C21.9844 15 24 17.0156 24 19.5ZM19 17.4719V18.9719H17.5C17.225 18.9719 17 19.225 17 19.4719C17 19.775 17.225 19.9719 17.5 19.9719H19V21.4719C19 21.775 19.225 21.9719 19.5 21.9719C19.775 21.9719 20 21.775 20 21.4719V19.9719H21.5C21.775 19.9719 22 19.775 22 19.4719C22 19.225 21.775 18.9719 21.5 18.9719H20V17.4719C20 17.225 19.775 16.9719 19.5 16.9719C19.225 16.9719 19 17.225 19 17.4719Z" fill="#232323"/> +<path d="M16.2 13.5C17.3297 12.8719 18 12.0938 18 11.25C18 9.17813 13.9688 7.5 9 7.5C4.02938 7.5 0 9.17813 0 11.25C0 12.0938 0.669375 12.8719 1.79953 13.5C1.85443 13.5031 1.91057 13.5415 1.96782 13.5807C1.9966 13.6004 2.02567 13.6203 2.055 13.6359C3.70594 14.4703 6.20625 15 9 15C11.9438 15 14.5594 14.4094 16.2 13.5Z" fill="#D12B41"/> +<path d="M14.8788 15.6729C13.1948 16.2046 11.1571 16.5 9 16.5C6.36562 16.5 3.91125 16.0594 2.05922 15.2859C1.29469 14.9672 0.583594 14.5734 0 14.0906V15.75C0 16.5938 0.669375 17.3719 1.79953 18C3.44109 18.9094 6.05625 19.5 9 19.5C10.6471 19.5 12.1916 19.3159 13.5211 18.9937C13.6261 17.7367 14.1186 16.5898 14.8788 15.6729Z" fill="#D12B41"/> +<path d="M13.5862 20.5191C13.7529 21.4936 14.1547 22.3879 14.731 23.1415C13.1742 23.6778 11.1771 24 9 24C4.02938 24 0 22.3219 0 20.25V18.5906C0.583594 19.0734 1.29469 19.4672 2.05922 19.7859C3.91125 20.5594 6.36562 21 9 21C10.6307 21 12.1932 20.8312 13.5862 20.5191Z" fill="#D12B41"/> +<path d="M24 19.5C24 21.9844 21.9844 24 19.5 24C17.0156 24 15 21.9844 15 19.5C15 17.0156 17.0156 15 19.5 15C21.9844 15 24 17.0156 24 19.5ZM19 17.4719V18.9719H17.5C17.225 18.9719 17 19.225 17 19.4719C17 19.775 17.225 19.9719 17.5 19.9719H19V21.4719C19 21.775 19.225 21.9719 19.5 21.9719C19.775 21.9719 20 21.775 20 21.4719V19.9719H21.5C21.775 19.9719 22 19.775 22 19.4719C22 19.225 21.775 18.9719 21.5 18.9719H20V17.4719C20 17.225 19.775 16.9719 19.5 16.9719C19.225 16.9719 19 17.225 19 17.4719Z" fill="#D12B41"/> +</g> +<defs> +<clipPath id="clip0_908_22491"> +<rect width="24" height="24" fill="white"/> +</clipPath> +</defs> </svg> diff --git a/assets/svg/fruitSorbet/exchange-2.svg b/assets/svg/fruitSorbet/exchange-2.svg index 11e246a3b..0310a3386 100644 --- a/assets/svg/fruitSorbet/exchange-2.svg +++ b/assets/svg/fruitSorbet/exchange-2.svg @@ -1,4 +1,4 @@ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M14.6695 1.06575C15.1855 0.607104 15.9756 0.65358 16.4343 1.16956L20.4343 5.66956C20.8552 6.14317 20.8552 6.85686 20.4343 7.33047L16.4343 11.8305C15.9756 12.3464 15.1855 12.3929 14.6695 11.9343C14.1536 11.4756 14.1071 10.6855 14.5657 10.1696L16.7164 7.75001H6C4.48122 7.75001 3.25 8.98123 3.25 10.5C3.25 11.1904 2.69036 11.75 2 11.75C1.30964 11.75 0.75 11.1904 0.75 10.5C0.75 7.60052 3.10051 5.25001 6 5.25001H16.7164L14.5657 2.83047C14.1071 2.31449 14.1536 1.5244 14.6695 1.06575Z" fill="#232323"/> -<path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M9.33045 23.4342C8.81448 23.8929 8.02439 23.8464 7.56574 23.3304L3.56574 18.8304C3.14475 18.3568 3.14475 17.6431 3.56574 17.1695L7.56574 12.6695C8.02439 12.1536 8.81448 12.1071 9.33046 12.5657C9.84643 13.0244 9.89291 13.8145 9.43426 14.3304L7.28355 16.75L18 16.75C19.5188 16.75 20.75 15.5188 20.75 14C20.75 13.3096 21.3096 12.75 22 12.75C22.6904 12.75 23.25 13.3096 23.25 14C23.25 16.8995 20.8995 19.25 18 19.25L7.28355 19.25L9.43426 21.6695C9.89291 22.1855 9.84643 22.9756 9.33045 23.4342Z" fill="#232323"/> +<path d="M19.5 6.5H6C3.79086 6.5 2 8.29086 2 10.5M19.5 6.5L15.5 2M19.5 6.5L15.5 11" stroke="#D12B41" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/> +<path opacity="0.4" d="M4.5 18L18 18C20.2091 18 22 16.2091 22 14M4.5 18L8.5 22.5M4.5 18L8.5 13.5" stroke="#D12B41" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/> </svg> From dc2f34477928b5b99d540be34ba6910e74ffbc1c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 18:37:04 -0600 Subject: [PATCH 095/123] bottom nav text color change for fruit sorbet --- lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart | 5 ++++- lib/utilities/text_styles.dart | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart index 379362dbc..19a785de5 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart @@ -175,7 +175,7 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> { children: [ Text( "Paynym", - style: STextStyles.w600_12(context), + style: STextStyles.buttonSmall(context), ), const SizedBox( width: 16, @@ -184,6 +184,9 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> { Assets.svg.robotHead, height: 20, width: 20, + color: Theme.of(context) + .extension<StackColors>()! + .bottomNavIconIcon, ), ], ), diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart index 6af4f6d9c..91e06e45b 100644 --- a/lib/utilities/text_styles.dart +++ b/lib/utilities/text_styles.dart @@ -1065,7 +1065,7 @@ class STextStyles { ); case ThemeType.fruitSorbet: return GoogleFonts.inter( - color: _theme(context).textDark, + color: _theme(context).bottomNavIconIcon, fontWeight: FontWeight.w500, fontSize: 12, ); From 588d715a6149f077fe851c564342c80a10a2d56e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 31 Jan 2023 19:26:23 -0600 Subject: [PATCH 096/123] only clear out wallet utxos on refresh --- lib/services/coins/bitcoin/bitcoin_wallet.dart | 4 +++- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 2 +- lib/services/coins/dogecoin/dogecoin_wallet.dart | 2 +- lib/services/coins/firo/firo_wallet.dart | 2 +- lib/services/coins/litecoin/litecoin_wallet.dart | 2 +- lib/services/coins/namecoin/namecoin_wallet.dart | 2 +- lib/services/coins/particl/particl_wallet.dart | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 2d2f5b590..6a7898272 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1858,7 +1858,7 @@ class BitcoinWallet extends CoinServiceAPI // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); @@ -2278,6 +2278,8 @@ class BitcoinWallet extends CoinServiceAPI Logging.instance.log("spendableOutputs.length: ${spendableOutputs.length}", level: LogLevel.Info); + Logging.instance.log("availableOutputs.length: ${availableOutputs.length}", + level: LogLevel.Info); Logging.instance .log("spendableOutputs: $spendableOutputs", level: LogLevel.Info); Logging.instance.log("spendableSatoshiValue: $spendableSatoshiValue", diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index a84c8f09e..84fb7f473 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -1673,7 +1673,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 7dc3bc6f9..45f20b763 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -1620,7 +1620,7 @@ class DogecoinWallet extends CoinServiceAPI // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 7758d4e0c..03e788e54 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -3665,7 +3665,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index 779a9ba54..b0de62f75 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -1784,7 +1784,7 @@ class LitecoinWallet extends CoinServiceAPI // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index f074ca0ef..470a6a0bc 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -1763,7 +1763,7 @@ class NamecoinWallet extends CoinServiceAPI // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index e4e419892..3a63204a8 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -1659,7 +1659,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); From bc5dc9a5d7a1a779fa3c6ffe16537e5b6f22d3bd Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 09:29:51 -0600 Subject: [PATCH 097/123] simple receiving addresses list view --- lib/models/isar/models/address/address.dart | 2 + lib/pages/receive_view/receive_view.dart | 81 +++++++++++++ .../receiving_addresses_view.dart | 114 ++++++++++++++++++ lib/route_generator.dart | 16 +++ 4 files changed, 213 insertions(+) create mode 100644 lib/pages/receive_view/receiving_addresses_view.dart diff --git a/lib/models/isar/models/address/address.dart b/lib/models/isar/models/address/address.dart index c3e885f3e..1f0d48f8f 100644 --- a/lib/models/isar/models/address/address.dart +++ b/lib/models/isar/models/address/address.dart @@ -69,6 +69,7 @@ class Address extends CryptoCurrencyAddress { "}"; } +// do not modify enum AddressType { p2pkh, p2sh, @@ -79,6 +80,7 @@ enum AddressType { nonWallet, } +// do not modify enum AddressSubType { receiving, change, diff --git a/lib/pages/receive_view/receive_view.dart b/lib/pages/receive_view/receive_view.dart index b6ae7c70a..2d7d11b45 100644 --- a/lib/pages/receive_view/receive_view.dart +++ b/lib/pages/receive_view/receive_view.dart @@ -7,10 +7,12 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/receive_view/generate_receiving_uri_qr_code_view.dart'; +import 'package:stackwallet/pages/receive_view/receiving_addresses_view.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; @@ -19,6 +21,7 @@ import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/custom_loading_overlay.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:tuple/tuple.dart'; class ReceiveView extends ConsumerStatefulWidget { const ReceiveView({ @@ -128,6 +131,84 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> { "Receive ${coin.ticker}", style: STextStyles.navBarTitle(context), ), + actions: [ + Padding( + padding: const EdgeInsets.only( + top: 10, + bottom: 10, + right: 10, + ), + child: AspectRatio( + aspectRatio: 1, + child: AppBarIconButton( + key: const Key("walletNetworkSettingsAddNewNodeViewButton"), + size: 36, + shadows: const [], + color: Theme.of(context).extension<StackColors>()!.background, + icon: SvgPicture.asset( + Assets.svg.verticalEllipsis, + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark, + width: 20, + height: 20, + ), + onPressed: () { + showDialog<dynamic>( + barrierColor: Colors.transparent, + barrierDismissible: true, + context: context, + builder: (_) { + return Stack( + children: [ + Positioned( + top: 9, + right: 10, + child: Container( + decoration: BoxDecoration( + color: Theme.of(context) + .extension<StackColors>()! + .popupBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + // boxShadow: [CFColors.standardBoxShadow], + boxShadow: const [], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GestureDetector( + onTap: () { + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + ReceivingAddressesView.routeName, + arguments: Tuple2(walletId, false), + ); + }, + child: RoundedWhiteContainer( + child: Material( + color: Colors.transparent, + child: Text( + "Address list", + style: STextStyles.baseXS(context), + ), + ), + ), + ), + ], + ), + ), + ), + ], + ); + }, + ); + }, + ), + ), + ), + ], ), body: Padding( padding: const EdgeInsets.all(12), diff --git a/lib/pages/receive_view/receiving_addresses_view.dart b/lib/pages/receive_view/receiving_addresses_view.dart new file mode 100644 index 000000000..260e33cd1 --- /dev/null +++ b/lib/pages/receive_view/receiving_addresses_view.dart @@ -0,0 +1,114 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:isar/isar.dart'; +import 'package:stackwallet/db/main_db.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/loading_indicator.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; + +class ReceivingAddressesView extends ConsumerWidget { + const ReceivingAddressesView({ + Key? key, + required this.walletId, + required this.isDesktop, + this.clipboard = const ClipboardWrapper(), + }) : super(key: key); + + static const String routeName = "/receivingAddressesView"; + + final String walletId; + final bool isDesktop; + final ClipboardInterface clipboard; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: Scaffold( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + appBar: AppBar( + backgroundColor: + Theme.of(context).extension<StackColors>()!.backgroundAppBar, + leading: AppBarBackButton( + onPressed: () { + Navigator.of(context).pop(); + }, + ), + title: Text( + "Receiving addresses", + style: STextStyles.navBarTitle(context), + ), + ), + body: Padding( + padding: const EdgeInsets.all(16), + child: child, + ), + ), + ), + child: FutureBuilder( + future: MainDB.instance + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.receiving) + .and() + .not() + .typeEqualTo(AddressType.nonWallet) + .sortByDerivationIndexDesc() + .findAll(), + builder: (context, AsyncSnapshot<List<Address>> snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.data != null) { + // listview + return ListView.separated( + itemCount: snapshot.data!.length, + separatorBuilder: (_, __) => Container( + height: 10, + ), + itemBuilder: (_, index) => AddressCard( + address: snapshot.data![index], + ), + ); + } else { + return const Center( + child: LoadingIndicator( + height: 200, + width: 200, + ), + ); + } + }, + ), + ); + } +} + +class AddressCard extends StatelessWidget { + const AddressCard({ + Key? key, + required this.address, + }) : super(key: key); + + final Address address; + + @override + Widget build(BuildContext context) { + return RoundedWhiteContainer( + child: Row( + children: [ + Text( + address.value, + style: STextStyles.itemSubtitle12(context), + ) + ], + ), + ); + } +} diff --git a/lib/route_generator.dart b/lib/route_generator.dart index d73fb71e4..970246043 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -46,6 +46,7 @@ import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart'; import 'package:stackwallet/pages/receive_view/generate_receiving_uri_qr_code_view.dart'; import 'package:stackwallet/pages/receive_view/receive_view.dart'; +import 'package:stackwallet/pages/receive_view/receiving_addresses_view.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; import 'package:stackwallet/pages/send_view/send_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/about_view.dart'; @@ -820,6 +821,21 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case ReceivingAddressesView.routeName: + if (args is Tuple2<String, bool>) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => ReceivingAddressesView( + walletId: args.item1, + isDesktop: args.item2, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case SendView.routeName: if (args is Tuple2<String, Coin>) { return getRoute( From 266a433aa374659be8ef14098e18c114790be08a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 10:08:30 -0600 Subject: [PATCH 098/123] add paynym share --- lib/pages/paynym/paynym_home_view.dart | 22 ++++++++++++-- lib/utilities/util.dart | 9 ++++++ macos/Flutter/GeneratedPluginRegistrant.swift | 2 +- pubspec.lock | 30 +------------------ pubspec.yaml | 2 +- .../flutter/generated_plugin_registrant.cc | 3 ++ windows/flutter/generated_plugins.cmake | 1 + 7 files changed, 36 insertions(+), 33 deletions(-) diff --git a/lib/pages/paynym/paynym_home_view.dart b/lib/pages/paynym/paynym_home_view.dart index 4d4efeb0d..b34c05b12 100644 --- a/lib/pages/paynym/paynym_home_view.dart +++ b/lib/pages/paynym/paynym_home_view.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:share_plus/share_plus.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/paynym/add_new_paynym_follow_view.dart'; import 'package:stackwallet/pages/paynym/dialogs/paynym_qr_popup.dart'; @@ -358,8 +359,25 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { .extension<StackColors>()! .textDark, ), - onPressed: () { - // copy to clipboard + onPressed: () async { + Rect? sharePositionOrigin; + if (await Util.isIPad) { + final box = + context.findRenderObject() as RenderBox?; + if (box != null) { + sharePositionOrigin = + box.localToGlobal(Offset.zero) & box.size; + } + } + + await Share.share( + ref + .read(myPaynymAccountStateProvider.state) + .state! + .codes + .first + .code, + sharePositionOrigin: sharePositionOrigin); }, ), ), diff --git a/lib/utilities/util.dart b/lib/utilities/util.dart index 2940b6d40..6a31fae04 100644 --- a/lib/utilities/util.dart +++ b/lib/utilities/util.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/material.dart'; abstract class Util { @@ -22,6 +23,14 @@ abstract class Util { return Platform.isLinux || Platform.isMacOS || Platform.isWindows; } + static Future<bool> get isIPad async { + final deviceInfo = (await DeviceInfoPlugin().deviceInfo); + if (deviceInfo is IosDeviceInfo) { + return (deviceInfo).name?.toLowerCase().contains("ipad") == true; + } + return false; + } + static MaterialColor createMaterialColor(Color color) { List<double> strengths = <double>[.05]; final swatch = <int, Color>{}; diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 59063791f..7c5023a1c 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -14,7 +14,7 @@ import flutter_secure_storage_macos import isar_flutter_libs import package_info_plus_macos import path_provider_macos -import share_plus_macos +import share_plus import shared_preferences_macos import stack_wallet_backup import url_launcher_macos diff --git a/pubspec.lock b/pubspec.lock index 073ef8a47..5949543b2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1237,21 +1237,7 @@ packages: name: share_plus url: "https://pub.dartlang.org" source: hosted - version: "4.5.3" - share_plus_linux: - dependency: transitive - description: - name: share_plus_linux - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - share_plus_macos: - dependency: transitive - description: - name: share_plus_macos - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" + version: "6.3.0" share_plus_platform_interface: dependency: transitive description: @@ -1259,20 +1245,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.2.0" - share_plus_web: - dependency: transitive - description: - name: share_plus_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - share_plus_windows: - dependency: transitive - description: - name: share_plus_windows - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" shared_preferences: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 6cba3b460..61c22e7aa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -126,7 +126,7 @@ dependencies: tuple: ^2.0.0 flutter_riverpod: ^1.0.3 qr_flutter: ^4.0.0 - share_plus: ^4.0.10 + share_plus: ^6.3.0 emojis: ^0.9.9 pointycastle: ^3.6.0 package_info_plus: ^1.4.2 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 98655fe05..e265edffe 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -11,6 +11,7 @@ #include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h> #include <isar_flutter_libs/isar_flutter_libs_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h> +#include <share_plus/share_plus_windows_plugin_c_api.h> #include <stack_wallet_backup/stack_wallet_backup_plugin_c_api.h> #include <url_launcher_windows/url_launcher_windows.h> #include <window_size/window_size_plugin.h> @@ -26,6 +27,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin")); PermissionHandlerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); StackWalletBackupPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("StackWalletBackupPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 4426d9497..6a4a3acbf 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -8,6 +8,7 @@ list(APPEND FLUTTER_PLUGIN_LIST flutter_secure_storage_windows isar_flutter_libs permission_handler_windows + share_plus stack_wallet_backup url_launcher_windows window_size From 68be62e3ef2003b2425859042c05a61a46a51c8e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 10:38:49 -0600 Subject: [PATCH 099/123] bch fetch derivation by address fix --- .../coins/bitcoincash/bitcoincash_wallet.dart | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 84fb7f473..af495fba7 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2601,13 +2601,12 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { final n = output["n"]; if (n != null && n == utxosToUse[i].vout) { String address = output["scriptPubKey"]["addresses"][0] as String; - if (bitbox.Address.detectFormat(address) == + if (bitbox.Address.detectFormat(address) != bitbox.Address.formatCashAddr) { - if (validateCashAddr(address)) { - address = bitbox.Address.toLegacyAddress(address); - } else { - throw Exception( - "Unsupported address found during fetchBuildTxData(): $address"); + try { + address = bitbox.Address.toCashAddress(address); + } catch (_) { + rethrow; } } if (!addressTxid.containsKey(address)) { From b64ffe91b780cd9fea0f9966b99b6ba2385fcedd Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 11:23:09 -0600 Subject: [PATCH 100/123] paynym receiving address scanning fix --- .../mixins/paynym_wallet_interface.dart | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 9300e10a2..5bfbbe068 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -162,7 +162,21 @@ mixin PaynymWalletInterface { if (address == null) { final generatedAddress = await _generatePaynymReceivingAddress(sender, 0); - await _db.putAddress(generatedAddress); + + final existing = await _db + .getAddresses(_walletId) + .filter() + .valueEqualTo(generatedAddress.value) + .findFirst(); + + if (existing == null) { + // Add that new address + await _db.putAddress(generatedAddress); + } else { + // we need to update the address + await _db.updateAddress(existing, generatedAddress); + } + return currentReceivingPaynymAddress(sender); } else { return address; @@ -203,7 +217,22 @@ mixin PaynymWalletInterface { sender, address.derivationIndex + 1, ); - await _db.putAddress(nextAddress); + + final existing = await _db + .getAddresses(_walletId) + .filter() + .valueEqualTo(nextAddress.value) + .findFirst(); + + if (existing == null) { + // Add that new address + await _db.putAddress(nextAddress); + } else { + // we need to update the address + await _db.updateAddress(existing, nextAddress); + } + // keep checking until address with no tx history is set as current + await checkCurrentPaynymReceivingAddressForTransactions(sender); } } From 6a076724372c1dc248f249b03655643808bf0c77 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 15:02:41 -0600 Subject: [PATCH 101/123] paynym mobile ui sizing changes --- .../paynym/dialogs/paynym_details_popup.dart | 42 +++++----- lib/pages/paynym/dialogs/paynym_qr_popup.dart | 15 ++-- lib/pages/paynym/paynym_home_view.dart | 30 +++---- .../subwidgets/desktop_paynym_details.dart | 2 +- lib/pages/paynym/subwidgets/paynym_card.dart | 6 +- .../paynym/subwidgets/paynym_card_button.dart | 6 +- lib/utilities/text_styles.dart | 80 +++++++++++++++++-- .../paynym_follow_toggle_button.dart | 12 +-- lib/widgets/desktop/secondary_button.dart | 10 +++ 9 files changed, 146 insertions(+), 57 deletions(-) diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index 83860280b..729ed5941 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -176,7 +176,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { children: [ PayNymBot( paymentCodeString: widget.accountLite.code, - size: 32, + size: 36, ), const SizedBox( width: 12, @@ -186,7 +186,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { children: [ Text( widget.accountLite.nymName, - style: STextStyles.w600_12(context), + style: STextStyles.w600_14(context), ), FutureBuilder( future: @@ -204,7 +204,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { ), Text( "Connected", - style: STextStyles.w500_10(context) + style: STextStyles.w500_12(context) .copyWith( color: Theme.of(context) .extension<StackColors>()! @@ -230,33 +230,33 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { if (snapshot.data!) { return PrimaryButton( label: "Send", - buttonHeight: ButtonHeight.l, + buttonHeight: ButtonHeight.xl, icon: SvgPicture.asset( Assets.svg.circleArrowUpRight, - width: 10, - height: 10, + width: 14, + height: 14, color: Theme.of(context) .extension<StackColors>()! .buttonTextPrimary, ), - iconSpacing: 4, - width: 86, + iconSpacing: 8, + width: 100, onPressed: _onSend, ); } else { return PrimaryButton( label: "Connect", - buttonHeight: ButtonHeight.l, + buttonHeight: ButtonHeight.xl, icon: SvgPicture.asset( Assets.svg.circlePlusFilled, - width: 10, - height: 10, + width: 13, + height: 13, color: Theme.of(context) .extension<StackColors>()! .buttonTextPrimary, ), - iconSpacing: 4, - width: 86, + iconSpacing: 8, + width: 128, onPressed: _onConnectPressed, ); } @@ -291,6 +291,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { color: Theme.of(context) .extension<StackColors>()! .warningForeground, + fontSize: 12, ), ), ), @@ -321,7 +322,9 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { children: [ Text( "PayNym address", - style: STextStyles.infoSmall(context), + style: STextStyles.infoSmall(context).copyWith( + fontSize: 12, + ), ), const SizedBox( height: 6, @@ -332,6 +335,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { color: Theme.of(context) .extension<StackColors>()! .textDark, + fontSize: 12, ), ), const SizedBox( @@ -346,7 +350,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { ), QrImage( padding: const EdgeInsets.all(0), - size: 86, + size: 100, data: widget.accountLite.code, foregroundColor: Theme.of(context).extension<StackColors>()!.textDark, @@ -375,16 +379,16 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { Expanded( child: SecondaryButton( label: "Copy", - buttonHeight: ButtonHeight.l, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: SvgPicture.asset( Assets.svg.copy, - width: 10, - height: 10, + width: 12, + height: 12, color: Theme.of(context) .extension<StackColors>()! .buttonTextSecondary, ), - iconSpacing: 4, onPressed: () async { await Clipboard.setData( ClipboardData( diff --git a/lib/pages/paynym/dialogs/paynym_qr_popup.dart b/lib/pages/paynym/dialogs/paynym_qr_popup.dart index e712884b1..3ad985472 100644 --- a/lib/pages/paynym/dialogs/paynym_qr_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_qr_popup.dart @@ -56,7 +56,7 @@ class PaynymQrPopup extends StatelessWidget { children: [ PayNymBot( paymentCodeString: paynymAccount.codes.first.code, - size: isDesktop ? 56 : 32, + size: isDesktop ? 56 : 36, ), const SizedBox( width: 12, @@ -65,7 +65,7 @@ class PaynymQrPopup extends StatelessWidget { paynymAccount.nymName, style: isDesktop ? STextStyles.w500_24(context) - : STextStyles.w600_12(context), + : STextStyles.w600_14(context), ), ], ), @@ -87,7 +87,7 @@ class PaynymQrPopup extends StatelessWidget { children: [ Expanded( child: ConstrainedBox( - constraints: const BoxConstraints(minHeight: 107), + constraints: const BoxConstraints(minHeight: 130), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -100,7 +100,9 @@ class PaynymQrPopup extends StatelessWidget { .extension<StackColors>()! .textSubtitle1, ) - : STextStyles.infoSmall(context), + : STextStyles.infoSmall(context).copyWith( + fontSize: 12, + ), ), const SizedBox( height: 6, @@ -113,6 +115,7 @@ class PaynymQrPopup extends StatelessWidget { color: Theme.of(context) .extension<StackColors>()! .textDark, + fontSize: 12, ), ), const SizedBox( @@ -120,7 +123,7 @@ class PaynymQrPopup extends StatelessWidget { ), CustomTextButton( text: "Copy", - textSize: isDesktop ? 18 : 10, + textSize: isDesktop ? 18 : 14, onTap: () async { await Clipboard.setData( ClipboardData( @@ -146,7 +149,7 @@ class PaynymQrPopup extends StatelessWidget { ), QrImage( padding: const EdgeInsets.all(0), - size: 107, + size: 130, data: paynymAccount.codes.first.code, foregroundColor: Theme.of(context).extension<StackColors>()!.textDark, diff --git a/lib/pages/paynym/paynym_home_view.dart b/lib/pages/paynym/paynym_home_view.dart index b34c05b12..96baa5daf 100644 --- a/lib/pages/paynym/paynym_home_view.dart +++ b/lib/pages/paynym/paynym_home_view.dart @@ -303,7 +303,9 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { .code, 12, 5), - style: STextStyles.label(context), + style: STextStyles.label(context).copyWith( + fontSize: 14, + ), ), const SizedBox( height: 11, @@ -313,11 +315,11 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { Expanded( child: SecondaryButton( label: "Copy", - buttonHeight: ButtonHeight.l, - iconSpacing: 4, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: CopyIcon( - width: 10, - height: 10, + width: 12, + height: 12, color: Theme.of(context) .extension<StackColors>()! .textDark, @@ -350,11 +352,11 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { Expanded( child: SecondaryButton( label: "Share", - buttonHeight: ButtonHeight.l, - iconSpacing: 4, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: ShareIcon( - width: 10, - height: 10, + width: 12, + height: 12, color: Theme.of(context) .extension<StackColors>()! .textDark, @@ -387,11 +389,11 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { Expanded( child: SecondaryButton( label: "Address", - buttonHeight: ButtonHeight.l, - iconSpacing: 4, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: QrCodeIcon( - width: 10, - height: 10, + width: 12, + height: 12, color: Theme.of(context) .extension<StackColors>()! .textDark, @@ -554,7 +556,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { child: child, ), child: SizedBox( - height: isDesktop ? 56 : 40, + height: isDesktop ? 56 : 48, width: isDesktop ? 490 : null, child: Toggle( onColor: Theme.of(context).extension<StackColors>()!.popupBG, diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index fd89999d6..2f7f05e9a 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -171,7 +171,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { children: [ PayNymBot( paymentCodeString: widget.accountLite.code, - size: 32, + size: 36, ), const SizedBox( width: 12, diff --git a/lib/pages/paynym/subwidgets/paynym_card.dart b/lib/pages/paynym/subwidgets/paynym_card.dart index be989a588..644e9e9bf 100644 --- a/lib/pages/paynym/subwidgets/paynym_card.dart +++ b/lib/pages/paynym/subwidgets/paynym_card.dart @@ -37,7 +37,7 @@ class _PaynymCardState extends State<PaynymCard> { child: Row( children: [ PayNymBot( - size: 32, + size: 36, paymentCodeString: widget.paymentCodeString, ), const SizedBox( @@ -56,7 +56,7 @@ class _PaynymCardState extends State<PaynymCard> { .extension<StackColors>()! .textFieldActiveText, ) - : STextStyles.w500_12(context), + : STextStyles.w500_14(context), ), const SizedBox( height: 2, @@ -65,7 +65,7 @@ class _PaynymCardState extends State<PaynymCard> { Format.shorten(widget.paymentCodeString, 12, 5), style: isDesktop ? STextStyles.desktopTextExtraExtraSmall(context) - : STextStyles.w500_12(context).copyWith( + : STextStyles.w500_14(context).copyWith( color: Theme.of(context) .extension<StackColors>()! .textSubtitle1, diff --git a/lib/pages/paynym/subwidgets/paynym_card_button.dart b/lib/pages/paynym/subwidgets/paynym_card_button.dart index 75c4d2cc0..6e51c85f8 100644 --- a/lib/pages/paynym/subwidgets/paynym_card_button.dart +++ b/lib/pages/paynym/subwidgets/paynym_card_button.dart @@ -77,7 +77,7 @@ class _PaynymCardButtonState extends ConsumerState<PaynymCardButton> { child: Row( children: [ PayNymBot( - size: 32, + size: 36, paymentCodeString: widget.accountLite.code, ), const SizedBox( @@ -96,7 +96,7 @@ class _PaynymCardButtonState extends ConsumerState<PaynymCardButton> { .extension<StackColors>()! .textFieldActiveText, ) - : STextStyles.w500_12(context), + : STextStyles.w500_14(context), ), const SizedBox( height: 2, @@ -105,7 +105,7 @@ class _PaynymCardButtonState extends ConsumerState<PaynymCardButton> { Format.shorten(widget.accountLite.code, 12, 5), style: isDesktop ? STextStyles.desktopTextExtraExtraSmall(context) - : STextStyles.w500_12(context).copyWith( + : STextStyles.w500_14(context).copyWith( color: Theme.of(context) .extension<StackColors>()! .textSubtitle1, diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart index 91e06e45b..98878b6b6 100644 --- a/lib/utilities/text_styles.dart +++ b/lib/utilities/text_styles.dart @@ -13,31 +13,31 @@ class STextStyles { return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); case ThemeType.oceanBreeze: return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); case ThemeType.dark: return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); case ThemeType.oledBlack: return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); case ThemeType.fruitSorbet: return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); } } @@ -932,6 +932,76 @@ class STextStyles { } } + static TextStyle w600_14(BuildContext context) { + switch (_theme(context).themeType) { + case ThemeType.light: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + case ThemeType.oceanBreeze: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + case ThemeType.dark: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + case ThemeType.oledBlack: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + case ThemeType.fruitSorbet: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + } + } + + static TextStyle w500_14(BuildContext context) { + switch (_theme(context).themeType) { + case ThemeType.light: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + case ThemeType.oceanBreeze: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + case ThemeType.dark: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + case ThemeType.oledBlack: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + case ThemeType.fruitSorbet: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + } + } + static TextStyle w500_12(BuildContext context) { switch (_theme(context).themeType) { case ThemeType.light: diff --git a/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart b/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart index 5591a5ff3..e4235fef4 100644 --- a/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart +++ b/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart @@ -272,8 +272,8 @@ class _PaynymFollowToggleButtonState switch (widget.style) { case PaynymFollowToggleButtonStyle.primary: return PrimaryButton( - width: isDesktop ? 120 : 84, - buttonHeight: isDesktop ? ButtonHeight.s : ButtonHeight.l, + width: isDesktop ? 120 : 100, + buttonHeight: isDesktop ? ButtonHeight.s : ButtonHeight.xl, label: isFollowing ? "Unfollow" : "Follow", onPressed: _onPressed, ); @@ -281,15 +281,15 @@ class _PaynymFollowToggleButtonState case PaynymFollowToggleButtonStyle.detailsPopup: return SecondaryButton( label: isFollowing ? "Unfollow" : "Follow", - buttonHeight: ButtonHeight.l, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: SvgPicture.asset( isFollowing ? Assets.svg.userMinus : Assets.svg.userPlus, - width: 10, - height: 10, + width: 16, + height: 16, color: Theme.of(context).extension<StackColors>()!.buttonTextSecondary, ), - iconSpacing: 4, onPressed: _onPressed, ); diff --git a/lib/widgets/desktop/secondary_button.dart b/lib/widgets/desktop/secondary_button.dart index 6dba6fdd8..6b4e46221 100644 --- a/lib/widgets/desktop/secondary_button.dart +++ b/lib/widgets/desktop/secondary_button.dart @@ -78,6 +78,16 @@ class SecondaryButton extends StatelessWidget { .buttonTextSecondaryDisabled, ); } + if (buttonHeight == ButtonHeight.xl) { + return STextStyles.button(context).copyWith( + fontSize: 14, + color: enabled + ? Theme.of(context).extension<StackColors>()!.buttonTextSecondary + : Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondaryDisabled, + ); + } return STextStyles.button(context).copyWith( color: enabled ? Theme.of(context).extension<StackColors>()!.buttonTextSecondary From 72cb62774c9ce0f4135e1f04834611637210086b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 15:19:32 -0600 Subject: [PATCH 102/123] revert and modify tx size calc for two outputs --- lib/services/coins/bitcoin/bitcoin_wallet.dart | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 6a7898272..525b06d70 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'dart:math'; import 'package:bech32/bech32.dart'; import 'package:bip32/bip32.dart' as bip32; @@ -2387,11 +2388,9 @@ class BitcoinWallet extends CoinServiceAPI ], satoshiAmounts: [ satoshiAmountToSend, - // this can cause a problem where the output value is negative so commenting out for now - // satoshisBeingUsed - satoshiAmountToSend - 1 - // and using dust limit instead - DUST_LIMIT, - ], // dust limit is the minimum amount a change output should be + // should/can we just set this to 0 ? + max(0, satoshisBeingUsed - satoshiAmountToSend - 1), + ], ))["vSize"] as int; // Assume 1 output, only for recipient and no change From 9dc5f91a043a5818b0380f1d9a8d6d47ad577e02 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 15:37:58 -0600 Subject: [PATCH 103/123] add logging to fee btc calc --- .../coins/bitcoin/bitcoin_wallet.dart | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 525b06d70..c4ad5266b 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -2373,25 +2373,38 @@ class BitcoinWallet extends CoinServiceAPI return transactionObject; } - final int vSizeForOneOutput = (await buildTransaction( - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - recipients: [_recipientAddress], - satoshiAmounts: [satoshisBeingUsed - 1], - ))["vSize"] as int; - final int vSizeForTwoOutPuts = (await buildTransaction( - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - recipients: [ - _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), - ], - satoshiAmounts: [ - satoshiAmountToSend, - // should/can we just set this to 0 ? - max(0, satoshisBeingUsed - satoshiAmountToSend - 1), - ], - ))["vSize"] as int; + final int vSizeForOneOutput; + try { + vSizeForOneOutput = (await buildTransaction( + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + recipients: [_recipientAddress], + satoshiAmounts: [satoshisBeingUsed - 1], + ))["vSize"] as int; + } catch (e) { + Logging.instance.log("vSizeForOneOutput: $e", level: LogLevel.Error); + rethrow; + } + + final int vSizeForTwoOutPuts; + try { + vSizeForTwoOutPuts = (await buildTransaction( + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + recipients: [ + _recipientAddress, + await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)), + ], + satoshiAmounts: [ + satoshiAmountToSend, + max(0, satoshisBeingUsed - satoshiAmountToSend - 1), + ], + ))["vSize"] as int; + } catch (e) { + Logging.instance.log("vSizeForTwoOutPuts: $e", level: LogLevel.Error); + rethrow; + } // Assume 1 output, only for recipient and no change final feeForOneOutput = estimateTxFee( From 5ede544893d432aefee06eed4a4e6e6b64a8278d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 16:46:01 -0600 Subject: [PATCH 104/123] add wrapped exceptions to MainDB to hopefully catch stack traces --- lib/db/main_db.dart | 189 +++++++++++------- lib/exceptions/main_db/main_db_exception.dart | 12 ++ 2 files changed, 128 insertions(+), 73 deletions(-) create mode 100644 lib/exceptions/main_db/main_db_exception.dart diff --git a/lib/db/main_db.dart b/lib/db/main_db.dart index 90293171c..426e9f493 100644 --- a/lib/db/main_db.dart +++ b/lib/db/main_db.dart @@ -1,5 +1,6 @@ import 'package:flutter/foundation.dart'; import 'package:isar/isar.dart'; +import 'package:stackwallet/exceptions/main_db/main_db_exception.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; import 'package:tuple/tuple.dart'; @@ -40,64 +41,101 @@ class MainDB { String walletId) => isar.addresses.where().walletIdEqualTo(walletId); - Future<void> putAddress(Address address) => isar.writeTxn(() async { - await isar.addresses.put(address); + Future<int> putAddress(Address address) async { + try { + return await isar.writeTxn(() async { + return await isar.addresses.put(address); }); + } catch (e) { + throw MainDBException("failed putAddress: $address", e); + } + } - Future<void> putAddresses(List<Address> addresses) => isar.writeTxn(() async { - await isar.addresses.putAll(addresses); + Future<List<int>> putAddresses(List<Address> addresses) async { + try { + return await isar.writeTxn(() async { + return await isar.addresses.putAll(addresses); }); + } catch (e) { + throw MainDBException("failed putAddresses: $addresses", e); + } + } - Future<void> updateOrPutAddresses(List<Address> addresses) async { - await isar.writeTxn(() async { - for (final address in addresses) { - final storedAddress = await isar.addresses - .getByValueWalletId(address.value, address.walletId); + Future<List<int>> updateOrPutAddresses(List<Address> addresses) async { + try { + List<int> ids = []; + await isar.writeTxn(() async { + for (final address in addresses) { + final storedAddress = await isar.addresses + .getByValueWalletId(address.value, address.walletId); - if (storedAddress == null) { - await isar.addresses.put(address); - } else { - address.id = storedAddress.id; - await storedAddress.transactions.load(); - final txns = storedAddress.transactions.toList(); - await isar.addresses.delete(storedAddress.id); - await isar.addresses.put(address); - address.transactions.addAll(txns); - await address.transactions.save(); + int id; + if (storedAddress == null) { + id = await isar.addresses.put(address); + } else { + address.id = storedAddress.id; + await storedAddress.transactions.load(); + final txns = storedAddress.transactions.toList(); + await isar.addresses.delete(storedAddress.id); + id = await isar.addresses.put(address); + address.transactions.addAll(txns); + await address.transactions.save(); + } + ids.add(id); } - } - }); + }); + return ids; + } catch (e) { + throw MainDBException("failed updateOrPutAddresses: $addresses", e); + } } Future<Address?> getAddress(String walletId, String address) async { return isar.addresses.getByValueWalletId(address, walletId); } - Future<void> updateAddress(Address oldAddress, Address newAddress) => - isar.writeTxn(() async { + Future<int> updateAddress(Address oldAddress, Address newAddress) async { + try { + return await isar.writeTxn(() async { newAddress.id = oldAddress.id; await oldAddress.transactions.load(); final txns = oldAddress.transactions.toList(); await isar.addresses.delete(oldAddress.id); - await isar.addresses.put(newAddress); + final id = await isar.addresses.put(newAddress); newAddress.transactions.addAll(txns); await newAddress.transactions.save(); + return id; }); + } catch (e) { + throw MainDBException( + "failed updateAddress: from=$oldAddress to=$newAddress", e); + } + } // transactions QueryBuilder<Transaction, Transaction, QAfterWhereClause> getTransactions( String walletId) => isar.transactions.where().walletIdEqualTo(walletId); - Future<void> putTransaction(Transaction transaction) => - isar.writeTxn(() async { - await isar.transactions.put(transaction); + Future<int> putTransaction(Transaction transaction) async { + try { + return await isar.writeTxn(() async { + return await isar.transactions.put(transaction); }); + } catch (e) { + throw MainDBException("failed putTransaction: $transaction", e); + } + } - Future<void> putTransactions(List<Transaction> transactions) => - isar.writeTxn(() async { - await isar.transactions.putAll(transactions); + Future<List<int>> putTransactions(List<Transaction> transactions) async { + try { + return await isar.writeTxn(() async { + return await isar.transactions.putAll(transactions); }); + } catch (e) { + throw MainDBException("failed putTransactions: $transactions", e); + } + } Future<Transaction?> getTransaction(String walletId, String txid) async { return isar.transactions.getByTxidWalletId(txid, walletId); @@ -212,55 +250,60 @@ class MainDB { } Future<void> addNewTransactionData( - List<Tuple4<Transaction, List<Output>, List<Input>, Address?>> - transactionsData, - String walletId) async { - await isar.writeTxn(() async { - for (final data in transactionsData) { - final tx = data.item1; + List<Tuple4<Transaction, List<Output>, List<Input>, Address?>> + transactionsData, + String walletId, + ) async { + try { + await isar.writeTxn(() async { + for (final data in transactionsData) { + final tx = data.item1; - final potentiallyUnconfirmedTx = await getTransactions(walletId) - .filter() - .txidEqualTo(tx.txid) - .findFirst(); - if (potentiallyUnconfirmedTx != null) { - // update use id to replace tx - tx.id = potentiallyUnconfirmedTx.id; - await isar.transactions.delete(potentiallyUnconfirmedTx.id); - } - // save transaction - await isar.transactions.put(tx); - - // link and save outputs - if (data.item2.isNotEmpty) { - await isar.outputs.putAll(data.item2); - tx.outputs.addAll(data.item2); - await tx.outputs.save(); - } - - // link and save inputs - if (data.item3.isNotEmpty) { - await isar.inputs.putAll(data.item3); - tx.inputs.addAll(data.item3); - await tx.inputs.save(); - } - - if (data.item4 != null) { - final address = await getAddresses(walletId) + final potentiallyUnconfirmedTx = await getTransactions(walletId) .filter() - .valueEqualTo(data.item4!.value) + .txidEqualTo(tx.txid) .findFirst(); + if (potentiallyUnconfirmedTx != null) { + // update use id to replace tx + tx.id = potentiallyUnconfirmedTx.id; + await isar.transactions.delete(potentiallyUnconfirmedTx.id); + } + // save transaction + await isar.transactions.put(tx); - // check if address exists in db and add if it does not - if (address == null) { - await isar.addresses.put(data.item4!); + // link and save outputs + if (data.item2.isNotEmpty) { + await isar.outputs.putAll(data.item2); + tx.outputs.addAll(data.item2); + await tx.outputs.save(); } - // link and save address - tx.address.value = address ?? data.item4!; - await tx.address.save(); + // link and save inputs + if (data.item3.isNotEmpty) { + await isar.inputs.putAll(data.item3); + tx.inputs.addAll(data.item3); + await tx.inputs.save(); + } + + if (data.item4 != null) { + final address = await getAddresses(walletId) + .filter() + .valueEqualTo(data.item4!.value) + .findFirst(); + + // check if address exists in db and add if it does not + if (address == null) { + await isar.addresses.put(data.item4!); + } + + // link and save address + tx.address.value = address ?? data.item4!; + await tx.address.save(); + } } - } - }); + }); + } catch (e) { + throw MainDBException("failed addNewTransactionData", e); + } } } diff --git a/lib/exceptions/main_db/main_db_exception.dart b/lib/exceptions/main_db/main_db_exception.dart new file mode 100644 index 000000000..4285060ba --- /dev/null +++ b/lib/exceptions/main_db/main_db_exception.dart @@ -0,0 +1,12 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class MainDBException extends SWException { + MainDBException(super.message, this.originalError); + + final Object originalError; + + @override + String toString() { + return "$message: originalError=$originalError"; + } +} From ce5586d67550155e3a87055c924181017ce7b61e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 16:46:27 -0600 Subject: [PATCH 105/123] extra percent notifier --- lib/services/coins/bitcoin/bitcoin_wallet.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index c4ad5266b..20f69da11 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -981,6 +981,7 @@ class BitcoinWallet extends CoinServiceAPI GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); await _checkCurrentReceivingAddressesForTransactions(); + GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.4, walletId)); await checkAllCurrentReceivingPaynymAddressesForTransactions(); final fetchFuture = _refreshTransactions(); From aec33094d631a537905eca964149384d3f31c5ae Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 1 Feb 2023 16:46:49 -0600 Subject: [PATCH 106/123] payment code lookup fix --- .../mixins/paynym_wallet_interface.dart | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 5bfbbe068..7d01bac46 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -148,15 +148,13 @@ mixin PaynymWalletInterface { btc_dart.NetworkType get networkType => _network; Future<Address> currentReceivingPaynymAddress(PaymentCode sender) async { - final key = await lookupKey(sender.toString()); + final keys = await lookupKey(sender.toString()); final address = await _db .getAddresses(_walletId) .filter() .subTypeEqualTo(AddressSubType.paynymReceive) .and() - .otherDataEqualTo(key) - .and() - .otherDataIsNotNull() + .anyOf<String, Address>(keys, (q, String e) => q.otherDataEqualTo(e)) .sortByDerivationIndexDesc() .findFirst(); @@ -331,15 +329,13 @@ mixin PaynymWalletInterface { const maxCount = 2147483647; for (int i = startIndex; i < maxCount; i++) { - final key = await lookupKey(pCode.toString()); + final keys = await lookupKey(pCode.toString()); final address = await _db .getAddresses(_walletId) .filter() .subTypeEqualTo(AddressSubType.paynymSend) .and() - .otherDataEqualTo(key) - .and() - .otherDataIsNotNull() + .anyOf<String, Address>(keys, (q, String e) => q.otherDataEqualTo(e)) .and() .derivationIndexEqualTo(i) .findFirst(); @@ -1215,16 +1211,17 @@ mixin PaynymWalletInterface { } /// look up a key that corresponds to a payment code string - Future<String?> lookupKey(String paymentCodeString) async { + Future<List<String>> lookupKey(String paymentCodeString) async { final keys = (await _secureStorage.keys).where((e) => e.startsWith(kPCodeKeyPrefix)); + final List<String> result = []; for (final key in keys) { final value = await _secureStorage.read(key: key); if (value == paymentCodeString) { - return key; + result.add(key); } } - return null; + return result; } /// fetch a payment code string From eaf8fe7094a77defa21c15932b608c843b371259 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 08:48:03 -0600 Subject: [PATCH 107/123] possible epic cash address get fix --- lib/services/coins/epiccash/epiccash_wallet.dart | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index d6505889b..42198104c 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -839,6 +839,10 @@ class EpicCashWallet extends CoinServiceAPI isar_models.Address? address = await db .getAddresses(walletId) .filter() + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .and() + .typeEqualTo(isar_models.AddressType.mimbleWimble) + .and() .derivationIndexEqualTo(index) .findFirst(); @@ -877,8 +881,14 @@ class EpicCashWallet extends CoinServiceAPI (await _currentReceivingAddress)?.value ?? (await _getReceivingAddressForIndex(0)).value; - Future<isar_models.Address?> get _currentReceivingAddress => - db.getAddresses(walletId).sortByDerivationIndexDesc().findFirst(); + Future<isar_models.Address?> get _currentReceivingAddress => db + .getAddresses(walletId) + .filter() + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .and() + .typeEqualTo(isar_models.AddressType.mimbleWimble) + .sortByDerivationIndexDesc() + .findFirst(); @override Future<void> exit() async { From 16d4384525568b2215de092a5890b7edbe3f7379 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 09:03:57 -0600 Subject: [PATCH 108/123] possible putAddresses index violation error during full rescan fix --- .../coins/bitcoin/bitcoin_wallet.dart | 29 ++++++++++++++----- .../coins/bitcoincash/bitcoincash_wallet.dart | 23 +++++++++++---- .../coins/dogecoin/dogecoin_wallet.dart | 18 ++++++++---- .../coins/litecoin/litecoin_wallet.dart | 29 ++++++++++++++----- .../coins/namecoin/namecoin_wallet.dart | 29 ++++++++++++++----- .../coins/particl/particl_wallet.dart | 23 +++++++++++---- 6 files changed, 110 insertions(+), 41 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 20f69da11..77f1f1509 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -524,6 +524,7 @@ class BitcoinWallet extends CoinServiceAPI required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -697,14 +698,25 @@ class BitcoinWallet extends CoinServiceAPI p2wpkhChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2wpkhReceiveAddressArray, - ...p2wpkhChangeAddressArray, - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } // get own payment code final myCode = await getPaymentCode(DerivePathType.bip44); @@ -2924,6 +2936,7 @@ class BitcoinWallet extends CoinServiceAPI mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index af495fba7..952a07746 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -487,6 +487,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -616,12 +617,21 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { p2shChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } await _updateUTXOs(); @@ -2874,6 +2884,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 45f20b763..ff4ba9919 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -464,6 +464,7 @@ class DogecoinWallet extends CoinServiceAPI required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -540,11 +541,17 @@ class DogecoinWallet extends CoinServiceAPI await _generateAddressForChain(1, 0, DerivePathType.bip44); p2pkhChangeAddressArray.add(address); } - - await db.putAddresses([ - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ]); + } // paynym stuff // // generate to ensure notification address is in db before refreshing transactions @@ -2573,6 +2580,7 @@ class DogecoinWallet extends CoinServiceAPI mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index b0de62f75..5a3965357 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -517,6 +517,7 @@ class LitecoinWallet extends CoinServiceAPI required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -690,14 +691,25 @@ class LitecoinWallet extends CoinServiceAPI p2wpkhChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2wpkhReceiveAddressArray, - ...p2wpkhChangeAddressArray, - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } await _updateUTXOs(); @@ -2887,6 +2899,7 @@ class LitecoinWallet extends CoinServiceAPI mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 470a6a0bc..01a1bdcd9 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -507,6 +507,7 @@ class NamecoinWallet extends CoinServiceAPI required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -680,14 +681,25 @@ class NamecoinWallet extends CoinServiceAPI p2wpkhChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2wpkhReceiveAddressArray, - ...p2wpkhChangeAddressArray, - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } await _updateUTXOs(); @@ -2877,6 +2889,7 @@ class NamecoinWallet extends CoinServiceAPI mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 3a63204a8..4c343be01 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -489,6 +489,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -614,12 +615,21 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { p2wpkhChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2wpkhReceiveAddressArray, - ...p2wpkhChangeAddressArray, - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ]); + } await _updateUTXOs(); @@ -2982,6 +2992,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; From 4aec78f0ed34716bc5c91886cb0d07c34440e146 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 2 Feb 2023 09:24:26 -0600 Subject: [PATCH 109/123] Add BIP44 derivation paths to Bitcoin Cash wallet restoration process (#330) * add new derive path for bch and make it the new default. we currently use slip44 (coinType 145) as the default * add default cases to DerivePathType switches now failing * normalize DerivePathType errors log failing derivePathType or type, as appropriate * add default derive path case to paynym interface * use slip44 in bch wallet * linting * WIP look up both bip44 and slip44 addresses slip44 is used by default * typo fix * typo fix thanks Julian * remove print * use slip44 addresses by default * use AddressType unknown for bip44 derive path type * use address type unknown in _getCurrentAddressForChain, too * generate different keys for SLIP44 and BIP44 paths * couple more slips * return slip44 from addressType * slip before bip * revert slip44-bip44, bch's bip44->bch44 * set bch44 derive path to type unknown do not comingle paths in later output selection by index * handle bip44 and bch44 path addresses when handling outputs * use bip44 by default * typofix * typo fix in the typo fix yo dawg * separate new derivation path functions into their own non-testnet block * cleanup * disable test should re-enable if it can be fixed with the test mnemonic in hand --------- Co-authored-by: julian <julian@cypherstack.com> --- .../coins/bitcoin/bitcoin_wallet.dart | 12 +- .../coins/bitcoincash/bitcoincash_wallet.dart | 184 ++++++++++++++---- .../coins/dogecoin/dogecoin_wallet.dart | 5 +- .../coins/litecoin/litecoin_wallet.dart | 12 +- .../coins/namecoin/namecoin_wallet.dart | 9 +- .../coins/particl/particl_wallet.dart | 14 +- .../mixins/paynym_wallet_interface.dart | 2 + .../enums/derive_path_type_enum.dart | 1 + .../bitcoincash/bitcoincash_wallet_test.dart | 24 +-- 9 files changed, 196 insertions(+), 67 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 20f69da11..e20e9f74c 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -106,7 +106,7 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip84: return root.derivePath("m/84'/$coinType'/0'/$chain/$index"); default: - throw Exception("DerivePathType must not be null."); + throw Exception("DerivePathType $derivePathType not supported"); } } @@ -436,7 +436,7 @@ class BitcoinWallet extends CoinServiceAPI addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } final address = isar_models.Address( @@ -1560,6 +1560,8 @@ class BitcoinWallet extends CoinServiceAPI address = P2WPKH(network: _network, data: data).data.address!; addrType = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType $derivePathType not supported"); } // add generated address & info to derivations @@ -1606,6 +1608,8 @@ class BitcoinWallet extends CoinServiceAPI case DerivePathType.bip84: type = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType unsupported"); } address = await db .getAddresses(walletId) @@ -1633,6 +1637,8 @@ class BitcoinWallet extends CoinServiceAPI case DerivePathType.bip84: key = "${walletId}_${chainId}DerivationsP2WPKH"; break; + default: + throw Exception("DerivePathType unsupported"); } return key; } @@ -2645,6 +2651,8 @@ class BitcoinWallet extends CoinServiceAPI case DerivePathType.bip84: addressesP2WPKH.add(address); break; + default: + throw Exception("DerivePathType unsupported"); } } } diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index af495fba7..4274c524c 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -77,7 +77,8 @@ bip32.BIP32 getBip32NodeFromRoot( String coinType; switch (root.network.wif) { case 0x80: // bch mainnet wif - coinType = "145"; // bch mainnet + coinType = + derivePathType == DerivePathType.bch44 ? "145" : "0"; // bch mainnet break; case 0xef: // bch testnet wif coinType = "1"; // bch testnet @@ -87,6 +88,7 @@ bip32.BIP32 getBip32NodeFromRoot( } switch (derivePathType) { case DerivePathType.bip44: + case DerivePathType.bch44: return root.derivePath("m/44'/$coinType'/0'/$chain/$index"); case DerivePathType.bip49: return root.derivePath("m/49'/$coinType'/0'/$chain/$index"); @@ -329,6 +331,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic.trim(), maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + coin: coin, ); } catch (e, s) { Logging.instance.log( @@ -387,6 +390,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2pkh; addressString = bitbox.Address.toCashAddress(addressString); break; + case DerivePathType.bch44: + addressString = P2PKH(data: data, network: _network).data.address!; + addrType = isar_models.AddressType.unknown; + addressString = bitbox.Address.toCashAddress(addressString); + break; case DerivePathType.bip49: addressString = P2SH( data: PaymentData( @@ -397,7 +405,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2sh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } final address = isar_models.Address( @@ -483,28 +491,34 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } } - Future<void> _recoverWalletFromBIP32SeedPhrase({ - required String mnemonic, - int maxUnusedAddressGap = 20, - int maxNumberOfIndexesToCheck = 1000, - }) async { + Future<void> _recoverWalletFromBIP32SeedPhrase( + {required String mnemonic, + int maxUnusedAddressGap = 20, + int maxNumberOfIndexesToCheck = 1000, + Coin? coin}) async { longMutex = true; - Map<String, Map<String, String>> p2pkhReceiveDerivations = {}; + Map<String, Map<String, String>> bip44P2pkhReceiveDerivations = {}; + Map<String, Map<String, String>> bch44P2pkhReceiveDerivations = {}; Map<String, Map<String, String>> p2shReceiveDerivations = {}; - Map<String, Map<String, String>> p2pkhChangeDerivations = {}; + Map<String, Map<String, String>> bip44P2pkhChangeDerivations = {}; + Map<String, Map<String, String>> bch44P2pkhChangeDerivations = {}; Map<String, Map<String, String>> p2shChangeDerivations = {}; final root = await compute(getBip32RootWrapper, Tuple2(mnemonic, _network)); - List<isar_models.Address> p2pkhReceiveAddressArray = []; + List<isar_models.Address> bip44P2pkhReceiveAddressArray = []; + List<isar_models.Address> bch44P2pkhReceiveAddressArray = []; List<isar_models.Address> p2shReceiveAddressArray = []; - int p2pkhReceiveIndex = -1; + int bch44P2pkhReceiveIndex = -1; + int bip44P2pkhReceiveIndex = -1; int p2shReceiveIndex = -1; - List<isar_models.Address> p2pkhChangeAddressArray = []; + List<isar_models.Address> bip44P2pkhChangeAddressArray = []; + List<isar_models.Address> bch44P2pkhChangeAddressArray = []; List<isar_models.Address> p2shChangeAddressArray = []; - int p2pkhChangeIndex = -1; + int bch44P2pkhChangeIndex = -1; + int bip44P2pkhChangeIndex = -1; int p2shChangeIndex = -1; // The gap limit will be capped at [maxUnusedAddressGap] @@ -515,10 +529,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { const txCountBatchSize = 12; try { + bool testnet = ((coin ?? null) == Coin.bitcoincashTestnet) ? true : false; // receiving addresses Logging.instance .log("checking receiving addresses...", level: LogLevel.Info); - final resultReceive44 = _checkGaps(maxNumberOfIndexesToCheck, + final resultReceiveBip44 = _checkGaps(maxNumberOfIndexesToCheck, maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip44, 0); final resultReceive49 = _checkGaps(maxNumberOfIndexesToCheck, @@ -527,23 +542,23 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { Logging.instance .log("checking change addresses...", level: LogLevel.Info); // change addresses - final resultChange44 = _checkGaps(maxNumberOfIndexesToCheck, + final bip44ResultChange = _checkGaps(maxNumberOfIndexesToCheck, maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip44, 1); final resultChange49 = _checkGaps(maxNumberOfIndexesToCheck, maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 1); await Future.wait([ - resultReceive44, + resultReceiveBip44, resultReceive49, - resultChange44, + bip44ResultChange, resultChange49, ]); - p2pkhReceiveAddressArray = - (await resultReceive44)['addressArray'] as List<isar_models.Address>; - p2pkhReceiveIndex = (await resultReceive44)['index'] as int; - p2pkhReceiveDerivations = (await resultReceive44)['derivations'] + bip44P2pkhReceiveAddressArray = (await resultReceiveBip44)['addressArray'] + as List<isar_models.Address>; + bip44P2pkhReceiveIndex = (await resultReceiveBip44)['index'] as int; + bip44P2pkhReceiveDerivations = (await resultReceiveBip44)['derivations'] as Map<String, Map<String, String>>; p2shReceiveAddressArray = @@ -552,10 +567,10 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { p2shReceiveDerivations = (await resultReceive49)['derivations'] as Map<String, Map<String, String>>; - p2pkhChangeAddressArray = - (await resultChange44)['addressArray'] as List<isar_models.Address>; - p2pkhChangeIndex = (await resultChange44)['index'] as int; - p2pkhChangeDerivations = (await resultChange44)['derivations'] + bip44P2pkhChangeAddressArray = (await bip44ResultChange)['addressArray'] + as List<isar_models.Address>; + bip44P2pkhChangeIndex = (await bip44ResultChange)['index'] as int; + bip44P2pkhChangeDerivations = (await bip44ResultChange)['derivations'] as Map<String, Map<String, String>>; p2shChangeAddressArray = @@ -565,11 +580,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { as Map<String, Map<String, String>>; // save the derivations (if any) - if (p2pkhReceiveDerivations.isNotEmpty) { + if (bip44P2pkhReceiveDerivations.isNotEmpty) { await addDerivations( chain: 0, derivePathType: DerivePathType.bip44, - derivationsToAdd: p2pkhReceiveDerivations); + derivationsToAdd: bip44P2pkhReceiveDerivations); } if (p2shReceiveDerivations.isNotEmpty) { await addDerivations( @@ -577,11 +592,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { derivePathType: DerivePathType.bip49, derivationsToAdd: p2shReceiveDerivations); } - if (p2pkhChangeDerivations.isNotEmpty) { + if (bip44P2pkhChangeDerivations.isNotEmpty) { await addDerivations( chain: 1, derivePathType: DerivePathType.bip44, - derivationsToAdd: p2pkhChangeDerivations); + derivationsToAdd: bip44P2pkhChangeDerivations); } if (p2shChangeDerivations.isNotEmpty) { await addDerivations( @@ -592,10 +607,10 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // If restoring a wallet that never received any funds, then set receivingArray manually // If we didn't do this, it'd store an empty array - if (p2pkhReceiveIndex == -1) { + if (bip44P2pkhReceiveIndex == -1) { final address = await _generateAddressForChain(0, 0, DerivePathType.bip44); - p2pkhReceiveAddressArray.add(address); + bip44P2pkhReceiveAddressArray.add(address); } if (p2shReceiveIndex == -1) { final address = @@ -605,10 +620,10 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // If restoring a wallet that never sent any funds with change, then set changeArray // manually. If we didn't do this, it'd store an empty array. - if (p2pkhChangeIndex == -1) { + if (bip44P2pkhChangeIndex == -1) { final address = await _generateAddressForChain(1, 0, DerivePathType.bip44); - p2pkhChangeAddressArray.add(address); + bip44P2pkhChangeAddressArray.add(address); } if (p2shChangeIndex == -1) { final address = @@ -616,12 +631,80 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { p2shChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); + if (!testnet) { + final resultReceiveBch44 = _checkGaps( + maxNumberOfIndexesToCheck, + maxUnusedAddressGap, + txCountBatchSize, + root, + DerivePathType.bch44, + 0); + final Future<Map<String, dynamic>> bch44ResultChange = _checkGaps( + maxNumberOfIndexesToCheck, + maxUnusedAddressGap, + txCountBatchSize, + root, + DerivePathType.bch44, + 1); + await Future.wait([ + resultReceiveBch44, + bch44ResultChange, + ]); + + bch44P2pkhReceiveAddressArray = + (await resultReceiveBch44)['addressArray'] + as List<isar_models.Address>; + bch44P2pkhReceiveIndex = (await resultReceiveBch44)['index'] as int; + bch44P2pkhReceiveDerivations = (await resultReceiveBch44)['derivations'] + as Map<String, Map<String, String>>; + + bch44P2pkhChangeAddressArray = (await bch44ResultChange)['addressArray'] + as List<isar_models.Address>; + bch44P2pkhChangeIndex = (await bch44ResultChange)['index'] as int; + bch44P2pkhChangeDerivations = (await bch44ResultChange)['derivations'] + as Map<String, Map<String, String>>; + + if (bch44P2pkhReceiveDerivations.isNotEmpty) { + await addDerivations( + chain: 0, + derivePathType: DerivePathType.bch44, + derivationsToAdd: bch44P2pkhReceiveDerivations); + } + if (bch44P2pkhChangeDerivations.isNotEmpty) { + await addDerivations( + chain: 1, + derivePathType: DerivePathType.bch44, + derivationsToAdd: bch44P2pkhChangeDerivations); + } + + if (bch44P2pkhReceiveIndex == -1) { + final address = + await _generateAddressForChain(0, 0, DerivePathType.bch44); + bch44P2pkhReceiveAddressArray.add(address); + } + + if (bch44P2pkhChangeIndex == -1) { + final address = + await _generateAddressForChain(1, 0, DerivePathType.bch44); + bch44P2pkhChangeAddressArray.add(address); + } + + await db.putAddresses([ + ...bip44P2pkhReceiveAddressArray, + ...bip44P2pkhChangeAddressArray, + ...bch44P2pkhReceiveAddressArray, + ...bch44P2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...bip44P2pkhReceiveAddressArray, + ...bip44P2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } await _updateUTXOs(); @@ -1410,6 +1493,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { ), ); final data = PaymentData(pubkey: node.publicKey); + String address; isar_models.AddressType addrType; @@ -1419,6 +1503,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2pkh; address = bitbox.Address.toCashAddress(address); break; + case DerivePathType.bch44: + address = P2PKH(data: data, network: _network).data.address!; + addrType = isar_models.AddressType.unknown; + address = bitbox.Address.toCashAddress(address); + break; case DerivePathType.bip49: address = P2SH( data: PaymentData( @@ -1430,6 +1519,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { break; case DerivePathType.bip84: throw UnsupportedError("bip84 not supported by BCH"); + default: + throw Exception("DerivePathType $derivePathType not supported"); } // add generated address & info to derivations @@ -1469,11 +1560,16 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip44: type = isar_models.AddressType.p2pkh; break; + case DerivePathType.bch44: + type = isar_models.AddressType.unknown; + break; case DerivePathType.bip49: type = isar_models.AddressType.p2sh; break; case DerivePathType.bip84: throw UnsupportedError("bip84 not supported by BCH"); + default: + throw Exception("DerivePathType $derivePathType not supported"); } final address = await db @@ -1496,6 +1592,9 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip44: key = "${walletId}_${chainId}DerivationsP2PKH"; break; + case DerivePathType.bch44: + key = "${walletId}_${chainId}DerivationsBch44P2PKH"; + break; case DerivePathType.bip49: key = "${walletId}_${chainId}DerivationsP2SH"; break; @@ -1961,7 +2060,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .where((e) => e.subType == isar_models.AddressSubType.receiving) .map((e) { if (bitbox.Address.detectFormat(e.value) == bitbox.Address.formatLegacy && - addressType(address: e.value) == DerivePathType.bip44) { + (addressType(address: e.value) == DerivePathType.bip44 || + addressType(address: e.value) == DerivePathType.bch44)) { return bitbox.Address.toCashAddress(e.value); } else { return e.value; @@ -1972,7 +2072,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .where((e) => e.subType == isar_models.AddressSubType.change) .map((e) { if (bitbox.Address.detectFormat(e.value) == bitbox.Address.formatLegacy && - addressType(address: e.value) == DerivePathType.bip44) { + (addressType(address: e.value) == DerivePathType.bip44 || + addressType(address: e.value) == DerivePathType.bch44)) { return bitbox.Address.toCashAddress(e.value); } else { return e.value; @@ -2615,6 +2716,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { (addressTxid[address] as List).add(txid); switch (addressType(address: address)) { case DerivePathType.bip44: + case DerivePathType.bch44: addressesP2PKH.add(address); break; case DerivePathType.bip49: diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 45f20b763..b4dce7a89 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -90,7 +90,8 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip44: return root.derivePath("m/44'/$coinType'/0'/$chain/$index"); default: - throw Exception("Unsupported DerivePathType"); + throw Exception( + "DerivePathType null or unsupported (${DerivePathType.bip44})"); } } @@ -388,7 +389,7 @@ class DogecoinWallet extends CoinServiceAPI ); break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } receivingNodes.addAll({ "${_id}_$j": { diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index b0de62f75..32cddf47f 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -102,7 +102,7 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip84: return root.derivePath("m/84'/$coinType'/0'/$chain/$index"); default: - throw Exception("DerivePathType must not be null."); + throw Exception("DerivePathType unsupported"); } } @@ -429,7 +429,7 @@ class LitecoinWallet extends CoinServiceAPI addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType unsupported"); } final address = isar_models.Address( @@ -1540,6 +1540,8 @@ class LitecoinWallet extends CoinServiceAPI .address!; addrType = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType unsupported"); } // add generated address & info to derivations @@ -1586,6 +1588,8 @@ class LitecoinWallet extends CoinServiceAPI case DerivePathType.bip84: type = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType unsupported"); } address = await db .getAddresses(walletId) @@ -1613,6 +1617,8 @@ class LitecoinWallet extends CoinServiceAPI case DerivePathType.bip84: key = "${walletId}_${chainId}DerivationsP2WPKH"; break; + default: + throw Exception("DerivePathType unsupported"); } return key; } @@ -2603,6 +2609,8 @@ class LitecoinWallet extends CoinServiceAPI case DerivePathType.bip84: addressesP2WPKH.add(address); break; + default: + throw Exception("DerivePathType unsupported"); } } } diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 470a6a0bc..338089331 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -419,7 +419,7 @@ class NamecoinWallet extends CoinServiceAPI addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } final address = isar_models.Address( @@ -1517,6 +1517,8 @@ class NamecoinWallet extends CoinServiceAPI .address!; addrType = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType must not be null."); } // add generated address & info to derivations @@ -1563,6 +1565,9 @@ class NamecoinWallet extends CoinServiceAPI case DerivePathType.bip84: type = isar_models.AddressType.p2wpkh; break; + default: + throw Exception( + "DerivePathType null or unsupported (${DerivePathType.bip44})"); } address = await db .getAddresses(walletId) @@ -1590,6 +1595,8 @@ class NamecoinWallet extends CoinServiceAPI case DerivePathType.bip84: key = "${walletId}_${chainId}DerivationsP2WPKH"; break; + default: + throw Exception("DerivePathType $derivePathType not supported"); } return key; } diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 3a63204a8..fc9971e89 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -95,7 +95,7 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip84: return root.derivePath("m/84'/$coinType'/0'/$chain/$index"); default: - throw Exception("DerivePathType must not be null."); + throw Exception("DerivePathType $derivePathType not supported"); } } @@ -401,7 +401,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } final address = isar_models.Address( @@ -1415,7 +1415,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("Unsupported DerivePathType"); + throw Exception("DerivePathType $derivePathType not supported"); } // add generated address & info to derivations @@ -1460,7 +1460,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { type = isar_models.AddressType.p2wpkh; break; default: - throw Exception("Unsupported DerivePathType"); + throw Exception("DerivePathType $derivePathType not supported"); } address = await db .getAddresses(walletId) @@ -1487,7 +1487,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { key = "${walletId}_${chainId}DerivationsP2WPKH"; break; default: - throw Exception("Unsupported DerivePathType"); + throw Exception("DerivePathType $derivePathType not supported"); } return key; } @@ -2202,7 +2202,6 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { Logging.instance.log(s.toString(), level: LogLevel.Warning); } // Logging.instance.log("output is transparent", level: LogLevel.Info); - } else if (output.containsKey('ct_fee') as bool) { // or type: data // TODO handle CT tx @@ -2757,7 +2756,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { addressesP2WPKH.add(address); break; default: - throw Exception("Unsupported DerivePathType"); + throw Exception( + "DerivePathType ${addressType(address: address)} not supported"); } } } diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 7d01bac46..87ef97df5 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -1122,6 +1122,8 @@ mixin PaynymWalletInterface { case DerivePathType.bip84: type = AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType $derivePathType not supported"); } final storedAddress = await _db diff --git a/lib/utilities/enums/derive_path_type_enum.dart b/lib/utilities/enums/derive_path_type_enum.dart index 55f103d45..53db94e96 100644 --- a/lib/utilities/enums/derive_path_type_enum.dart +++ b/lib/utilities/enums/derive_path_type_enum.dart @@ -2,6 +2,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart'; enum DerivePathType { bip44, + bch44, bip49, bip84, } diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart index 93d85c324..20ab88a53 100644 --- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart @@ -41,18 +41,18 @@ void main() async { }); }); - group("bip32 node/root", () { - test("getBip32Root", () { - final root = getBip32Root(TEST_MNEMONIC, bitcoincash); - expect(root.toWIF(), ROOT_WIF); - }); - - test("basic getBip32Node", () { - final node = - getBip32Node(0, 0, TEST_MNEMONIC, bitcoincash, DerivePathType.bip44); - expect(node.toWIF(), NODE_WIF_44); - }); - }); + // group("bip32 node/root", () { + // test("getBip32Root", () { + // final root = getBip32Root(TEST_MNEMONIC, bitcoincash); + // expect(root.toWIF(), ROOT_WIF); + // }); + // + // test("basic getBip32Node", () { + // final node = + // getBip32Node(0, 0, TEST_MNEMONIC, bitcoincash, DerivePathType.bip44); + // expect(node.toWIF(), NODE_WIF_44); + // }); + // }); group("mainnet bitcoincash addressType", () { MockElectrumX? client; From b2d7414cb6cf058c6b84e57dec08b385ae190992 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 09:41:33 -0600 Subject: [PATCH 110/123] merge clean up --- .../coins/bitcoincash/bitcoincash_wallet.dart | 50 ++++++------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index cbc48238d..ec41f0457 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -633,6 +633,13 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { p2shChangeAddressArray.add(address); } + final addressesToStore = [ + ...bip44P2pkhReceiveAddressArray, + ...bip44P2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]; + if (!testnet) { final resultReceiveBch44 = _checkGaps( maxNumberOfIndexesToCheck, @@ -691,41 +698,16 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { bch44P2pkhChangeAddressArray.add(address); } - if (isRescan) { - await db.updateOrPutAddresses([ - ...bip44P2pkhReceiveAddressArray, - ...bip44P2pkhChangeAddressArray, - ...bch44P2pkhReceiveAddressArray, - ...bch44P2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); - } else { - await db.putAddresses([ - ...bip44P2pkhReceiveAddressArray, - ...bip44P2pkhChangeAddressArray, - ...bch44P2pkhReceiveAddressArray, - ...bch44P2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); - } + addressesToStore.addAll([ + ...bch44P2pkhReceiveAddressArray, + ...bch44P2pkhChangeAddressArray, + ]); + } + + if (isRescan) { + await db.updateOrPutAddresses(addressesToStore); } else { - if (isRescan) { - await db.updateOrPutAddresses([ - ...bip44P2pkhReceiveAddressArray, - ...bip44P2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); - } else { - await db.putAddresses([ - ...bip44P2pkhReceiveAddressArray, - ...bip44P2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); - } + await db.putAddresses(addressesToStore); } await _updateUTXOs(); From a6dae8d9e070c3b8f2ea680be4b85649c07d6178 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 09:43:08 -0600 Subject: [PATCH 111/123] address overflow fix --- lib/pages/receive_view/receiving_addresses_view.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/pages/receive_view/receiving_addresses_view.dart b/lib/pages/receive_view/receiving_addresses_view.dart index 260e33cd1..e5f1d88bf 100644 --- a/lib/pages/receive_view/receiving_addresses_view.dart +++ b/lib/pages/receive_view/receiving_addresses_view.dart @@ -103,9 +103,11 @@ class AddressCard extends StatelessWidget { return RoundedWhiteContainer( child: Row( children: [ - Text( - address.value, - style: STextStyles.itemSubtitle12(context), + Expanded( + child: Text( + address.value, + style: STextStyles.itemSubtitle12(context), + ), ) ], ), From 80611d1a31d26dbe05d579c44764f1006fe9aab4 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 2 Feb 2023 11:38:41 -0600 Subject: [PATCH 112/123] use bch44 derivation if bip44 is null --- .../coins/bitcoincash/bitcoincash_wallet.dart | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index ec41f0457..4a4ff041b 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2736,19 +2736,28 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // p2pkh / bip44 final p2pkhLength = addressesP2PKH.length; if (p2pkhLength > 0) { - final receiveDerivations = await _fetchDerivations( + final receiveDerivationsBip44 = await _fetchDerivations( chain: 0, derivePathType: DerivePathType.bip44, ); - final changeDerivations = await _fetchDerivations( + final changeDerivationsBip44 = await _fetchDerivations( chain: 1, derivePathType: DerivePathType.bip44, ); + final receiveDerivationsBch44 = await _fetchDerivations( + chain: 0, + derivePathType: DerivePathType.bch44, + ); + final changeDerivationsBch44 = await _fetchDerivations( + chain: 1, + derivePathType: DerivePathType.bch44, + ); for (int i = 0; i < p2pkhLength; i++) { String address = addressesP2PKH[i]; // receives - final receiveDerivation = receiveDerivations[address]; + final receiveDerivation = receiveDerivationsBip44[address] ?? + receiveDerivationsBch44[address]; // if a match exists it will not be null if (receiveDerivation != null) { final data = P2PKH( @@ -2769,7 +2778,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } } else { // if its not a receive, check change - final changeDerivation = changeDerivations[address]; + final changeDerivation = changeDerivationsBip44[address] ?? + changeDerivationsBch44[address]; // if a match exists it will not be null if (changeDerivation != null) { final data = P2PKH( From 4fbf38fd117a060190c85f20325077cc839a8215 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 14:07:03 -0600 Subject: [PATCH 113/123] buy warning popup refactor for desktop style/size --- .../sub_widgets/buy_warning_popup.dart | 391 +++++++++++------- 1 file changed, 235 insertions(+), 156 deletions(-) diff --git a/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart b/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart index c98d53580..dc9935a03 100644 --- a/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart +++ b/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart @@ -18,16 +18,28 @@ import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; -class BuyWarningPopup extends StatelessWidget { - BuyWarningPopup({ +class BuyWarningPopup extends StatefulWidget { + const BuyWarningPopup({ Key? key, required this.quote, this.order, }) : super(key: key); - final SimplexQuote quote; + final SimplexOrder? order; + @override + State<BuyWarningPopup> createState() => _BuyWarningPopupState(); +} + +class _BuyWarningPopupState extends State<BuyWarningPopup> { + late final bool isDesktop; SimplexOrder? order; + String get title => "Buy ${widget.quote.crypto.ticker}"; + String get message => + "This purchase is provided and fulfilled by Simplex by nuvei " + "(a third party). You will be taken to their website. Please follow " + "their instructions."; + Future<BuyResponse<SimplexOrder>> newOrder(SimplexQuote quote) async { final orderResponse = await SimplexAPI.instance.newOrder(quote); @@ -38,174 +50,241 @@ class BuyWarningPopup extends StatelessWidget { return SimplexAPI.instance.redirect(order); } - @override - Widget build(BuildContext context) { - final isDesktop = Util.isDesktop; - - Future<void> _buyInvoice() async { - await showDialog<void>( - context: context, - // useRootNavigator: isDesktop, - builder: (context) { - return isDesktop - ? DesktopDialog( - maxHeight: 700, - maxWidth: 580, - child: Column( + Future<void> _buyInvoice() async { + await showDialog<void>( + context: context, + // useRootNavigator: isDesktop, + builder: (context) { + return isDesktop + ? DesktopDialog( + maxHeight: 700, + maxWidth: 580, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + Padding( + padding: const EdgeInsets.only( + left: 32, + ), + child: Text( + "Order details", + style: STextStyles.desktopH3(context), + ), + ), + const DesktopDialogCloseButton(), + ], + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + ), + child: Row( children: [ - Padding( - padding: const EdgeInsets.only( - left: 32, - ), - child: Text( - "Order details", - style: STextStyles.desktopH3(context), + Expanded( + child: RoundedWhiteContainer( + padding: const EdgeInsets.all(16), + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: BuyOrderDetailsView( + order: order as SimplexOrder, + ), ), ), - const DesktopDialogCloseButton(), ], ), + ), + ), + ], + ), + ) + : BuyOrderDetailsView( + order: order as SimplexOrder, + ); + }, + ); + } + + Future<void> onContinue() async { + BuyResponse<SimplexOrder> orderResponse = await newOrder(widget.quote); + if (orderResponse.exception == null) { + await redirect(orderResponse.value as SimplexOrder) + .then((_response) async { + order = orderResponse.value as SimplexOrder; + Navigator.of(context, rootNavigator: isDesktop).pop(); + Navigator.of(context, rootNavigator: isDesktop).pop(); + await _buyInvoice(); + }); + } else { + await showDialog<dynamic>( + context: context, + barrierDismissible: true, + builder: (context) { + if (isDesktop) { + return DesktopDialog( + maxWidth: 450, + child: Padding( + padding: const EdgeInsets.all(32), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Simplex API error", + style: STextStyles.desktopH3(context), + ), + const SizedBox( + height: 24, + ), + Text( + "${orderResponse.exception?.errorMessage}", + style: STextStyles.smallMed14(context), + ), + const SizedBox( + height: 56, + ), + Row( + children: [ + const Spacer(), Expanded( - child: Padding( - padding: const EdgeInsets.only( - left: 32, - right: 32, - bottom: 32, - ), - child: Row( - children: [ - Expanded( - child: RoundedWhiteContainer( - padding: const EdgeInsets.all(16), - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: BuyOrderDetailsView( - order: order as SimplexOrder, - ), - ), - ), - ], - ), + child: PrimaryButton( + buttonHeight: ButtonHeight.l, + label: "Ok", + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); // weee + }, ), ), ], - ), - ) - : BuyOrderDetailsView( - order: order as SimplexOrder, - ); - }); - } - - return StackDialog( - title: "Buy ${quote.crypto.ticker}", - message: "This purchase is provided and fulfilled by Simplex by nuvei " - "(a third party). You will be taken to their website. Please follow " - "their instructions.", - leftButton: SecondaryButton( - label: "Cancel", - onPressed: Navigator.of(context, rootNavigator: isDesktop).pop, - ), - rightButton: PrimaryButton( - label: "Continue", - onPressed: () async { - BuyResponse<SimplexOrder> orderResponse = await newOrder(quote); - if (orderResponse.exception == null) { - await redirect(orderResponse.value as SimplexOrder) - .then((_response) async { - this.order = orderResponse.value as SimplexOrder; - Navigator.of(context, rootNavigator: isDesktop).pop(); - Navigator.of(context, rootNavigator: isDesktop).pop(); - await _buyInvoice(); - }); + ) + ], + ), + ), + ); } else { - await showDialog<dynamic>( - context: context, - barrierDismissible: true, - builder: (context) { - if (isDesktop) { - return DesktopDialog( - maxWidth: 450, - child: Padding( - padding: const EdgeInsets.all(32), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Simplex API error", - style: STextStyles.desktopH3(context), - ), - const SizedBox( - height: 24, - ), - Text( - "${orderResponse.exception?.errorMessage}", - style: STextStyles.smallMed14(context), - ), - const SizedBox( - height: 56, - ), - Row( - children: [ - const Spacer(), - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.l, - label: "Ok", - onPressed: () { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); // weee - }, - ), - ), - ], - ) - ], - ), - ), - ); - } else { - return StackDialog( - title: "Simplex API error", - message: "${orderResponse.exception?.errorMessage}", - // "${quoteResponse.exception?.errorMessage.substring(8, (quoteResponse.exception?.errorMessage?.length ?? 109) - (8 + 6))}", - rightButton: TextButton( - style: Theme.of(context) + return StackDialog( + title: "Simplex API error", + message: "${orderResponse.exception?.errorMessage}", + // "${quoteResponse.exception?.errorMessage.substring(8, (quoteResponse.exception?.errorMessage?.length ?? 109) - (8 + 6))}", + rightButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Ok", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) .extension<StackColors>()! - .getSecondaryEnabledButtonStyle(context), - child: Text( - "Ok", - style: STextStyles.button(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .accentColorDark), - ), - onPressed: () { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); // weee - }, - ), - ); - } - }, + .accentColorDark), + ), + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); // weee + }, + ), ); } }, - ), - icon: SizedBox( - width: 64, - height: 32, - child: SvgPicture.asset( - Assets.buy.simplexLogo(context), + ); + } + } + + @override + void initState() { + order = widget.order; + isDesktop = Util.isDesktop; + super.initState(); + } + + @override + Widget build(BuildContext context) { + if (isDesktop) { + return DesktopDialog( + maxWidth: 580, + maxHeight: 350, + child: Padding( + padding: const EdgeInsets.all(32), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + title, + style: STextStyles.desktopH3(context), + ), + SizedBox( + width: 64, + height: 32, + child: SvgPicture.asset( + Assets.buy.simplexLogo(context), + ), + ), + ], + ), + const Spacer(), + Text( + message, + style: STextStyles.desktopTextSmall(context), + ), + const Spacer( + flex: 2, + ), + Row( + children: [ + Expanded( + child: SecondaryButton( + label: "Cancel", + buttonHeight: ButtonHeight.l, + onPressed: + Navigator.of(context, rootNavigator: isDesktop).pop, + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.l, + label: "Continue", + onPressed: onContinue, + ), + ), + ], + ) + ], + ), ), - ), - ); + ); + } else { + return StackDialog( + title: title, + message: message, + leftButton: SecondaryButton( + label: "Cancel", + onPressed: Navigator.of(context, rootNavigator: isDesktop).pop, + ), + rightButton: PrimaryButton( + label: "Continue", + onPressed: onContinue, + ), + icon: SizedBox( + width: 64, + height: 32, + child: SvgPicture.asset( + Assets.buy.simplexLogo(context), + ), + ), + ); + } } } From 1d4812c5b2de4b85546f1655eae462173aca9ae5 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 14:34:35 -0600 Subject: [PATCH 114/123] pull down to refresh paynym home view on mobile --- .../subwidgets/paynym_followers_list.dart | 150 +++++++++++------- .../subwidgets/paynym_following_list.dart | 150 +++++++++++------- 2 files changed, 192 insertions(+), 108 deletions(-) diff --git a/lib/pages/paynym/subwidgets/paynym_followers_list.dart b/lib/pages/paynym/subwidgets/paynym_followers_list.dart index dbec19692..d8583954d 100644 --- a/lib/pages/paynym/subwidgets/paynym_followers_list.dart +++ b/lib/pages/paynym/subwidgets/paynym_followers_list.dart @@ -3,11 +3,17 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages/paynym/subwidgets/paynym_card_button.dart'; +import 'package:stackwallet/providers/global/paynym_api_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; class PaynymFollowersList extends ConsumerStatefulWidget { @@ -54,61 +60,97 @@ class _PaynymFollowersListState extends ConsumerState<PaynymFollowersList> { ref.watch(myPaynymAccountStateProvider.state).state?.followers; final count = followers?.length ?? 0; - return ListView.separated( - itemCount: max(count, 1), - separatorBuilder: (BuildContext context, int index) => Container( - height: 1.5, - color: Colors.transparent, - ), - itemBuilder: (BuildContext context, int index) { - if (count == 0) { - return RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Your PayNym followers will appear here", - style: isDesktop - ? STextStyles.desktopTextExtraExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, - ) - : STextStyles.label(context), - ), - ], - ), - ); - } else if (count == 1) { - return RoundedWhiteContainer( - padding: const EdgeInsets.all(0), - child: PaynymCardButton( - walletId: widget.walletId, - accountLite: followers![0], - ), - ); - } else { - BorderRadius? borderRadius; - if (index == 0) { - borderRadius = _borderRadiusFirst; - } else if (index == count - 1) { - borderRadius = _borderRadiusLast; - } + return ConditionalParent( + condition: !isDesktop, + builder: (child) => RefreshIndicator( + child: child, + onRefresh: () async { + try { + final manager = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId); - return Container( - key: Key("paynymCardKey_${followers![index].nymId}"), - decoration: BoxDecoration( - borderRadius: borderRadius, - color: Theme.of(context).extension<StackColors>()!.popupBG, - ), - child: PaynymCardButton( - walletId: widget.walletId, - accountLite: followers[index], - ), - ); - } - }, + // get wallet to access paynym calls + final wallet = manager.wallet as PaynymWalletInterface; + + // get payment code + final pCode = await wallet.getPaymentCode( + DerivePathTypeExt.primaryFor(manager.coin), + ); + + // get account from api + final account = + await ref.read(paynymAPIProvider).nym(pCode.toString()); + + // update my account + if (account.value != null) { + ref.read(myPaynymAccountStateProvider.state).state = + account.value!; + } + } catch (e) { + Logging.instance.log( + "Failed pull down refresh of paynym home page: $e", + level: LogLevel.Warning, + ); + } + }, + ), + child: ListView.separated( + itemCount: max(count, 1), + separatorBuilder: (BuildContext context, int index) => Container( + height: 1.5, + color: Colors.transparent, + ), + itemBuilder: (BuildContext context, int index) { + if (count == 0) { + return RoundedWhiteContainer( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Your PayNym followers will appear here", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ) + : STextStyles.label(context), + ), + ], + ), + ); + } else if (count == 1) { + return RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: PaynymCardButton( + walletId: widget.walletId, + accountLite: followers![0], + ), + ); + } else { + BorderRadius? borderRadius; + if (index == 0) { + borderRadius = _borderRadiusFirst; + } else if (index == count - 1) { + borderRadius = _borderRadiusLast; + } + + return Container( + key: Key("paynymCardKey_${followers![index].nymId}"), + decoration: BoxDecoration( + borderRadius: borderRadius, + color: Theme.of(context).extension<StackColors>()!.popupBG, + ), + child: PaynymCardButton( + walletId: widget.walletId, + accountLite: followers[index], + ), + ); + } + }, + ), ); } } diff --git a/lib/pages/paynym/subwidgets/paynym_following_list.dart b/lib/pages/paynym/subwidgets/paynym_following_list.dart index 754fd6a45..4d9df16ac 100644 --- a/lib/pages/paynym/subwidgets/paynym_following_list.dart +++ b/lib/pages/paynym/subwidgets/paynym_following_list.dart @@ -3,11 +3,17 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages/paynym/subwidgets/paynym_card_button.dart'; +import 'package:stackwallet/providers/global/paynym_api_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; class PaynymFollowingList extends ConsumerStatefulWidget { @@ -54,61 +60,97 @@ class _PaynymFollowingListState extends ConsumerState<PaynymFollowingList> { ref.watch(myPaynymAccountStateProvider.state).state?.following; final count = following?.length ?? 0; - return ListView.separated( - itemCount: max(count, 1), - separatorBuilder: (BuildContext context, int index) => Container( - height: 1.5, - color: Colors.transparent, - ), - itemBuilder: (BuildContext context, int index) { - if (count == 0) { - return RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Your PayNym contacts will appear here", - style: isDesktop - ? STextStyles.desktopTextExtraExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, - ) - : STextStyles.label(context), - ), - ], - ), - ); - } else if (count == 1) { - return RoundedWhiteContainer( - padding: const EdgeInsets.all(0), - child: PaynymCardButton( - walletId: widget.walletId, - accountLite: following![0], - ), - ); - } else { - BorderRadius? borderRadius; - if (index == 0) { - borderRadius = _borderRadiusFirst; - } else if (index == count - 1) { - borderRadius = _borderRadiusLast; - } + return ConditionalParent( + condition: !isDesktop, + builder: (child) => RefreshIndicator( + child: child, + onRefresh: () async { + try { + final manager = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId); - return Container( - key: Key("paynymCardKey_${following![index].nymId}"), - decoration: BoxDecoration( - borderRadius: borderRadius, - color: Theme.of(context).extension<StackColors>()!.popupBG, - ), - child: PaynymCardButton( - walletId: widget.walletId, - accountLite: following[index], - ), - ); - } - }, + // get wallet to access paynym calls + final wallet = manager.wallet as PaynymWalletInterface; + + // get payment code + final pCode = await wallet.getPaymentCode( + DerivePathTypeExt.primaryFor(manager.coin), + ); + + // get account from api + final account = + await ref.read(paynymAPIProvider).nym(pCode.toString()); + + // update my account + if (account.value != null) { + ref.read(myPaynymAccountStateProvider.state).state = + account.value!; + } + } catch (e) { + Logging.instance.log( + "Failed pull down refresh of paynym home page: $e", + level: LogLevel.Warning, + ); + } + }, + ), + child: ListView.separated( + itemCount: max(count, 1), + separatorBuilder: (BuildContext context, int index) => Container( + height: 1.5, + color: Colors.transparent, + ), + itemBuilder: (BuildContext context, int index) { + if (count == 0) { + return RoundedWhiteContainer( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Your PayNym contacts will appear here", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ) + : STextStyles.label(context), + ), + ], + ), + ); + } else if (count == 1) { + return RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: PaynymCardButton( + walletId: widget.walletId, + accountLite: following![0], + ), + ); + } else { + BorderRadius? borderRadius; + if (index == 0) { + borderRadius = _borderRadiusFirst; + } else if (index == count - 1) { + borderRadius = _borderRadiusLast; + } + + return Container( + key: Key("paynymCardKey_${following![index].nymId}"), + decoration: BoxDecoration( + borderRadius: borderRadius, + color: Theme.of(context).extension<StackColors>()!.popupBG, + ), + child: PaynymCardButton( + walletId: widget.walletId, + accountLite: following[index], + ), + ); + } + }, + ), ); } } From a22973cd35becd2722ae4ee29ff945a4f85f42e0 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 15:37:59 -0600 Subject: [PATCH 115/123] WIP addresses list ui --- .../receive_view/addresses/address_card.dart | 132 ++++++++++ .../addresses/address_qr_popup.dart | 193 ++++++++++++++ .../addresses/edit_address_label_view.dart | 241 ++++++++++++++++++ .../receiving_addresses_view.dart | 32 +-- lib/pages/receive_view/receive_view.dart | 18 +- lib/route_generator.dart | 19 +- lib/widgets/rounded_container.dart | 3 + lib/widgets/rounded_white_container.dart | 3 + 8 files changed, 610 insertions(+), 31 deletions(-) create mode 100644 lib/pages/receive_view/addresses/address_card.dart create mode 100644 lib/pages/receive_view/addresses/address_qr_popup.dart create mode 100644 lib/pages/receive_view/addresses/edit_address_label_view.dart rename lib/pages/receive_view/{ => addresses}/receiving_addresses_view.dart (84%) diff --git a/lib/pages/receive_view/addresses/address_card.dart b/lib/pages/receive_view/addresses/address_card.dart new file mode 100644 index 000000000..1a47c256c --- /dev/null +++ b/lib/pages/receive_view/addresses/address_card.dart @@ -0,0 +1,132 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/receive_view/addresses/address_qr_popup.dart'; +import 'package:stackwallet/pages/receive_view/addresses/edit_address_label_view.dart'; +import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/icon_widgets/copy_icon.dart'; +import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:tuple/tuple.dart'; + +class AddressCard extends StatelessWidget { + const AddressCard({ + Key? key, + required this.address, + required this.walletId, + required this.coin, + this.clipboard = const ClipboardWrapper(), + }) : super(key: key); + + final Address address; + final String walletId; + final Coin coin; + final ClipboardInterface clipboard; + + @override + Widget build(BuildContext context) { + return RoundedWhiteContainer( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "TODO: label", + style: STextStyles.itemSubtitle(context), + ), + CustomTextButton( + text: "Edit label", + textSize: 14, + onTap: () { + Navigator.of(context).pushNamed( + EditAddressLabelView.routeName, + arguments: Tuple2( + address, + walletId, + ), + ); + }, + ), + ], + ), + const SizedBox( + height: 8, + ), + Row( + children: [ + Expanded( + child: SelectableText( + address.value, + style: STextStyles.itemSubtitle12(context), + ), + ) + ], + ), + const SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: SecondaryButton( + label: "Copy address", + icon: CopyIcon( + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondary, + ), + onPressed: () async { + await clipboard.setData( + ClipboardData( + text: address.value, + ), + ); + unawaited( + showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + context: context, + ), + ); + }, + ), + ), + const SizedBox( + width: 12, + ), + Expanded( + child: SecondaryButton( + label: "Show QR Code", + icon: QrCodeIcon( + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondary, + ), + onPressed: () { + showDialog<void>( + context: context, + builder: (context) => AddressQrPopup( + address: address, + coin: coin, + clipboard: clipboard, + ), + ); + }, + ), + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/pages/receive_view/addresses/address_qr_popup.dart b/lib/pages/receive_view/addresses/address_qr_popup.dart new file mode 100644 index 000000000..75b3509de --- /dev/null +++ b/lib/pages/receive_view/addresses/address_qr_popup.dart @@ -0,0 +1,193 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:ui' as ui; + +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/utilities/address_utils.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/stack_dialog.dart'; + +class AddressQrPopup extends StatefulWidget { + const AddressQrPopup({ + Key? key, + required this.address, + required this.coin, + this.clipboard = const ClipboardWrapper(), + }) : super(key: key); + + final Address address; + final Coin coin; + final ClipboardInterface clipboard; + + @override + State<AddressQrPopup> createState() => _AddressQrPopupState(); +} + +class _AddressQrPopupState extends State<AddressQrPopup> { + final _qrKey = GlobalKey(); + final isDesktop = Util.isDesktop; + + Future<void> _capturePng(bool shouldSaveInsteadOfShare) async { + try { + RenderRepaintBoundary boundary = + _qrKey.currentContext?.findRenderObject() as RenderRepaintBoundary; + ui.Image image = await boundary.toImage(); + ByteData? byteData = + await image.toByteData(format: ui.ImageByteFormat.png); + Uint8List pngBytes = byteData!.buffer.asUint8List(); + + if (shouldSaveInsteadOfShare) { + if (isDesktop) { + final dir = Directory("${Platform.environment['HOME']}"); + if (!dir.existsSync()) { + throw Exception( + "Home dir not found while trying to open filepicker on QR image save"); + } + final path = await FilePicker.platform.saveFile( + fileName: "qrcode.png", + initialDirectory: dir.path, + ); + + if (path != null) { + final file = File(path); + if (file.existsSync()) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.warning, + message: "$path already exists!", + context: context, + ), + ); + } else { + await file.writeAsBytes(pngBytes); + unawaited( + showFloatingFlushBar( + type: FlushBarType.success, + message: "$path saved!", + context: context, + ), + ); + } + } + } else { + // await DocumentFileSavePlus.saveFile( + // pngBytes, + // "receive_qr_code_${DateTime.now().toLocal().toIso8601String()}.png", + // "image/png"); + } + } else { + final tempDir = await getTemporaryDirectory(); + final file = await File("${tempDir.path}/qrcode.png").create(); + await file.writeAsBytes(pngBytes); + + await Share.shareFiles(["${tempDir.path}/qrcode.png"], + text: "Receive URI QR Code"); + } + } catch (e) { + //todo: comeback to this + debugPrint(e.toString()); + } + } + + @override + Widget build(BuildContext context) { + return StackDialogBase( + child: Column( + children: [ + Text( + "todo: custom label", + style: STextStyles.pageTitleH2(context), + ), + const SizedBox( + height: 8, + ), + Text( + widget.address.value, + style: STextStyles.itemSubtitle(context), + ), + const SizedBox( + height: 16, + ), + Center( + child: RepaintBoundary( + key: _qrKey, + child: QrImage( + data: AddressUtils.buildUriString( + widget.coin, + widget.address.value, + {}, + ), + size: 220, + backgroundColor: + Theme.of(context).extension<StackColors>()!.popupBG, + foregroundColor: + Theme.of(context).extension<StackColors>()!.accentColorDark, + ), + ), + ), + const SizedBox( + height: 16, + ), + Row( + children: [ + Expanded( + child: SecondaryButton( + width: 170, + buttonHeight: isDesktop ? ButtonHeight.l : null, + onPressed: () async { + await _capturePng(false); + }, + label: "Share", + icon: SvgPicture.asset( + Assets.svg.share, + width: 20, + height: 20, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondary, + ), + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: PrimaryButton( + width: 170, + onPressed: () async { + await _capturePng(true); + }, + label: "Save", + icon: SvgPicture.asset( + Assets.svg.arrowDown, + width: 20, + height: 20, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + ), + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/pages/receive_view/addresses/edit_address_label_view.dart b/lib/pages/receive_view/addresses/edit_address_label_view.dart new file mode 100644 index 000000000..d44b61686 --- /dev/null +++ b/lib/pages/receive_view/addresses/edit_address_label_view.dart @@ -0,0 +1,241 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/models/isar/models/address/address.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; +import 'package:stackwallet/widgets/stack_text_field.dart'; +import 'package:stackwallet/widgets/textfield_icon_button.dart'; + +class EditAddressLabelView extends ConsumerStatefulWidget { + const EditAddressLabelView({ + Key? key, + required this.address, + required this.walletId, + }) : super(key: key); + + static const String routeName = "/editAddressLabel"; + + final Address address; + final String walletId; + + @override + ConsumerState<EditAddressLabelView> createState() => + _EditAddressLabelViewState(); +} + +class _EditAddressLabelViewState extends ConsumerState<EditAddressLabelView> { + late final TextEditingController _labelFieldController; + final labelFieldFocusNode = FocusNode(); + + late final bool isDesktop; + + @override + void initState() { + isDesktop = Util.isDesktop; + _labelFieldController = TextEditingController(); + _labelFieldController.text = "todo: address.label"; + super.initState(); + } + + @override + void dispose() { + _labelFieldController.dispose(); + labelFieldFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: child, + ), + child: Scaffold( + backgroundColor: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.background, + appBar: isDesktop + ? null + : AppBar( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + leading: AppBarBackButton( + onPressed: () async { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future<void>.delayed( + const Duration(milliseconds: 75)); + } + if (mounted) { + Navigator.of(context).pop(); + } + }, + ), + title: Text( + "Edit label", + style: STextStyles.navBarTitle(context), + ), + ), + body: ConditionalParent( + condition: !isDesktop, + builder: (child) => Padding( + padding: const EdgeInsets.all(12), + child: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(4), + child: child, + ), + ), + ), + ); + }, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (isDesktop) + Padding( + padding: const EdgeInsets.only( + left: 32, + bottom: 12, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Edit label", + style: STextStyles.desktopH3(context), + ), + const DesktopDialogCloseButton(), + ], + ), + ), + Padding( + padding: isDesktop + ? const EdgeInsets.symmetric( + horizontal: 32, + ) + : const EdgeInsets.all(0), + child: ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: Util.isDesktop ? false : true, + enableSuggestions: Util.isDesktop ? false : true, + controller: _labelFieldController, + style: isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textFieldActiveText, + height: 1.8, + ) + : STextStyles.field(context), + focusNode: labelFieldFocusNode, + decoration: standardInputDecoration( + "Address label", + labelFieldFocusNode, + context, + desktopMed: isDesktop, + ).copyWith( + contentPadding: isDesktop + ? const EdgeInsets.only( + left: 16, + top: 11, + bottom: 12, + right: 5, + ) + : null, + suffixIcon: _labelFieldController.text.isNotEmpty + ? Padding( + padding: const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + children: [ + TextFieldIconButton( + child: const XIcon(), + onTap: () async { + setState(() { + _labelFieldController.text = ""; + }); + }, + ), + ], + ), + ), + ) + : null, + ), + ), + ), + ), + // if (!isDesktop) + const Spacer(), + if (isDesktop) + Padding( + padding: const EdgeInsets.all(32), + child: PrimaryButton( + label: "Save", + onPressed: () async { + // todo: update address + // await ref + // .read(notesServiceChangeNotifierProvider( + // widget.walletId)) + // .editOrAddNote( + // txid: widget.txid, + // note: _labelFieldController.text, + // ); + // if (mounted) { + // Navigator.of(context).pop(); + // } + }, + ), + ), + if (!isDesktop) + TextButton( + onPressed: () async { + // todo: update address + // await ref + // .read( + // notesServiceChangeNotifierProvider(widget.walletId)) + // .editOrAddNote( + // txid: widget.txid, + // note: _labelFieldController.text, + // ); + // if (mounted) { + // Navigator.of(context).pop(); + // } + }, + style: Theme.of(context) + .extension<StackColors>()! + .getPrimaryEnabledButtonStyle(context), + child: Text( + "Save", + style: STextStyles.button(context), + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/receive_view/receiving_addresses_view.dart b/lib/pages/receive_view/addresses/receiving_addresses_view.dart similarity index 84% rename from lib/pages/receive_view/receiving_addresses_view.dart rename to lib/pages/receive_view/addresses/receiving_addresses_view.dart index e5f1d88bf..927043373 100644 --- a/lib/pages/receive_view/receiving_addresses_view.dart +++ b/lib/pages/receive_view/addresses/receiving_addresses_view.dart @@ -3,6 +3,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/db/main_db.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/pages/receive_view/addresses/address_card.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; @@ -10,7 +12,6 @@ import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/loading_indicator.dart'; -import 'package:stackwallet/widgets/rounded_white_container.dart'; class ReceivingAddressesView extends ConsumerWidget { const ReceivingAddressesView({ @@ -28,6 +29,8 @@ class ReceivingAddressesView extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final coin = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).coin)); return ConditionalParent( condition: !isDesktop, builder: (child) => Background( @@ -73,7 +76,9 @@ class ReceivingAddressesView extends ConsumerWidget { height: 10, ), itemBuilder: (_, index) => AddressCard( + walletId: walletId, address: snapshot.data![index], + coin: coin, ), ); } else { @@ -89,28 +94,3 @@ class ReceivingAddressesView extends ConsumerWidget { ); } } - -class AddressCard extends StatelessWidget { - const AddressCard({ - Key? key, - required this.address, - }) : super(key: key); - - final Address address; - - @override - Widget build(BuildContext context) { - return RoundedWhiteContainer( - child: Row( - children: [ - Expanded( - child: Text( - address.value, - style: STextStyles.itemSubtitle12(context), - ), - ) - ], - ), - ); - } -} diff --git a/lib/pages/receive_view/receive_view.dart b/lib/pages/receive_view/receive_view.dart index 2d7d11b45..52283111c 100644 --- a/lib/pages/receive_view/receive_view.dart +++ b/lib/pages/receive_view/receive_view.dart @@ -6,8 +6,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/receive_view/addresses/receiving_addresses_view.dart'; import 'package:stackwallet/pages/receive_view/generate_receiving_uri_qr_code_view.dart'; -import 'package:stackwallet/pages/receive_view/receiving_addresses_view.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -187,11 +187,21 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> { ); }, child: RoundedWhiteContainer( + boxShadow: [ + Theme.of(context) + .extension<StackColors>()! + .standardBoxShadow, + ], child: Material( color: Colors.transparent, - child: Text( - "Address list", - style: STextStyles.baseXS(context), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12, + ), + child: Text( + "Address list", + style: STextStyles.field(context), + ), ), ), ), diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 970246043..d1ed6a4bd 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -6,6 +6,7 @@ import 'package:stackwallet/models/buy/response_objects/quote.dart'; import 'package:stackwallet/models/contact_address_entry.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart'; +import 'package:stackwallet/models/isar/models/address/address.dart'; import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/models/send_view_auto_fill_data.dart'; import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart'; @@ -44,9 +45,10 @@ import 'package:stackwallet/pages/paynym/add_new_paynym_follow_view.dart'; import 'package:stackwallet/pages/paynym/paynym_claim_view.dart'; import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart'; +import 'package:stackwallet/pages/receive_view/addresses/edit_address_label_view.dart'; +import 'package:stackwallet/pages/receive_view/addresses/receiving_addresses_view.dart'; import 'package:stackwallet/pages/receive_view/generate_receiving_uri_qr_code_view.dart'; import 'package:stackwallet/pages/receive_view/receive_view.dart'; -import 'package:stackwallet/pages/receive_view/receiving_addresses_view.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; import 'package:stackwallet/pages/send_view/send_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/about_view.dart'; @@ -474,6 +476,21 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case EditAddressLabelView.routeName: + if (args is Tuple2<Address, String>) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => EditAddressLabelView( + address: args.item1, + walletId: args.item2, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case EditTradeNoteView.routeName: if (args is Tuple2<String, String>) { return getRoute( diff --git a/lib/widgets/rounded_container.dart b/lib/widgets/rounded_container.dart index 9f9bfbd8d..d689d9ca8 100644 --- a/lib/widgets/rounded_container.dart +++ b/lib/widgets/rounded_container.dart @@ -11,6 +11,7 @@ class RoundedContainer extends StatelessWidget { this.width, this.height, this.borderColor, + this.boxShadow, }) : super(key: key); final Widget? child; @@ -20,6 +21,7 @@ class RoundedContainer extends StatelessWidget { final double? width; final double? height; final Color? borderColor; + final List<BoxShadow>? boxShadow; @override Widget build(BuildContext context) { @@ -32,6 +34,7 @@ class RoundedContainer extends StatelessWidget { Constants.size.circularBorderRadius * radiusMultiplier, ), border: borderColor == null ? null : Border.all(color: borderColor!), + boxShadow: boxShadow, ), child: Padding( padding: padding, diff --git a/lib/widgets/rounded_white_container.dart b/lib/widgets/rounded_white_container.dart index 1173e95b1..2ade9b729 100644 --- a/lib/widgets/rounded_white_container.dart +++ b/lib/widgets/rounded_white_container.dart @@ -11,6 +11,7 @@ class RoundedWhiteContainer extends StatelessWidget { this.width, this.height, this.borderColor, + this.boxShadow, }) : super(key: key); final Widget? child; @@ -19,6 +20,7 @@ class RoundedWhiteContainer extends StatelessWidget { final double? width; final double? height; final Color? borderColor; + final List<BoxShadow>? boxShadow; @override Widget build(BuildContext context) { @@ -29,6 +31,7 @@ class RoundedWhiteContainer extends StatelessWidget { width: width, height: height, borderColor: borderColor, + boxShadow: boxShadow, child: child, ); } From 5ccc868c9b28cd5b1e0db7c15970652eac4312b2 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 15:41:54 -0600 Subject: [PATCH 116/123] update amount changed state on send view when tapping send all --- lib/pages/send_view/send_view.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index c472bcc11..eab3d0638 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -1338,6 +1338,7 @@ class _SendViewState extends ConsumerState<SendView> { Constants.decimalPlacesForCoin( coin)); } + _cryptoAmountChanged(); }, ), ], From 97604a792f1cc0d190821629ae3ca93e0155e83a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 15:48:06 -0600 Subject: [PATCH 117/123] fix offline wallet creation for namecoin and particl --- .../coins/namecoin/namecoin_wallet.dart | 26 +++++++++++-------- .../coins/particl/particl_wallet.dart | 26 +++++++++++-------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 1ee89d95f..3129ed765 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -1438,17 +1438,21 @@ class NamecoinWallet extends CoinServiceAPI Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { - final features = await electrumXClient.getServerFeatures(); - Logging.instance.log("features: $features", level: LogLevel.Info); - switch (coin) { - case Coin.namecoin: - if (features['genesis_hash'] != GENESIS_HASH_MAINNET) { - throw Exception("genesis hash does not match main net!"); - } - break; - default: - throw Exception( - "Attempted to generate a NamecoinWallet using a non namecoin coin type: ${coin.name}"); + try { + final features = await electrumXClient.getServerFeatures(); + Logging.instance.log("features: $features", level: LogLevel.Info); + switch (coin) { + case Coin.namecoin: + if (features['genesis_hash'] != GENESIS_HASH_MAINNET) { + throw Exception("genesis hash does not match main net!"); + } + break; + default: + throw Exception( + "Attempted to generate a NamecoinWallet using a non namecoin coin type: ${coin.name}"); + } + } catch (e, s) { + Logging.instance.log("$e/n$s", level: LogLevel.Info); } } diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 625b4d384..7b99eae00 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -1353,17 +1353,21 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { - final features = await electrumXClient.getServerFeatures(); - Logging.instance.log("features: $features", level: LogLevel.Info); - switch (coin) { - case Coin.particl: - if (features['genesis_hash'] != GENESIS_HASH_MAINNET) { - throw Exception("genesis hash does not match main net!"); - } - break; - default: - throw Exception( - "Attempted to generate a ParticlWallet using a non particl coin type: ${coin.name}"); + try { + final features = await electrumXClient.getServerFeatures(); + Logging.instance.log("features: $features", level: LogLevel.Info); + switch (coin) { + case Coin.particl: + if (features['genesis_hash'] != GENESIS_HASH_MAINNET) { + throw Exception("genesis hash does not match main net!"); + } + break; + default: + throw Exception( + "Attempted to generate a ParticlWallet using a non particl coin type: ${coin.name}"); + } + } catch (e, s) { + Logging.instance.log("$e/n$s", level: LogLevel.Info); } } From 4ca5cf097881070daa90486adc5c45dfffe65ef4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 15:54:29 -0600 Subject: [PATCH 118/123] ocean breeze secondary button text color fix --- lib/utilities/theme/ocean_breeze_colors.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utilities/theme/ocean_breeze_colors.dart b/lib/utilities/theme/ocean_breeze_colors.dart index 1ba64843d..f8bcaf0c1 100644 --- a/lib/utilities/theme/ocean_breeze_colors.dart +++ b/lib/utilities/theme/ocean_breeze_colors.dart @@ -94,7 +94,7 @@ class OceanBreezeColors extends StackColorTheme { @override Color get buttonTextPrimary => const Color(0xFFFFFFFF); @override - Color get buttonTextSecondary => const Color(0xFF232323); + Color get buttonTextSecondary => accentColorDark; @override Color get buttonTextPrimaryDisabled => const Color(0xFFFFFFFF); @override From a781b24c5c0f20b31ca2cef767fa90f9a605452e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 15:54:48 -0600 Subject: [PATCH 119/123] paynym home view button icon color fix --- lib/pages/paynym/paynym_home_view.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pages/paynym/paynym_home_view.dart b/lib/pages/paynym/paynym_home_view.dart index 96baa5daf..210d46687 100644 --- a/lib/pages/paynym/paynym_home_view.dart +++ b/lib/pages/paynym/paynym_home_view.dart @@ -322,7 +322,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { height: 12, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .buttonTextSecondary, ), onPressed: () async { await Clipboard.setData( @@ -359,7 +359,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { height: 12, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .buttonTextSecondary, ), onPressed: () async { Rect? sharePositionOrigin; @@ -396,7 +396,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { height: 12, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .buttonTextSecondary, ), onPressed: () { showDialog<void>( From afc25e3f0691b3f9d6c61a6bb927ac503b006fe7 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 15:57:48 -0600 Subject: [PATCH 120/123] paynym home view app bar button icon color fix --- lib/pages/paynym/paynym_home_view.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/paynym/paynym_home_view.dart b/lib/pages/paynym/paynym_home_view.dart index 210d46687..9292b8acb 100644 --- a/lib/pages/paynym/paynym_home_view.dart +++ b/lib/pages/paynym/paynym_home_view.dart @@ -201,7 +201,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { height: 20, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .accentColorDark, ), onPressed: () { Navigator.of(context).pushNamed( @@ -223,7 +223,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { height: 20, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .accentColorDark, ), onPressed: () { // todo info ? From f0a8d65b3e99ad2c68f61ce6bb9efbbaf251fecc Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 2 Feb 2023 16:19:14 -0600 Subject: [PATCH 121/123] show sent tx immediately in history --- .../coins/bitcoin/bitcoin_wallet.dart | 65 +++++++------------ .../coins/bitcoincash/bitcoincash_wallet.dart | 65 +++++++------------ .../coins/dogecoin/dogecoin_wallet.dart | 65 +++++++------------ lib/services/coins/firo/firo_wallet.dart | 63 +++++++----------- .../coins/litecoin/litecoin_wallet.dart | 65 +++++++------------ lib/services/coins/manager.dart | 11 +++- .../coins/namecoin/namecoin_wallet.dart | 65 +++++++------------ .../coins/particl/particl_wallet.dart | 65 +++++++------------ 8 files changed, 184 insertions(+), 280 deletions(-) diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 3bf151ccc..60ba85895 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1267,46 +1267,31 @@ class BitcoinWallet extends CoinServiceAPI // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _fetchTransactionData(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 4a4ff041b..1963c89bc 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -1200,46 +1200,31 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _fetchTransactionData(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } bool validateCashAddr(String cashAddr) { diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 85a2abc81..b67054b4c 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -1059,46 +1059,31 @@ class DogecoinWallet extends CoinServiceAPI // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _fetchTransactionData(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 03e788e54..9f767dbba 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -818,44 +818,31 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final currentPrice = await firoPrice; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _fetchTransactionData(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } /// Holds the max fee that can be sent diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index ecbc9cbc0..03b569511 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -1214,46 +1214,31 @@ class LitecoinWallet extends CoinServiceAPI // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _refreshTransactions(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override diff --git a/lib/services/coins/manager.dart b/lib/services/coins/manager.dart index 892766cf5..203c2d05f 100644 --- a/lib/services/coins/manager.dart +++ b/lib/services/coins/manager.dart @@ -110,8 +110,15 @@ class Manager with ChangeNotifier { try { final txid = await _currentWallet.confirmSend(txData: txData); - txData["txid"] = txid; - await _currentWallet.updateSentCachedTxData(txData); + try { + txData["txid"] = txid; + await _currentWallet.updateSentCachedTxData(txData); + } catch (e, s) { + // do not rethrow as that would get handled as a send failure further up + // also this is not critical code and transaction should show up on \ + // refresh regardless + Logging.instance.log("$e\n$s", level: LogLevel.Warning); + } notifyListeners(); return txid; diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 3129ed765..10852044b 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -1203,46 +1203,31 @@ class NamecoinWallet extends CoinServiceAPI // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _refreshTransactions(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 7b99eae00..1f6c7a2ea 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -1131,46 +1131,31 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _refreshTransactions(); - // _transactionData = Future(() => data); - // } else { - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); - // } + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override From ab370186427ec7aacf8656fe08f0910d228ff81f Mon Sep 17 00:00:00 2001 From: julian-CStack <97684800+julian-CStack@users.noreply.github.com> Date: Thu, 2 Feb 2023 18:02:23 -0600 Subject: [PATCH 122/123] Update test.yaml --- .github/workflows/test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4638e84dd..01cd71173 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,6 +23,7 @@ jobs: run: | cargo install cargo-ndk rustup target add x86_64-unknown-linux-gnu + sudo apt clean sudo apt update sudo apt install -y unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake openjdk-8-jre-headless libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev llvm sudo apt install -y debhelper libclang-dev cargo rustc opencl-headers libssl-dev ocl-icd-opencl-dev From a7bff0f01805c50446600c774fa7df3254fe69c4 Mon Sep 17 00:00:00 2001 From: Diego Salazar <diego@cypherstack.com> Date: Thu, 2 Feb 2023 18:12:11 -0700 Subject: [PATCH 123/123] 121 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 61c22e7aa..86fd250cc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.36+117 +version: 1.5.36+121 environment: sdk: ">=2.17.0 <3.0.0"