changes and fixes to reflect cs_monero changes

This commit is contained in:
julian 2024-10-28 17:49:19 -06:00 committed by julian-CStack
parent 699990883c
commit 11d1ceb40f
3 changed files with 94 additions and 42 deletions

@ -1 +1 @@
Subproject commit bc02996cd44cc338d643a06594d79ca88f7f1b62 Subproject commit bfb026b56b8995caf280a9f4e5a4941f57fbff5d

View file

@ -115,11 +115,27 @@ class TxData {
this.ignoreCachedBalanceChecks = false, this.ignoreCachedBalanceChecks = false,
}); });
Amount? get amount => recipients != null && recipients!.isNotEmpty Amount? get amount {
? recipients! if (recipients != null && recipients!.isNotEmpty) {
final sum = recipients!
.map((e) => e.amount) .map((e) => e.amount)
.reduce((total, amount) => total += amount) .reduce((total, amount) => total += amount);
: null;
// special xmr/wow check
if (pendingTransaction?.amount != null && fee != null) {
if (pendingTransaction!.amount + fee!.raw == sum.raw) {
return Amount(
rawValue: pendingTransaction!.amount,
fractionDigits: recipients!.first.amount.fractionDigits,
);
}
}
return sum;
}
return null;
}
Amount? get amountSpark => Amount? get amountSpark =>
sparkRecipients != null && sparkRecipients!.isNotEmpty sparkRecipients != null && sparkRecipients!.isNotEmpty
@ -136,10 +152,22 @@ class TxData {
fractionDigits: recipients!.first.amount.fractionDigits, fractionDigits: recipients!.first.amount.fractionDigits,
); );
} else { } else {
return recipients! final sum = recipients!
.where((e) => !e.isChange) .where((e) => !e.isChange)
.map((e) => e.amount) .map((e) => e.amount)
.reduce((total, amount) => total += amount); .reduce((total, amount) => total += amount);
// special xmr/wow check
if (pendingTransaction?.amount != null && fee != null) {
if (pendingTransaction!.amount + fee!.raw == sum.raw) {
return Amount(
rawValue: pendingTransaction!.amount,
fractionDigits: recipients!.first.amount.fractionDigits,
);
}
}
return sum;
} }
} else { } else {
return null; return null;

View file

@ -470,9 +470,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
return; return;
} }
// TODO: cs_monero: add flag to getTxs() to trigger refreshTransactions() optionally? final transactions = await base.getTxs(refresh: true);
await base.refreshTransactions();
final transactions = base.getTxs();
// final cachedTransactions = // final cachedTransactions =
// DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model') // DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
@ -512,12 +510,27 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
Address? address; Address? address;
TransactionType type; TransactionType type;
if (!tx.isSpend) { if (!tx.isSpend) {
final addressString = libMoneroWallet final String? addressString;
?.getAddress( if (tx.addressIndexes.isEmpty) {
accountIndex: tx.accountIndex, addressString = null;
addressIndex: tx.addressIndex, Logging.instance.log(
) "tx.addressIndexes.isEmpty for receive",
.value; level: LogLevel.Warning,
);
} else {
if (tx.addressIndexes.length > 1) {
Logging.instance.log(
"tx.addressIndexes contains more than one in receive",
level: LogLevel.Warning,
);
}
addressString = libMoneroWallet
?.getAddress(
accountIndex: tx.accountIndex,
addressIndex: tx.addressIndexes.first,
)
.value;
}
if (addressString != null) { if (addressString != null) {
address = await mainDB address = await mainDB
@ -539,13 +552,13 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
timestamp: (tx.timeStamp.millisecondsSinceEpoch ~/ 1000), timestamp: (tx.timeStamp.millisecondsSinceEpoch ~/ 1000),
type: type, type: type,
subType: TransactionSubType.none, subType: TransactionSubType.none,
amount: tx.amount, amount: tx.amount.toInt(),
amountString: Amount( amountString: Amount(
rawValue: BigInt.from(tx.amount), rawValue: tx.amount,
fractionDigits: cryptoCurrency.fractionDigits, fractionDigits: cryptoCurrency.fractionDigits,
).toJsonString(), ).toJsonString(),
fee: tx.fee, fee: tx.fee.toInt(),
height: tx.blockheight, height: tx.blockHeight,
isCancelled: false, isCancelled: false,
isLelantus: false, isLelantus: false,
slateId: null, slateId: null,
@ -605,8 +618,8 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
fractionDigits: cryptoCurrency.fractionDigits, fractionDigits: cryptoCurrency.fractionDigits,
); );
} else { } else {
final transactions = libMoneroWallet!.getTxs(); final transactions = await libMoneroWallet!.getTxs(refresh: true);
int transactionBalance = 0; BigInt transactionBalance = BigInt.zero;
for (final tx in transactions) { for (final tx in transactions) {
if (!tx.isSpend) { if (!tx.isSpend) {
transactionBalance += tx.amount; transactionBalance += tx.amount;
@ -616,7 +629,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
} }
return Amount( return Amount(
rawValue: BigInt.from(transactionBalance), rawValue: transactionBalance,
fractionDigits: cryptoCurrency.fractionDigits, fractionDigits: cryptoCurrency.fractionDigits,
); );
} }
@ -702,7 +715,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
final _utxosUpdateLock = Mutex(); final _utxosUpdateLock = Mutex();
Future<void> onUTXOsChanged(List<UTXO> utxos) async { Future<void> onUTXOsChanged(List<UTXO> utxos) async {
await _utxosUpdateLock.protect(() async { await _utxosUpdateLock.protect(() async {
final cwUtxos = await libMoneroWallet?.getOutputs() ?? []; final cwUtxos = await libMoneroWallet?.getOutputs(refresh: true) ?? [];
// bool changed = false; // bool changed = false;
@ -902,7 +915,8 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
@override @override
Future<bool> updateUTXOs() async { Future<bool> updateUTXOs() async {
final List<UTXO> outputArray = []; final List<UTXO> outputArray = [];
final utxos = await libMoneroWallet?.getOutputs() ?? <lib_monero.Output>[]; final utxos = await libMoneroWallet?.getOutputs(refresh: true) ??
<lib_monero.Output>[];
for (final rawUTXO in utxos) { for (final rawUTXO in utxos) {
if (!rawUTXO.spent) { if (!rawUTXO.spent) {
final current = await mainDB.isar.utxos final current = await mainDB.isar.utxos
@ -930,7 +944,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
walletId: walletId, walletId: walletId,
txid: rawUTXO.hash, txid: rawUTXO.hash,
vout: rawUTXO.vout, vout: rawUTXO.vout,
value: rawUTXO.value, value: rawUTXO.value.toInt(),
name: current?.name ?? "", name: current?.name ?? "",
isBlocked: current?.isBlocked ?? rawUTXO.isFrozen, isBlocked: current?.isBlocked ?? rawUTXO.isFrozen,
blockedReason: current?.blockedReason ?? "", blockedReason: current?.blockedReason ?? "",
@ -1045,11 +1059,13 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
try { try {
int highestIndex = -1; int highestIndex = -1;
final entries = libMoneroWallet?.getTxs(); final entries = await libMoneroWallet?.getTxs(refresh: true);
if (entries != null) { if (entries != null) {
for (final element in entries) { for (final element in entries) {
if (!element.isSpend) { if (!element.isSpend) {
final int curAddressIndex = element.addressIndex; final int curAddressIndex = element.addressIndexes.isEmpty
? 0
: element.addressIndexes.reduce(max);
if (curAddressIndex > highestIndex) { if (curAddressIndex > highestIndex) {
highestIndex = curAddressIndex; highestIndex = curAddressIndex;
} }
@ -1150,17 +1166,21 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
} }
try { try {
// TODO: ??? final bool sweep;
// check for send all
bool isSendAll = false;
final balance = await availableBalance; if (txData.utxos == null) {
if (txData.amount! == balance && final balance = await availableBalance;
txData.recipients!.first.amount == balance) { sweep = txData.amount! == balance;
isSendAll = true; } else {
final totalInputsValue = txData.utxos!
.map((e) => e.value)
.fold(BigInt.zero, (p, e) => p + BigInt.from(e));
sweep = txData.amount!.raw == totalInputsValue;
} }
if (isSendAll && txData.recipients!.length > 1) { // TODO: test this one day
// cs_monero may not support this yet properly
if (sweep && txData.recipients!.length > 1) {
throw Exception("Send all not supported with multiple recipients"); throw Exception("Send all not supported with multiple recipients");
} }
@ -1168,7 +1188,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
for (final recipient in txData.recipients!) { for (final recipient in txData.recipients!) {
final output = lib_monero.Recipient( final output = lib_monero.Recipient(
address: recipient.address, address: recipient.address,
amount: recipient.amount.decimal.toString(), amount: recipient.amount.raw,
); );
outputs.add(output); outputs.add(output);
@ -1185,7 +1205,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
address: e.address!, address: e.address!,
hash: e.txid, hash: e.txid,
keyImage: e.keyImage!, keyImage: e.keyImage!,
value: e.value, value: BigInt.from(e.value),
isFrozen: e.isBlocked, isFrozen: e.isBlocked,
isUnlocked: e.blockHeight != null && isUnlocked: e.blockHeight != null &&
(height - (e.blockHeight ?? 0)) >= (height - (e.blockHeight ?? 0)) >=
@ -1193,6 +1213,7 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
height: e.blockHeight ?? 0, height: e.blockHeight ?? 0,
vout: e.vout, vout: e.vout,
spent: e.used ?? false, spent: e.used ?? false,
spentHeight: null, // doesn't matter here
coinbase: e.isCoinbase, coinbase: e.isCoinbase,
), ),
) )
@ -1202,23 +1223,26 @@ abstract class LibMoneroWallet<T extends CryptonoteCurrency>
final lib_monero.PendingTransaction pendingTransaction; final lib_monero.PendingTransaction pendingTransaction;
if (outputs.length == 1) { if (outputs.length == 1) {
pendingTransaction = await libMoneroWallet!.createTx( pendingTransaction = await libMoneroWallet!.createTx(
address: outputs.first.address, output: outputs.first,
paymentId: "", paymentId: "",
amount: isSendAll ? null : outputs.first.amount, sweep: sweep,
priority: feePriority, priority: feePriority,
preferredInputs: inputs?.map((e) => e.keyImage).toList() ?? [], preferredInputs: inputs,
accountIndex: 0, // sw only uses account 0 at this time
); );
} else { } else {
pendingTransaction = await libMoneroWallet!.createTxMultiDest( pendingTransaction = await libMoneroWallet!.createTxMultiDest(
outputs: outputs, outputs: outputs,
paymentId: "", paymentId: "",
priority: feePriority, priority: feePriority,
preferredInputs: inputs?.map((e) => e.keyImage).toList() ?? [], preferredInputs: inputs,
sweep: sweep,
accountIndex: 0, // sw only uses account 0 at this time
); );
} }
final realFee = Amount( final realFee = Amount(
rawValue: BigInt.from(pendingTransaction.fee!), rawValue: pendingTransaction.fee,
fractionDigits: cryptoCurrency.fractionDigits, fractionDigits: cryptoCurrency.fractionDigits,
); );