diff --git a/cw_decred/lib/transaction_history.dart b/cw_decred/lib/transaction_history.dart index d2abafbf4..37993e532 100644 --- a/cw_decred/lib/transaction_history.dart +++ b/cw_decred/lib/transaction_history.dart @@ -2,7 +2,6 @@ import 'package:mobx/mobx.dart'; import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_history.dart'; -// NOTE: Methods currently not used. class DecredTransactionHistory extends TransactionHistoryBase<TransactionInfo> { DecredTransactionHistory() { transactions = ObservableMap<String, TransactionInfo>(); @@ -23,6 +22,17 @@ class DecredTransactionHistory extends TransactionHistoryBase<TransactionInfo> { Future<void> changePassword(String password) async {} - void _update(TransactionInfo transaction) => - transactions[transaction.id] = transaction; + // update returns true if a known transaction that is not pending was found. + bool update(Map<String, TransactionInfo> txs) { + var foundOldTx = false; + txs.forEach((_, tx) { + if (!this.transactions.containsKey(tx.id) || + this.transactions[tx.id]!.isPending) { + this.transactions[tx.id] = tx; + } else { + foundOldTx = true; + } + }); + return foundOldTx; + } } diff --git a/cw_decred/lib/wallet.dart b/cw_decred/lib/wallet.dart index 7aec45cfb..d633954d4 100644 --- a/cw_decred/lib/wallet.dart +++ b/cw_decred/lib/wallet.dart @@ -51,6 +51,8 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance, final String _password; final idPrefix = "decred_"; bool connecting = false; + int bestHeight = 0; + String bestHash = ""; String persistantPeer = ""; FeeCache feeRateFast = FeeCache(defaultFeeRate); FeeCache feeRateMedium = FeeCache(defaultFeeRate); @@ -84,11 +86,32 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance, updateBalance(); } - void performBackgroundTasks() { + void performBackgroundTasks() async { if (!checkSync()) { return; } + final res = libdcrwallet.bestBlock(walletInfo.name); + final decoded = json.decode(res); + final hash = decoded["hash"] ?? ""; + if (this.bestHash != hash) { + this.bestHash = hash; + this.bestHeight = decoded["height"] ?? ""; + } updateBalance(); + var from = 0; + while (true) { + // Transactions are returned from newest to oldest. Loop fetching 5 txn + // at a time until we find a batch with txn that no longer need to be + // updated. + final txs = await this.fetchFiveTransactions(from); + if (txs.length == 0) { + return; + } + if (this.transactionHistory.update(txs)) { + return; + } + from += 5; + } } bool checkSync() { @@ -335,21 +358,42 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance, @override Future<Map<String, DecredTransactionInfo>> fetchTransactions() async { - // TODO: Read from libdcrwallet. - final txInfo = DecredTransactionInfo( - id: "3cbf3eb9523fd04e96dbaf98cdbd21779222cc8855ece8700494662ae7578e02", - amount: 1234567, - fee: 123, - direction: TransactionDirection.outgoing, - isPending: true, - date: DateTime.now(), - height: 0, - confirmations: 0, - to: "DsT4qJPPaYEuQRimfgvSKxKH3paysn1x3Nt", - ); - return { - "3cbf3eb9523fd04e96dbaf98cdbd21779222cc8855ece8700494662ae7578e02": txInfo - }; + return this.fetchFiveTransactions(0); + } + + @override + Future<Map<String, DecredTransactionInfo>> fetchFiveTransactions( + int from) async { + final res = + libdcrwallet.listTransactions(walletInfo.name, from.toString(), "5"); + final decoded = json.decode(res); + var txs = <String, DecredTransactionInfo>{}; + for (final d in decoded) { + final txid = d["txid"] ?? ""; + var direction = TransactionDirection.outgoing; + if (d["category"] == "receive") { + direction = TransactionDirection.incoming; + } + final amountDouble = d["amount"] ?? 0.0; + final amount = (amountDouble * 1e8).toInt().abs(); + final feeDouble = d["fee"] ?? 0.0; + final fee = (feeDouble * 1e8).toInt().abs(); + final confs = d["confirmations"] ?? 0; + final sendTime = d["time"] ?? 0; + final txInfo = DecredTransactionInfo( + id: txid, + amount: amount, + fee: fee, + direction: direction, + isPending: confs == 0, + date: DateTime.fromMillisecondsSinceEpoch(sendTime * 1000, isUtc: true), + height: 0, + confirmations: confs, + to: d["address"] ?? "", + ); + txs[txid] = txInfo; + } + return txs; } @override