From 772ec1e95b3d9ed1d6cce0ff8aad950c75ceefd3 Mon Sep 17 00:00:00 2001 From: julian Date: Sun, 19 Oct 2025 08:54:02 -0600 Subject: [PATCH 1/2] clean up unseen address error --- lib/wallets/wallet/impl/cardano_wallet.dart | 57 ++++++++++++++++----- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/lib/wallets/wallet/impl/cardano_wallet.dart b/lib/wallets/wallet/impl/cardano_wallet.dart index 1583123a2..46544139e 100644 --- a/lib/wallets/wallet/impl/cardano_wallet.dart +++ b/lib/wallets/wallet/impl/cardano_wallet.dart @@ -8,6 +8,7 @@ import 'package:blockchain_utils/bip/cardano/mnemonic/cardano_icarus_seed_genera import 'package:blockchain_utils/bip/cardano/shelley/cardano_shelley.dart'; import 'package:isar_community/isar.dart'; import 'package:on_chain/ada/ada.dart'; +import 'package:on_chain/ada/src/provider/exception/blockfrost_api_error.dart'; import 'package:socks5_proxy/socks.dart'; import 'package:tuple/tuple.dart'; @@ -418,19 +419,45 @@ class CardanoWallet extends Bip39Wallet { }); } + Future _checkAddressIsFound() async { + try { + await blockfrostProvider!.request( + BlockfrostRequestSpecificAddress( + ADAAddress.fromAddress((await getCurrentReceivingAddress())!.value), + ), + ); + return true; + } on BlockfrostError catch (e, s) { + if (e.statusCode == 404 && e.error == "Not found") { + Logging.instance.i( + "Ada address not seen on network yet", + error: e, + stackTrace: s, + ); + return false; + } else { + rethrow; + } + } + } + @override Future updateBalance() async { try { await updateProvider(); - final addressUtxos = await blockfrostProvider!.request( - BlockfrostRequestAddressUTXOsOfAGivenAsset( - address: ADAAddress.fromAddress( - (await getCurrentReceivingAddress())!.value, - ), - asset: "lovelace", - ), - ); + final addressExists = await _checkAddressIsFound(); + + final addressUtxos = addressExists + ? await blockfrostProvider!.request( + BlockfrostRequestAddressUTXOsOfAGivenAsset( + address: ADAAddress.fromAddress( + (await getCurrentReceivingAddress())!.value, + ), + asset: "lovelace", + ), + ) + : []; BigInt totalBalanceInLovelace = BigInt.parse("0"); for (final utxo in addressUtxos) { @@ -498,13 +525,17 @@ class CardanoWallet extends Bip39Wallet { try { await updateProvider(); + final addressExists = await _checkAddressIsFound(); + final currentAddr = (await getCurrentReceivingAddress())!.value; - final txsList = await blockfrostProvider!.request( - BlockfrostRequestAddressTransactions( - ADAAddress.fromAddress(currentAddr), - ), - ); + final txsList = addressExists + ? await blockfrostProvider!.request( + BlockfrostRequestAddressTransactions( + ADAAddress.fromAddress(currentAddr), + ), + ) + : []; final parsedTxsList = List>.empty( growable: true, From cbb3fc3d1c8dba589c07b45cdbfa0a144cc22f8a Mon Sep 17 00:00:00 2001 From: julian Date: Sun, 19 Oct 2025 09:00:11 -0600 Subject: [PATCH 2/2] optimize some db calls to prevent creating a write transaction if no data will be written --- lib/db/isar/main_db.dart | 96 ++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index d951a1a6b..94f27e1f8 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -92,11 +92,10 @@ class MainDB { Future updateWalletInfo(WalletInfo walletInfo) async { try { await isar.writeTxn(() async { - final info = - await isar.walletInfo - .where() - .walletIdEqualTo(walletInfo.walletId) - .findFirst(); + final info = await isar.walletInfo + .where() + .walletIdEqualTo(walletInfo.walletId) + .findFirst(); if (info == null) { throw Exception( "updateWalletInfo() called with new WalletInfo." @@ -189,6 +188,7 @@ class MainDB { } Future> putAddresses(List
addresses) async { + if (addresses.isEmpty) return []; try { return await isar.writeTxn(() async { return await isar.addresses.putAll(addresses); @@ -199,6 +199,7 @@ class MainDB { } Future> updateOrPutAddresses(List
addresses) async { + if (addresses.isEmpty) return []; try { final List ids = []; await isar.writeTxn(() async { @@ -269,6 +270,7 @@ class MainDB { } Future> putTransactions(List transactions) async { + if (transactions.isEmpty) return []; try { return await isar.writeTxn(() async { return await isar.transactions.putAll(transactions); @@ -306,9 +308,11 @@ class MainDB { await isar.utxos.put(utxo); }); - Future putUTXOs(List utxos) => isar.writeTxn(() async { - await isar.utxos.putAll(utxos); - }); + Future putUTXOs(List utxos) => utxos.isEmpty + ? Future.value() + : isar.writeTxn(() async { + await isar.utxos.putAll(utxos); + }); Future updateUTXOs(String walletId, List utxos) async { bool newUTXO = false; @@ -317,11 +321,10 @@ class MainDB { final set = utxos.toSet(); for (final utxo in utxos) { // check if utxo exists in db and update accordingly - final storedUtxo = - await isar.utxos - .where() - .txidWalletIdVoutEqualTo(utxo.txid, utxo.walletId, utxo.vout) - .findFirst(); + final storedUtxo = await isar.utxos + .where() + .txidWalletIdVoutEqualTo(utxo.txid, utxo.walletId, utxo.vout) + .findFirst(); if (storedUtxo != null) { // update @@ -441,8 +444,10 @@ class MainDB { // Future deleteWalletBlockchainData(String walletId) async { final transactionCount = await getTransactions(walletId).count(); - final transactionCountV2 = - await isar.transactionV2s.where().walletIdEqualTo(walletId).count(); + final transactionCountV2 = await isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .count(); final addressCount = await getAddresses(walletId).count(); final utxoCount = await getUTXOs(walletId).count(); // final lelantusCoinCount = @@ -453,41 +458,37 @@ class MainDB { // transactions for (int i = 0; i < transactionCount; i += paginateLimit) { - final txnIds = - await getTransactions( - walletId, - ).offset(i).limit(paginateLimit).idProperty().findAll(); + final txnIds = await getTransactions( + walletId, + ).offset(i).limit(paginateLimit).idProperty().findAll(); await isar.transactions.deleteAll(txnIds); } // transactions V2 for (int i = 0; i < transactionCountV2; i += paginateLimit) { - final txnIds = - await isar.transactionV2s - .where() - .walletIdEqualTo(walletId) - .offset(i) - .limit(paginateLimit) - .idProperty() - .findAll(); + final txnIds = await isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .offset(i) + .limit(paginateLimit) + .idProperty() + .findAll(); await isar.transactionV2s.deleteAll(txnIds); } // addresses for (int i = 0; i < addressCount; i += paginateLimit) { - final addressIds = - await getAddresses( - walletId, - ).offset(i).limit(paginateLimit).idProperty().findAll(); + final addressIds = await getAddresses( + walletId, + ).offset(i).limit(paginateLimit).idProperty().findAll(); await isar.addresses.deleteAll(addressIds); } // utxos for (int i = 0; i < utxoCount; i += paginateLimit) { - final utxoIds = - await getUTXOs( - walletId, - ).offset(i).limit(paginateLimit).idProperty().findAll(); + final utxoIds = await getUTXOs( + walletId, + ).offset(i).limit(paginateLimit).idProperty().findAll(); await isar.utxos.deleteAll(utxoIds); } @@ -504,10 +505,9 @@ class MainDB { await isar.writeTxn(() async { const paginateLimit = 50; for (int i = 0; i < addressLabelCount; i += paginateLimit) { - final labelIds = - await getAddressLabels( - walletId, - ).offset(i).limit(paginateLimit).idProperty().findAll(); + final labelIds = await getAddressLabels( + walletId, + ).offset(i).limit(paginateLimit).idProperty().findAll(); await isar.addressLabels.deleteAll(labelIds); } }); @@ -518,10 +518,9 @@ class MainDB { await isar.writeTxn(() async { const paginateLimit = 50; for (int i = 0; i < noteCount; i += paginateLimit) { - final labelIds = - await getTransactionNotes( - walletId, - ).offset(i).limit(paginateLimit).idProperty().findAll(); + final labelIds = await getTransactionNotes( + walletId, + ).offset(i).limit(paginateLimit).idProperty().findAll(); await isar.transactionNotes.deleteAll(labelIds); } }); @@ -531,6 +530,7 @@ class MainDB { List> transactionsData, String walletId, ) async { + if (transactionsData.isEmpty) return; try { await isar.writeTxn(() async { for (final data in transactionsData) { @@ -570,15 +570,15 @@ class MainDB { Future> updateOrPutTransactionV2s( List transactions, ) async { + if (transactions.isEmpty) return []; try { final List ids = []; await isar.writeTxn(() async { for (final tx in transactions) { - final storedTx = - await isar.transactionV2s - .where() - .txidWalletIdEqualTo(tx.txid, tx.walletId) - .findFirst(); + final storedTx = await isar.transactionV2s + .where() + .txidWalletIdEqualTo(tx.txid, tx.walletId) + .findFirst(); Id id; if (storedTx == null) {