diff --git a/lib/models/isar/models/blockchain_data/address.dart b/lib/models/isar/models/blockchain_data/address.dart index b131c20f8..cbdc6b2a1 100644 --- a/lib/models/isar/models/blockchain_data/address.dart +++ b/lib/models/isar/models/blockchain_data/address.dart @@ -1,4 +1,3 @@ -import 'package:equatable/equatable.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/exceptions/address/address_exception.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/crypto_currency_address.dart'; @@ -13,7 +12,7 @@ class Address extends CryptoCurrencyAddress { required this.value, required this.publicKey, required this.derivationIndex, - // required this.derivationPath, + required this.derivationPath, required this.type, required this.subType, this.otherData, @@ -97,7 +96,7 @@ enum AddressSubType { } @Embedded(inheritance: false) -class DerivationPath extends Equatable { +class DerivationPath { late final String value; List getComponents() => value.split("/"); @@ -107,7 +106,11 @@ class DerivationPath extends Equatable { @override toString() => value; + @override + bool operator ==(Object other) => + identical(this, other) || other is DerivationPath && value == other.value; + @ignore @override - List get props => [value]; + int get hashCode => value.hashCode; } diff --git a/lib/models/isar/models/blockchain_data/address.g.dart b/lib/models/isar/models/blockchain_data/address.g.dart index 567dc993a..37186584b 100644 --- a/lib/models/isar/models/blockchain_data/address.g.dart +++ b/lib/models/isar/models/blockchain_data/address.g.dart @@ -182,6 +182,11 @@ Address _addressDeserialize( ) { final object = Address( derivationIndex: reader.readLong(offsets[0]), + derivationPath: reader.readObjectOrNull( + offsets[1], + DerivationPathSchema.deserialize, + allOffsets, + ), otherData: reader.readStringOrNull(offsets[2]), publicKey: reader.readByteList(offsets[3]) ?? [], subType: _AddresssubTypeValueEnumMap[reader.readByteOrNull(offsets[4])] ?? @@ -191,11 +196,6 @@ Address _addressDeserialize( value: reader.readString(offsets[6]), walletId: reader.readString(offsets[7]), ); - object.derivationPath = reader.readObjectOrNull( - offsets[1], - DerivationPathSchema.deserialize, - allOffsets, - ); object.id = id; return object; } diff --git a/lib/models/isar/models/blockchain_data/input.dart b/lib/models/isar/models/blockchain_data/input.dart index 9cee0db08..b530da61a 100644 --- a/lib/models/isar/models/blockchain_data/input.dart +++ b/lib/models/isar/models/blockchain_data/input.dart @@ -9,6 +9,7 @@ class Input { this.vout = -1, this.scriptSig, this.scriptSigAsm, + this.witness, this.isCoinbase, this.sequence, this.innerRedeemScriptAsm, diff --git a/lib/models/isar/models/blockchain_data/input.g.dart b/lib/models/isar/models/blockchain_data/input.g.dart index d197c2fdc..608446fea 100644 --- a/lib/models/isar/models/blockchain_data/input.g.dart +++ b/lib/models/isar/models/blockchain_data/input.g.dart @@ -124,8 +124,8 @@ Input _inputDeserialize( sequence: reader.readLongOrNull(offsets[4]), txid: reader.readStringOrNull(offsets[5]) ?? "error", vout: reader.readLongOrNull(offsets[6]) ?? -1, + witness: reader.readStringOrNull(offsets[7]), ); - object.witness = reader.readStringOrNull(offsets[7]); return object; } diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index ac42df4bb..1c93321eb 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -457,6 +457,7 @@ class BitcoinWallet extends CoinServiceAPI publicKey: node.publicKey, type: addrType, derivationIndex: index + j, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, @@ -1556,6 +1557,7 @@ class BitcoinWallet extends CoinServiceAPI publicKey: node.publicKey, type: addrType, derivationIndex: index, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 559c3eb38..3a7e25545 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -413,6 +413,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { publicKey: node.publicKey, type: addrType, derivationIndex: index + j, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, @@ -1517,6 +1518,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { publicKey: node.publicKey, type: addrType, derivationIndex: index, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, @@ -2216,6 +2218,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { publicKey: [], type: AddressType.nonWallet, derivationIndex: -1, + derivationPath: null, subType: AddressSubType.nonWallet, ); } diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 4f2ca7090..c5e568381 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -398,6 +398,7 @@ class DogecoinWallet extends CoinServiceAPI publicKey: node.publicKey, type: isar_models.AddressType.p2pkh, derivationIndex: index + j, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, @@ -1332,6 +1333,7 @@ class DogecoinWallet extends CoinServiceAPI publicKey: node.publicKey, type: isar_models.AddressType.p2pkh, derivationIndex: index, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index 85c5ec046..b6986508d 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -865,6 +865,7 @@ class EpicCashWallet extends CoinServiceAPI walletId: walletId, value: walletAddress!, derivationIndex: index, + derivationPath: null, type: isar_models.AddressType.mimbleWimble, subType: isar_models.AddressSubType.receiving, publicKey: [], // ?? diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 2a34b6a62..de2088a5d 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -3066,6 +3066,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { walletId: walletId, value: transactionInfo["address"] as String, derivationIndex: -1, + derivationPath: null, type: isar_models.AddressType.nonWallet, subType: isar_models.AddressSubType.nonWallet, publicKey: [], @@ -3555,6 +3556,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { walletId: walletId, value: outAddress, derivationIndex: -1, + derivationPath: null, type: isar_models.AddressType.nonWallet, subType: isar_models.AddressSubType.nonWallet, publicKey: [], @@ -3835,7 +3837,11 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { derivations = Map.from( jsonDecode(changeDerivationsString ?? "{}") as Map); } - + final derivePath = constructDerivePath( + networkWIF: _network.wif, + chain: chain, + index: index, + ); if (derivations!.isNotEmpty) { if (derivations["$index"] == null) { await fillAddresses( @@ -3854,16 +3860,12 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { derivations["$index"]['publicKey'] as String), type: isar_models.AddressType.p2pkh, derivationIndex: index, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, ); } else { - final derivePath = constructDerivePath( - networkWIF: _network.wif, - chain: chain, - index: index, - ); final node = await Bip32Utils.getBip32Node( _mnemonic!, _mnemonicPassphrase!, @@ -3882,6 +3884,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { publicKey: node.publicKey, type: isar_models.AddressType.p2pkh, derivationIndex: index, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, @@ -4299,6 +4302,11 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { int numTxs = await futureNumTxs; if (numTxs >= 1) { receivingIndex = i; + final derivePath = constructDerivePath( + networkWIF: _network.wif, + chain: 0, + index: receivingIndex, + ); final addr = isar_models.Address( walletId: walletId, value: address, @@ -4306,6 +4314,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { receiveDerivation['publicKey'] as String), type: isar_models.AddressType.p2pkh, derivationIndex: i, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: isar_models.AddressSubType.receiving, ); receivingAddressArray.add(addr); @@ -4325,6 +4334,11 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { int numTxs = await _futureNumTxs; if (numTxs >= 1) { changeIndex = i; + final derivePath = constructDerivePath( + networkWIF: _network.wif, + chain: 1, + index: changeIndex, + ); final addr = isar_models.Address( walletId: walletId, value: _address, @@ -4332,6 +4346,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { changeDerivation['publicKey'] as String), type: isar_models.AddressType.p2pkh, derivationIndex: i, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: isar_models.AddressSubType.change, ); changeAddressArray.add(addr); @@ -4929,6 +4944,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { walletId: walletId, value: tx["address"] as String, derivationIndex: -2, + derivationPath: null, type: isar_models.AddressType.nonWallet, subType: isar_models.AddressSubType.unknown, publicKey: [], diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index 5141f0a3a..c8b69c8c8 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -426,6 +426,7 @@ class LitecoinWallet extends CoinServiceAPI publicKey: node.publicKey, type: addrType, derivationIndex: index + j, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, @@ -1263,8 +1264,6 @@ class LitecoinWallet extends CoinServiceAPI late SecureStorageInterface _secureStore; - - @override Future updateNode(bool shouldRefresh) async { final failovers = NodeService(secureStorageInterface: _secureStore) @@ -1540,6 +1539,7 @@ class LitecoinWallet extends CoinServiceAPI publicKey: node.publicKey, type: addrType, derivationIndex: index, + derivationPath: isar_models.DerivationPath()..value = derivePath, subType: chain == 0 ? isar_models.AddressSubType.receiving : isar_models.AddressSubType.change, diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart index 886bda1b8..8c956bb76 100644 --- a/lib/services/coins/monero/monero_wallet.dart +++ b/lib/services/coins/monero/monero_wallet.dart @@ -854,6 +854,7 @@ class MoneroWallet extends CoinServiceAPI with WalletCache, WalletDB { return isar_models.Address( walletId: walletId, derivationIndex: index, + derivationPath: null, value: address, publicKey: [], type: isar_models.AddressType.cryptonote, diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 43982875e..3be5ad6d7 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -420,6 +420,7 @@ class NamecoinWallet extends CoinServiceAPI publicKey: node.publicKey, value: addressString, derivationIndex: index + j, + derivationPath: isar_models.DerivationPath()..value = derivePath, ); receivingNodes.addAll({ @@ -1517,6 +1518,7 @@ class NamecoinWallet extends CoinServiceAPI return isar_models.Address( walletId: walletId, derivationIndex: index, + derivationPath: isar_models.DerivationPath()..value = derivePath, value: address, publicKey: node.publicKey, type: addrType, diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 6b0275fdc..577bf2def 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -401,6 +401,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { publicKey: node.publicKey, value: addressString, derivationIndex: index + j, + derivationPath: isar_models.DerivationPath()..value = derivePath, ); receivingNodes.addAll({ @@ -1411,6 +1412,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { return isar_models.Address( walletId: walletId, derivationIndex: index, + derivationPath: isar_models.DerivationPath()..value = derivePath, value: address, publicKey: node.publicKey, type: addrType, @@ -2175,6 +2177,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { value: address, publicKey: [], derivationIndex: -1, + derivationPath: null, ); } } catch (s) { diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart index 12343f036..044f377a3 100644 --- a/lib/services/coins/wownero/wownero_wallet.dart +++ b/lib/services/coins/wownero/wownero_wallet.dart @@ -862,6 +862,7 @@ class WowneroWallet extends CoinServiceAPI with WalletCache, WalletDB { return isar_models.Address( walletId: walletId, derivationIndex: index, + derivationPath: null, value: address, publicKey: [], type: isar_models.AddressType.cryptonote, diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index f50c38e44..6e2316185 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -139,6 +139,7 @@ mixin ElectrumXParsing { walletId: walletId, value: possible, derivationIndex: -1, + derivationPath: null, subType: AddressSubType.nonWallet, type: AddressType.nonWallet, publicKey: [], diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart index 5944f69cf..697e00b53 100644 --- a/lib/services/mixins/paynym_wallet_interface.dart +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -847,6 +847,8 @@ mixin PaynymWalletInterface { value: notificationAddress, publicKey: [], derivationIndex: 0, + derivationPath: + null, // might as well use null due to complexity of context type: oldAddress.type, subType: AddressSubType.paynymNotification, otherData: await storeCode(code.toString()), @@ -1023,6 +1025,8 @@ mixin PaynymWalletInterface { value: addressString, publicKey: pair.publicKey, derivationIndex: derivationIndex, + derivationPath: + null, // might as well use null due to complexity of context type: AddressType.nonWallet, subType: AddressSubType.paynymSend, otherData: await storeCode(toPaymentCode.toString()), @@ -1090,6 +1094,8 @@ mixin PaynymWalletInterface { value: addressString, publicKey: pair.publicKey, derivationIndex: derivationIndex, + derivationPath: + null, // might as well use null due to complexity of context type: addrType, subType: AddressSubType.paynymReceive, otherData: await storeCode(fromPaymentCode.toString()), @@ -1214,6 +1220,8 @@ mixin PaynymWalletInterface { value: addressString, publicKey: paymentCode.getPubKey(), derivationIndex: 0, + derivationPath: + null, // might as well use null due to complexity of context type: type, subType: AddressSubType.paynymNotification, otherData: await storeCode(paymentCode.toString()), diff --git a/lib/utilities/db_version_migration.dart b/lib/utilities/db_version_migration.dart index 75b20a42e..45c15ab82 100644 --- a/lib/utilities/db_version_migration.dart +++ b/lib/utilities/db_version_migration.dart @@ -494,6 +494,7 @@ class DbVersionMigrator with WalletDB { value: tx.address, publicKey: [], derivationIndex: -1, + derivationPath: null, type: isar_models.AddressType.unknown, subType: type == isar_models.TransactionType.incoming ? isar_models.AddressSubType.receiving @@ -529,6 +530,7 @@ class DbVersionMigrator with WalletDB { value: addr, publicKey: Format.stringToUint8List(pubKey), derivationIndex: index, + derivationPath: null, // we have no idea what the full path is type: type, subType: subType, ); @@ -552,6 +554,7 @@ class DbVersionMigrator with WalletDB { value: addr, publicKey: [], derivationIndex: -1, + derivationPath: null, // index unknown type: type, subType: subType, ); diff --git a/test/widget_tests/transaction_card_test.dart b/test/widget_tests/transaction_card_test.dart index ed5e226e1..d8cb9d390 100644 --- a/test/widget_tests/transaction_card_test.dart +++ b/test/widget_tests/transaction_card_test.dart @@ -66,6 +66,7 @@ void main() { value: "", publicKey: [], derivationIndex: 0, + derivationPath: null, type: AddressType.p2pkh, subType: AddressSubType.receiving); @@ -166,6 +167,7 @@ void main() { value: "", publicKey: [], derivationIndex: 0, + derivationPath: null, type: AddressType.p2pkh, subType: AddressSubType.receiving); @@ -263,6 +265,7 @@ void main() { value: "", publicKey: [], derivationIndex: 0, + derivationPath: null, type: AddressType.p2pkh, subType: AddressSubType.receiving); @@ -354,6 +357,7 @@ void main() { value: "", publicKey: [], derivationIndex: 0, + derivationPath: null, type: AddressType.p2pkh, subType: AddressSubType.receiving);