From f96306cb760b05b5741e065e867e3d3f743fcd90 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 19 Oct 2023 16:24:54 -0600 Subject: [PATCH] mark transactions as fusion txns and use txV2 throughout bch --- lib/db/isar/main_db.dart | 14 +++ .../sub_widgets/transaction_v2_list.dart | 18 ++- .../coins/bitcoincash/bitcoincash_wallet.dart | 106 ++++++++++-------- 3 files changed, 83 insertions(+), 55 deletions(-) diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index 61ec51545..afff7e870 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -386,6 +386,8 @@ class MainDB { // Future deleteWalletBlockchainData(String walletId) async { final transactionCount = await getTransactions(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 = @@ -404,6 +406,18 @@ class MainDB { 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(); + await isar.transactionV2s.deleteAll(txnIds); + } + // addresses for (int i = 0; i < addressCount; i += paginateLimit) { final addressIds = await getAddresses(walletId) diff --git a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart index b82cd3539..15ec84b31 100644 --- a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart +++ b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart @@ -367,7 +367,6 @@ class _TransactionCardStateV2 extends ConsumerState { late final TransactionType txType; String whatIsIt( - TransactionType type, Coin coin, int currentHeight, ) { @@ -376,7 +375,15 @@ class _TransactionCardStateV2 extends ConsumerState { coin.requiredConfirmations, ); - if (type == TransactionType.incoming) { + if (_transaction.subType == TransactionSubType.cashFusion) { + if (confirmedStatus) { + return "Anonymized"; + } else { + return "Anonymizing"; + } + } + + if (_transaction.type == TransactionType.incoming) { // if (_transaction.isMinting) { // return "Minting"; // } else @@ -385,16 +392,16 @@ class _TransactionCardStateV2 extends ConsumerState { } else { return "Receiving"; } - } else if (type == TransactionType.outgoing) { + } else if (_transaction.type == TransactionType.outgoing) { if (confirmedStatus) { return "Sent"; } else { return "Sending"; } - } else if (type == TransactionType.sentToSelf) { + } else if (_transaction.type == TransactionType.sentToSelf) { return "Sent to self"; } else { - return type.name; + return _transaction.type.name; } } @@ -506,7 +513,6 @@ class _TransactionCardStateV2 extends ConsumerState { fit: BoxFit.scaleDown, child: Text( whatIsIt( - _transaction.type, coin, currentHeight, ), diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 4c50cc306..10bf44a49 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -188,6 +188,7 @@ class BitcoinCashWallet extends CoinServiceAPI @override Future> get utxos => db.getUTXOs(walletId).findAll(); + @Deprecated("V2 soon (tm)") @override Future> get transactions => db.getTransactions(walletId).sortByTimestampDesc().findAll(); @@ -793,18 +794,20 @@ class BitcoinCashWallet extends CoinServiceAPI Future getAllTxsToWatch() async { if (_hasCalledExit) return; - List unconfirmedTxnsToNotifyPending = []; - List unconfirmedTxnsToNotifyConfirmed = []; + List unconfirmedTxnsToNotifyPending = []; + List unconfirmedTxnsToNotifyConfirmed = []; final currentChainHeight = await chainHeight; - final txCount = await db.getTransactions(walletId).count(); + final txCount = + await db.isar.transactionV2s.where().walletIdEqualTo(walletId).count(); const paginateLimit = 50; for (int i = 0; i < txCount; i += paginateLimit) { - final transactions = await db - .getTransactions(walletId) + final transactions = await db.isar.transactionV2s + .where() + .walletIdEqualTo(walletId) .offset(i) .limit(paginateLimit) .findAll(); @@ -1282,37 +1285,38 @@ class BitcoinCashWallet extends CoinServiceAPI // transactions locally in a good way @override Future updateSentCachedTxData(Map txData) async { - 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, - // precision may be lost here hence the following amountString - amount: (txData["recipientAmt"] as Amount).raw.toInt(), - amountString: (txData["recipientAmt"] as Amount).toJsonString(), - fee: txData["fee"] as int, - height: null, - isCancelled: false, - isLelantus: false, - otherData: null, - slateId: null, - nonce: null, - inputs: [], - outputs: [], - numberOfMessages: null, - ); - - final address = txData["address"] is String - ? await db.getAddress(walletId, txData["address"] as String) - : null; - - await db.addNewTransactionData( - [ - Tuple2(transaction, address), - ], - walletId, - ); + //. TODO update this to V2 properly + // final transaction = TransactionV2( + // walletId: walletId, + // txid: txData["txid"] as String, + // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + // type: isar_models.TransactionType.outgoing, + // subType: isar_models.TransactionSubType.none, + // // precision may be lost here hence the following amountString + // amount: (txData["recipientAmt"] as Amount).raw.toInt(), + // amountString: (txData["recipientAmt"] as Amount).toJsonString(), + // fee: txData["fee"] as int, + // height: null, + // isCancelled: false, + // isLelantus: false, + // otherData: null, + // slateId: null, + // nonce: null, + // inputs: [], + // outputs: [], + // numberOfMessages: null, + // ); + // + // final address = txData["address"] is String + // ? await db.getAddress(walletId, txData["address"] as String) + // : null; + // + // await db.addNewTransactionData( + // [ + // Tuple2(transaction, address), + // ], + // walletId, + // ); } bool validateCashAddr(String cashAddr) { @@ -2060,12 +2064,10 @@ class BitcoinCashWallet extends CoinServiceAPI final List txns = []; for (final txData in allTransactions) { - Set inputAddresses = {}; - Set outputAddresses = {}; - // set to true if any inputs were detected as owned by this wallet bool wasSentFromThisWallet = false; - BigInt amountSentFromThisWallet = BigInt.zero; + BigInt amountSentFromThisWallet = + BigInt.zero; // unsure if needed. Not used rn // set to true if any outputs were detected as owned by this wallet bool wasReceivedInThisWallet = false; @@ -2126,8 +2128,6 @@ class BitcoinCashWallet extends CoinServiceAPI wasSentFromThisWallet = true; amountSentFromThisWallet += input.value; } - - inputAddresses.addAll(input.addresses); } // parse outputs @@ -2141,12 +2141,6 @@ class BitcoinCashWallet extends CoinServiceAPI } for (final output in outputs) { - if (allAddressesSet - .intersection(output.addresses.toSet()) - .isNotEmpty) {} - - outputAddresses.addAll(output.addresses); - // if output was to my wallet, add value to amount received if (receivingAddresses .intersection(output.addresses.toSet()) @@ -2171,6 +2165,8 @@ class BitcoinCashWallet extends CoinServiceAPI final fee = totalIn - totalOut; isar_models.TransactionType type; + isar_models.TransactionSubType subType = + isar_models.TransactionSubType.none; // at least one input was owned by this wallet if (wasSentFromThisWallet) { @@ -2185,6 +2181,18 @@ class BitcoinCashWallet extends CoinServiceAPI // most likely just a typical send // do nothing here yet } + + // check vout 0 for special scripts + if (outputs.isNotEmpty) { + final output = outputs.first; + + // check for fusion + if (BchUtils.isFUZE(output.scriptPubKeyHex.toUint8ListFromHex)) { + subType = isar_models.TransactionSubType.cashFusion; + } else { + // check other cases here such as SLP or cash tokens etc + } + } } } else if (wasReceivedInThisWallet) { // only found outputs owned by this wallet @@ -2205,7 +2213,7 @@ class BitcoinCashWallet extends CoinServiceAPI inputs: List.unmodifiable(inputs), outputs: List.unmodifiable(outputs), type: type, - subType: isar_models.TransactionSubType.none, + subType: subType, ); txns.add(tx);