CW 1080: fix(cw_monero): call store() directly after commiting tx (#2312)

* fix(cw_monero): call store() directly after commiting tx to make sure that tx key is written to cache also, store it in TransactionDescription hive box * Update lib/view_model/send/send_view_model.dart --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

cyan committed Jun 16, 2025 at 16:49 UTC a96b493b60b10837903d1bc59699f8db5dd3bcd6
7 files changed +31 -15
cw_monero/lib/api/structs/pending_transaction.dart
-2
@@ -5,13 +5,11 @@ class PendingTransactionDescription {
5 required this.fee,
6 required this.hash,
7 required this.hex,
8 - required this.txKey,
8 required this.pointerAddress});
9
10 final int amount;
11 final int fee;
12 final String hash;
13 final String hex;
15 - final String txKey;
14 final int pointerAddress;
15 }
\ No newline at end of file
cw_monero/lib/api/transaction_history.dart
+8 -8
@@ -1,3 +1,4 @@
1 +import 'dart:async';
2 import 'dart:ffi';
3 import 'dart:isolate';
4
@@ -194,14 +195,12 @@ Future<PendingTransactionDescription> createTransactionSync(
195 final rFee = pendingTx.fee();
196 final rHash = pendingTx.txid('');
197 final rHex = pendingTx.hex('');
197 - final rTxKey = rHash;
198
199 return PendingTransactionDescription(
200 amount: rAmt,
201 fee: rFee,
202 hash: rHash,
203 hex: rHex,
204 - txKey: rTxKey,
204 pointerAddress: pendingTx.ffiAddress(),
205 );
206 }
@@ -246,7 +245,6 @@ Future<PendingTransactionDescription> createTransactionMultDest(
245 fee: tx.fee(),
246 hash: tx.txid(''),
247 hex: tx.hex(''),
249 - txKey: tx.txid(''),
248 pointerAddress: tx.ffiAddress(),
249 );
250 }
@@ -263,6 +261,7 @@ Future<String?> commitTransaction({required Wallet2PendingTransaction tx, requir
261 filename: '',
262 overwrite: false,
263 );
264 + return null;
265 });
266
267 String? error = (() {
@@ -285,11 +284,12 @@ Future<String?> commitTransaction({required Wallet2PendingTransaction tx, requir
284 if (error != null && error != "no tx keys found for this txid") {
285 throw CreationTransactionException(message: error);
286 }
288 - if (useUR) {
289 - return Future.value(txCommit as String?);
290 - } else {
291 - return Future.value(null);
292 - }
287 + unawaited(() async {
288 + storeSync(force: true);
289 + await Future.delayed(Duration(seconds: 5));
290 + storeSync(force: true);
291 + }());
292 + return Future.value(txCommit);
293 }
294
295 class Transaction {
cw_monero/lib/pending_monero_transaction.dart
-2
@@ -31,8 +31,6 @@ class PendingMoneroTransaction with PendingTransaction {
31 @override
32 String get hex => pendingTransactionDescription.hex;
33
34 - String get txKey => pendingTransactionDescription.txKey;
35 -
34 @override
35 String get amountFormatted => AmountConverter.amountIntToString(
36 CryptoCurrency.xmr, pendingTransactionDescription.amount);
lib/entities/transaction_description.dart
+6 -1
@@ -5,7 +5,7 @@ part 'transaction_description.g.dart';
5
6 @HiveType(typeId: TransactionDescription.typeId)
7 class TransactionDescription extends HiveObject {
8 - TransactionDescription({required this.id, this.recipientAddress, this.transactionNote});
8 + TransactionDescription({required this.id, this.recipientAddress, this.transactionNote, this.transactionKey});
9
10 static const typeId = TRANSACTION_TYPE_ID;
11 static const boxName = 'TransactionDescriptions';
@@ -20,12 +20,16 @@ class TransactionDescription extends HiveObject {
20 @HiveField(2)
21 String? transactionNote;
22
23 + @HiveField(3)
24 + String? transactionKey;
25 +
26 String get note => transactionNote ?? '';
27
28 Map<String, dynamic> toJson() => {
29 'id': id,
30 'recipientAddress': recipientAddress,
31 'transactionNote': transactionNote,
32 + 'transactionKey': transactionKey,
33 };
34
35 factory TransactionDescription.fromJson(Map<String, dynamic> json) {
@@ -33,6 +37,7 @@ class TransactionDescription extends HiveObject {
37 id: json['id'] as String,
38 recipientAddress: json['recipientAddress'] as String?,
39 transactionNote: json['transactionNote'] as String?,
40 + transactionKey: json['transactionKey'] as String?,
41 );
42 }
43 }
lib/monero/cw_monero.dart
+1 -1
@@ -365,7 +365,7 @@ class CWMonero extends Monero {
365 @override
366 Map<String, String> pendingTransactionInfo(Object transaction) {
367 final ptx = transaction as PendingMoneroTransaction;
368 - return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey};
368 + return {'id': ptx.id, 'hex': ptx.hex};
369 }
370
371 @override
lib/view_model/send/send_view_model.dart
+9
@@ -590,16 +590,25 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
590 }
591
592 if (pendingTransaction!.id.isNotEmpty) {
593 + TransactionInfo? tx;
594 + if (walletType == WalletType.monero) {
595 + await Future.delayed(Duration(milliseconds: 450));
596 + await wallet.fetchTransactions();
597 + final txhistory = monero!.getTransactionHistory(wallet);
598 + tx = txhistory.transactions.values.last;
599 + }
600 final descriptionKey = '${pendingTransaction!.id}_${wallet.walletAddresses.primaryAddress}';
601 _settingsStore.shouldSaveRecipientAddress
602 ? await transactionDescriptionBox.add(TransactionDescription(
603 id: descriptionKey,
604 recipientAddress: address,
605 transactionNote: note,
606 + transactionKey: tx?.additionalInfo["key"] as String?,
607 ))
608 : await transactionDescriptionBox.add(TransactionDescription(
609 id: descriptionKey,
610 transactionNote: note,
611 + transactionKey: tx?.additionalInfo["key"] as String?,
612 ));
613 }
614 final sharedPreferences = await SharedPreferences.getInstance();
lib/view_model/transaction_details_view_model.dart
+7 -1
@@ -233,7 +233,13 @@ abstract class TransactionDetailsViewModelBase with Store {
233 }
234
235 void _addMoneroListItems(TransactionInfo tx, DateFormat dateFormat) {
236 - final key = tx.additionalInfo['key'] as String?;
236 + final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
237 + final description = transactionDescriptionBox.values.firstWhere(
238 + (val) => val.id == descriptionKey || val.id == transactionInfo.txHash,
239 + orElse: () => TransactionDescription(id: descriptionKey));
240 +
241 +
242 + final key = tx.additionalInfo['key'] as String? ?? description.transactionKey;
243 final accountIndex = tx.additionalInfo['accountIndex'] as int;
244 final addressIndex = tx.additionalInfo['addressIndex'] as int;
245 final feeFormatted = tx.feeFormatted();