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>
This commit is contained in:
cyan 2025-06-16 16:49:43 +02:00 committed by GitHub
parent fe0c9ecc0e
commit a96b493b60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 31 additions and 15 deletions

View file

@ -5,13 +5,11 @@ class PendingTransactionDescription {
required this.fee, required this.fee,
required this.hash, required this.hash,
required this.hex, required this.hex,
required this.txKey,
required this.pointerAddress}); required this.pointerAddress});
final int amount; final int amount;
final int fee; final int fee;
final String hash; final String hash;
final String hex; final String hex;
final String txKey;
final int pointerAddress; final int pointerAddress;
} }

View file

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:ffi'; import 'dart:ffi';
import 'dart:isolate'; import 'dart:isolate';
@ -194,14 +195,12 @@ Future<PendingTransactionDescription> createTransactionSync(
final rFee = pendingTx.fee(); final rFee = pendingTx.fee();
final rHash = pendingTx.txid(''); final rHash = pendingTx.txid('');
final rHex = pendingTx.hex(''); final rHex = pendingTx.hex('');
final rTxKey = rHash;
return PendingTransactionDescription( return PendingTransactionDescription(
amount: rAmt, amount: rAmt,
fee: rFee, fee: rFee,
hash: rHash, hash: rHash,
hex: rHex, hex: rHex,
txKey: rTxKey,
pointerAddress: pendingTx.ffiAddress(), pointerAddress: pendingTx.ffiAddress(),
); );
} }
@ -246,7 +245,6 @@ Future<PendingTransactionDescription> createTransactionMultDest(
fee: tx.fee(), fee: tx.fee(),
hash: tx.txid(''), hash: tx.txid(''),
hex: tx.hex(''), hex: tx.hex(''),
txKey: tx.txid(''),
pointerAddress: tx.ffiAddress(), pointerAddress: tx.ffiAddress(),
); );
} }
@ -263,6 +261,7 @@ Future<String?> commitTransaction({required Wallet2PendingTransaction tx, requir
filename: '', filename: '',
overwrite: false, overwrite: false,
); );
return null;
}); });
String? error = (() { String? error = (() {
@ -285,11 +284,12 @@ Future<String?> commitTransaction({required Wallet2PendingTransaction tx, requir
if (error != null && error != "no tx keys found for this txid") { if (error != null && error != "no tx keys found for this txid") {
throw CreationTransactionException(message: error); throw CreationTransactionException(message: error);
} }
if (useUR) { unawaited(() async {
return Future.value(txCommit as String?); storeSync(force: true);
} else { await Future.delayed(Duration(seconds: 5));
return Future.value(null); storeSync(force: true);
} }());
return Future.value(txCommit);
} }
class Transaction { class Transaction {

View file

@ -31,8 +31,6 @@ class PendingMoneroTransaction with PendingTransaction {
@override @override
String get hex => pendingTransactionDescription.hex; String get hex => pendingTransactionDescription.hex;
String get txKey => pendingTransactionDescription.txKey;
@override @override
String get amountFormatted => AmountConverter.amountIntToString( String get amountFormatted => AmountConverter.amountIntToString(
CryptoCurrency.xmr, pendingTransactionDescription.amount); CryptoCurrency.xmr, pendingTransactionDescription.amount);

View file

@ -5,7 +5,7 @@ part 'transaction_description.g.dart';
@HiveType(typeId: TransactionDescription.typeId) @HiveType(typeId: TransactionDescription.typeId)
class TransactionDescription extends HiveObject { class TransactionDescription extends HiveObject {
TransactionDescription({required this.id, this.recipientAddress, this.transactionNote}); TransactionDescription({required this.id, this.recipientAddress, this.transactionNote, this.transactionKey});
static const typeId = TRANSACTION_TYPE_ID; static const typeId = TRANSACTION_TYPE_ID;
static const boxName = 'TransactionDescriptions'; static const boxName = 'TransactionDescriptions';
@ -20,12 +20,16 @@ class TransactionDescription extends HiveObject {
@HiveField(2) @HiveField(2)
String? transactionNote; String? transactionNote;
@HiveField(3)
String? transactionKey;
String get note => transactionNote ?? ''; String get note => transactionNote ?? '';
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
'id': id, 'id': id,
'recipientAddress': recipientAddress, 'recipientAddress': recipientAddress,
'transactionNote': transactionNote, 'transactionNote': transactionNote,
'transactionKey': transactionKey,
}; };
factory TransactionDescription.fromJson(Map<String, dynamic> json) { factory TransactionDescription.fromJson(Map<String, dynamic> json) {
@ -33,6 +37,7 @@ class TransactionDescription extends HiveObject {
id: json['id'] as String, id: json['id'] as String,
recipientAddress: json['recipientAddress'] as String?, recipientAddress: json['recipientAddress'] as String?,
transactionNote: json['transactionNote'] as String?, transactionNote: json['transactionNote'] as String?,
transactionKey: json['transactionKey'] as String?,
); );
} }
} }

View file

@ -365,7 +365,7 @@ class CWMonero extends Monero {
@override @override
Map<String, String> pendingTransactionInfo(Object transaction) { Map<String, String> pendingTransactionInfo(Object transaction) {
final ptx = transaction as PendingMoneroTransaction; final ptx = transaction as PendingMoneroTransaction;
return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey}; return {'id': ptx.id, 'hex': ptx.hex};
} }
@override @override

View file

@ -590,16 +590,25 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
} }
if (pendingTransaction!.id.isNotEmpty) { if (pendingTransaction!.id.isNotEmpty) {
TransactionInfo? tx;
if (walletType == WalletType.monero) {
await Future.delayed(Duration(milliseconds: 450));
await wallet.fetchTransactions();
final txhistory = monero!.getTransactionHistory(wallet);
tx = txhistory.transactions.values.last;
}
final descriptionKey = '${pendingTransaction!.id}_${wallet.walletAddresses.primaryAddress}'; final descriptionKey = '${pendingTransaction!.id}_${wallet.walletAddresses.primaryAddress}';
_settingsStore.shouldSaveRecipientAddress _settingsStore.shouldSaveRecipientAddress
? await transactionDescriptionBox.add(TransactionDescription( ? await transactionDescriptionBox.add(TransactionDescription(
id: descriptionKey, id: descriptionKey,
recipientAddress: address, recipientAddress: address,
transactionNote: note, transactionNote: note,
transactionKey: tx?.additionalInfo["key"] as String?,
)) ))
: await transactionDescriptionBox.add(TransactionDescription( : await transactionDescriptionBox.add(TransactionDescription(
id: descriptionKey, id: descriptionKey,
transactionNote: note, transactionNote: note,
transactionKey: tx?.additionalInfo["key"] as String?,
)); ));
} }
final sharedPreferences = await SharedPreferences.getInstance(); final sharedPreferences = await SharedPreferences.getInstance();

View file

@ -233,7 +233,13 @@ abstract class TransactionDetailsViewModelBase with Store {
} }
void _addMoneroListItems(TransactionInfo tx, DateFormat dateFormat) { void _addMoneroListItems(TransactionInfo tx, DateFormat dateFormat) {
final key = tx.additionalInfo['key'] as String?; final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
final description = transactionDescriptionBox.values.firstWhere(
(val) => val.id == descriptionKey || val.id == transactionInfo.txHash,
orElse: () => TransactionDescription(id: descriptionKey));
final key = tx.additionalInfo['key'] as String? ?? description.transactionKey;
final accountIndex = tx.additionalInfo['accountIndex'] as int; final accountIndex = tx.additionalInfo['accountIndex'] as int;
final addressIndex = tx.additionalInfo['addressIndex'] as int; final addressIndex = tx.additionalInfo['addressIndex'] as int;
final feeFormatted = tx.feeFormatted(); final feeFormatted = tx.feeFormatted();