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] 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(