clean up linter warnings and disable auto minting

This commit is contained in:
julian 2022-09-06 09:34:39 -06:00
parent 2fb96f4a96
commit d2fbb7a4ba
2 changed files with 234 additions and 232 deletions

View file

@ -186,7 +186,7 @@ Future<void> executeNative(Map<String, dynamic> arguments) async {
level: LogLevel.Error); level: LogLevel.Error);
sendPort.send("Error"); sendPort.send("Error");
} finally { } finally {
Logging.instance.isar?.close(); await Logging.instance.isar?.close();
} }
} }
@ -375,7 +375,7 @@ Future<Map<String, dynamic>> isolateRestore(
// Edit the receive transactions with the mint fees. // Edit the receive transactions with the mint fees.
Map<String, models.Transaction> editedTransactions = Map<String, models.Transaction> editedTransactions =
<String, models.Transaction>{}; <String, models.Transaction>{};
lelantusCoins.forEach((item) { for (var item in lelantusCoins) {
item.forEach((key, value) { item.forEach((key, value) {
String txid = value.txId; String txid = value.txId;
var tx = data.findTransaction(txid); var tx = data.findTransaction(txid);
@ -420,7 +420,7 @@ Future<Map<String, dynamic>> isolateRestore(
); );
} }
}); });
}); }
// Logging.instance.log(editedTransactions, addToDebugMessagesDB: false); // Logging.instance.log(editedTransactions, addToDebugMessagesDB: false);
Map<String, models.Transaction> transactionMap = data.getAllTransactions(); Map<String, models.Transaction> transactionMap = data.getAllTransactions();
@ -1156,7 +1156,7 @@ class FiroWallet extends CoinServiceAPI {
); );
if (shouldRefresh) { if (shouldRefresh) {
refresh(); unawaited(refresh());
} }
} }
@ -1333,32 +1333,36 @@ class FiroWallet extends CoinServiceAPI {
for (final tx in unconfirmedTxnsToNotifyPending) { for (final tx in unconfirmedTxnsToNotifyPending) {
switch (tx.txType) { switch (tx.txType) {
case "Received": case "Received":
NotificationApi.showNotification( unawaited(
title: "Incoming transaction", NotificationApi.showNotification(
body: walletName, title: "Incoming transaction",
walletId: walletId, body: walletName,
iconAssetName: Assets.svg.iconFor(coin: coin), walletId: walletId,
date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000), iconAssetName: Assets.svg.iconFor(coin: coin),
shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS, date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
coinName: coin.name, shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS,
txid: tx.txid, coinName: coin.name,
confirmations: tx.confirmations, txid: tx.txid,
requiredConfirmations: MINIMUM_CONFIRMATIONS, confirmations: tx.confirmations,
requiredConfirmations: MINIMUM_CONFIRMATIONS,
),
); );
await txTracker.addNotifiedPending(tx.txid); await txTracker.addNotifiedPending(tx.txid);
break; break;
case "Sent": case "Sent":
NotificationApi.showNotification( unawaited(
title: "Outgoing transaction", NotificationApi.showNotification(
body: walletName, title: "Outgoing transaction",
walletId: walletId, body: walletName,
iconAssetName: Assets.svg.iconFor(coin: coin), walletId: walletId,
date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000), iconAssetName: Assets.svg.iconFor(coin: coin),
shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS, date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
coinName: coin.name, shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS,
txid: tx.txid, coinName: coin.name,
confirmations: tx.confirmations, txid: tx.txid,
requiredConfirmations: MINIMUM_CONFIRMATIONS, confirmations: tx.confirmations,
requiredConfirmations: MINIMUM_CONFIRMATIONS,
),
); );
await txTracker.addNotifiedPending(tx.txid); await txTracker.addNotifiedPending(tx.txid);
break; break;
@ -1369,25 +1373,29 @@ class FiroWallet extends CoinServiceAPI {
for (final tx in unconfirmedTxnsToNotifyConfirmed) { for (final tx in unconfirmedTxnsToNotifyConfirmed) {
if (tx.txType == "Received") { if (tx.txType == "Received") {
NotificationApi.showNotification( unawaited(
title: "Incoming transaction confirmed", NotificationApi.showNotification(
body: walletName, title: "Incoming transaction confirmed",
walletId: walletId, body: walletName,
iconAssetName: Assets.svg.iconFor(coin: coin), walletId: walletId,
date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000), iconAssetName: Assets.svg.iconFor(coin: coin),
shouldWatchForUpdates: false, date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
coinName: coin.name, shouldWatchForUpdates: false,
coinName: coin.name,
),
); );
await txTracker.addNotifiedConfirmed(tx.txid); await txTracker.addNotifiedConfirmed(tx.txid);
} else if (tx.txType == "Sent" && tx.subType == "join") { } else if (tx.txType == "Sent" && tx.subType == "join") {
NotificationApi.showNotification( unawaited(
title: "Outgoing transaction confirmed", NotificationApi.showNotification(
body: walletName, title: "Outgoing transaction confirmed",
walletId: walletId, body: walletName,
iconAssetName: Assets.svg.iconFor(coin: coin), walletId: walletId,
date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000), iconAssetName: Assets.svg.iconFor(coin: coin),
shouldWatchForUpdates: false, date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
coinName: coin.name, shouldWatchForUpdates: false,
coinName: coin.name,
),
); );
await txTracker.addNotifiedConfirmed(tx.txid); await txTracker.addNotifiedConfirmed(tx.txid);
} }
@ -1520,14 +1528,14 @@ class FiroWallet extends CoinServiceAPI {
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.60, walletId)); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.60, walletId));
final lelantusCoins = getLelantusCoinMap(); final lelantusCoins = getLelantusCoinMap();
Logging.instance.log("_lelantus_coins at refresh: ${lelantusCoins}", Logging.instance.log("_lelantus_coins at refresh: $lelantusCoins",
level: LogLevel.Warning, printFullLength: true); level: LogLevel.Warning, printFullLength: true);
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.70, walletId)); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.70, walletId));
await _refreshLelantusData(); await _refreshLelantusData();
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.80, walletId)); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.80, walletId));
await autoMint(); // await autoMint();
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.90, walletId)); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.90, walletId));
var balance = await _getFullBalance(); var balance = await _getFullBalance();
@ -1590,7 +1598,7 @@ class FiroWallet extends CoinServiceAPI {
final balance = await availableBalance; final balance = await availableBalance;
int spendAmount = int spendAmount =
(balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt(); (balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt();
int fee = await EstimateJoinSplitFee(spendAmount); int fee = await estimateJoinSplitFee(spendAmount);
return fee; return fee;
} }
@ -1643,7 +1651,7 @@ class FiroWallet extends CoinServiceAPI {
Future<List<LelantusCoin>> _getUnspentCoins() async { Future<List<LelantusCoin>> _getUnspentCoins() async {
final List<Map<dynamic, LelantusCoin>> lelantusCoins = getLelantusCoinMap(); final List<Map<dynamic, LelantusCoin>> lelantusCoins = getLelantusCoinMap();
if (lelantusCoins != null && lelantusCoins.isNotEmpty) { if (lelantusCoins.isNotEmpty) {
lelantusCoins.removeWhere((element) => lelantusCoins.removeWhere((element) =>
element.values.any((elementCoin) => elementCoin.value == 0)); element.values.any((elementCoin) => elementCoin.value == 0));
} }
@ -1652,9 +1660,6 @@ class FiroWallet extends CoinServiceAPI {
final data = await _txnData; final data = await _txnData;
final lelantusData = await lelantusTransactionData; final lelantusData = await lelantusTransactionData;
List<LelantusCoin> coins = []; List<LelantusCoin> coins = [];
if (lelantusCoins == null) {
return coins;
}
List<LelantusCoin> lelantusCoinsList = List<LelantusCoin> lelantusCoinsList =
lelantusCoins.fold(<LelantusCoin>[], (previousValue, element) { lelantusCoins.fold(<LelantusCoin>[], (previousValue, element) {
@ -1699,7 +1704,7 @@ class FiroWallet extends CoinServiceAPI {
try { try {
final List<Map<dynamic, LelantusCoin>> lelantusCoins = final List<Map<dynamic, LelantusCoin>> lelantusCoins =
getLelantusCoinMap(); getLelantusCoinMap();
if (lelantusCoins != null && lelantusCoins.isNotEmpty) { if (lelantusCoins.isNotEmpty) {
lelantusCoins.removeWhere((element) => lelantusCoins.removeWhere((element) =>
element.values.any((elementCoin) => elementCoin.value == 0)); element.values.any((elementCoin) => elementCoin.value == 0));
} }
@ -1711,32 +1716,32 @@ class FiroWallet extends CoinServiceAPI {
DB.instance.get<dynamic>(boxName: walletId, key: 'jindex') as List?; DB.instance.get<dynamic>(boxName: walletId, key: 'jindex') as List?;
int intLelantusBalance = 0; int intLelantusBalance = 0;
int unconfirmedLelantusBalance = 0; int unconfirmedLelantusBalance = 0;
if (lelantusCoins != null) {
lelantusCoins.forEach((element) { for (var element in lelantusCoins) {
element.forEach((key, value) { element.forEach((key, value) {
final tx = data.findTransaction(value.txId); final tx = data.findTransaction(value.txId);
models.Transaction? ltx; models.Transaction? ltx;
ltx = lData.findTransaction(value.txId); ltx = lData.findTransaction(value.txId);
// Logging.instance.log("$value $tx $ltx"); // Logging.instance.log("$value $tx $ltx");
if (!jindexes!.contains(value.index) && tx == null) { if (!jindexes!.contains(value.index) && tx == null) {
// This coin is not confirmed and may be replaced // This coin is not confirmed and may be replaced
} else if (jindexes.contains(value.index) && } else if (jindexes.contains(value.index) &&
tx == null && tx == null &&
!value.isUsed && !value.isUsed &&
ltx != null && ltx != null &&
!ltx.confirmedStatus) { !ltx.confirmedStatus) {
unconfirmedLelantusBalance += value.value; unconfirmedLelantusBalance += value.value;
} else if (jindexes.contains(value.index) && !value.isUsed) { } else if (jindexes.contains(value.index) && !value.isUsed) {
intLelantusBalance += value.value; intLelantusBalance += value.value;
} else if (!value.isUsed && } else if (!value.isUsed &&
(tx == null ? true : tx.confirmedStatus != false)) { (tx == null ? true : tx.confirmedStatus != false)) {
intLelantusBalance += value.value; intLelantusBalance += value.value;
} else if (tx != null && tx.confirmedStatus == false) { } else if (tx != null && tx.confirmedStatus == false) {
unconfirmedLelantusBalance += value.value; unconfirmedLelantusBalance += value.value;
} }
});
}); });
} }
final int utxosIntValue = utxos.satoshiBalance; final int utxosIntValue = utxos.satoshiBalance;
final Decimal utxosValue = Format.satoshisToAmount(utxosIntValue); final Decimal utxosValue = Format.satoshisToAmount(utxosIntValue);
@ -1769,125 +1774,125 @@ class FiroWallet extends CoinServiceAPI {
} }
} }
Future<void> autoMint() async { // Future<void> autoMint() async {
try { // try {
var mintResult = await _mintSelection(); // var mintResult = await _mintSelection();
if (mintResult.isEmpty) { // if (mintResult.isEmpty) {
Logging.instance.log("nothing to mint", level: LogLevel.Info); // Logging.instance.log("nothing to mint", level: LogLevel.Info);
return; // return;
} // }
await _submitLelantusToNetwork(mintResult); // await _submitLelantusToNetwork(mintResult);
} catch (e, s) { // } catch (e, s) {
Logging.instance.log("Exception caught in _autoMint(): $e\n$s", // Logging.instance.log("Exception caught in _autoMint(): $e\n$s",
level: LogLevel.Error); // level: LogLevel.Error);
} // }
} // }
//
/// Returns the mint transaction hex to mint all of the available funds. // /// Returns the mint transaction hex to mint all of the available funds.
Future<Map<String, dynamic>> _mintSelection() async { // Future<Map<String, dynamic>> _mintSelection() async {
final List<UtxoObject> availableOutputs = _outputsList; // final List<UtxoObject> availableOutputs = _outputsList;
final List<UtxoObject?> spendableOutputs = []; // final List<UtxoObject?> spendableOutputs = [];
//
// Build list of spendable outputs and totaling their satoshi amount // // Build list of spendable outputs and totaling their satoshi amount
for (var i = 0; i < availableOutputs.length; i++) { // for (var i = 0; i < availableOutputs.length; i++) {
if (availableOutputs[i].blocked == false && // if (availableOutputs[i].blocked == false &&
availableOutputs[i].status.confirmed == true && // availableOutputs[i].status.confirmed == true &&
!(availableOutputs[i].isCoinbase && // !(availableOutputs[i].isCoinbase &&
availableOutputs[i].status.confirmations <= 101)) { // availableOutputs[i].status.confirmations <= 101)) {
spendableOutputs.add(availableOutputs[i]); // spendableOutputs.add(availableOutputs[i]);
} // }
} // }
//
final List<Map<dynamic, LelantusCoin>> lelantusCoins = getLelantusCoinMap(); // final List<Map<dynamic, LelantusCoin>> lelantusCoins = getLelantusCoinMap();
if (lelantusCoins != null && lelantusCoins.isNotEmpty) { // if (lelantusCoins != null && lelantusCoins.isNotEmpty) {
lelantusCoins.removeWhere((element) => // lelantusCoins.removeWhere((element) =>
element.values.any((elementCoin) => elementCoin.value == 0)); // element.values.any((elementCoin) => elementCoin.value == 0));
} // }
final data = await _txnData; // final data = await _txnData;
if (lelantusCoins != null) { // if (lelantusCoins != null) {
final dataMap = data.getAllTransactions(); // final dataMap = data.getAllTransactions();
dataMap.forEach((key, value) { // dataMap.forEach((key, value) {
if (value.inputs.isNotEmpty) { // if (value.inputs.isNotEmpty) {
for (var element in value.inputs) { // for (var element in value.inputs) {
if (lelantusCoins // if (lelantusCoins
.any((element) => element.keys.contains(value.txid)) && // .any((element) => element.keys.contains(value.txid)) &&
spendableOutputs.firstWhere( // spendableOutputs.firstWhere(
(output) => output?.txid == element.txid, // (output) => output?.txid == element.txid,
orElse: () => null) != // orElse: () => null) !=
null) { // null) {
spendableOutputs // spendableOutputs
.removeWhere((output) => output!.txid == element.txid); // .removeWhere((output) => output!.txid == element.txid);
} // }
} // }
} // }
}); // });
} // }
//
// If there is no Utxos to mint then stop the function. // // If there is no Utxos to mint then stop the function.
if (spendableOutputs.isEmpty) { // if (spendableOutputs.isEmpty) {
Logging.instance.log("_mintSelection(): No spendable outputs found", // Logging.instance.log("_mintSelection(): No spendable outputs found",
level: LogLevel.Info); // level: LogLevel.Info);
return {}; // return {};
} // }
//
int satoshisBeingUsed = 0; // int satoshisBeingUsed = 0;
List<UtxoObject> utxoObjectsToUse = []; // List<UtxoObject> utxoObjectsToUse = [];
//
for (var i = 0; i < spendableOutputs.length; i++) { // for (var i = 0; i < spendableOutputs.length; i++) {
final spendable = spendableOutputs[i]; // final spendable = spendableOutputs[i];
if (spendable != null) { // if (spendable != null) {
utxoObjectsToUse.add(spendable); // utxoObjectsToUse.add(spendable);
satoshisBeingUsed += spendable.value; // satoshisBeingUsed += spendable.value;
} // }
} // }
//
var mintsWithoutFee = await createMintsFromAmount(satoshisBeingUsed); // var mintsWithoutFee = await createMintsFromAmount(satoshisBeingUsed);
//
var tmpTx = await buildMintTransaction( // var tmpTx = await buildMintTransaction(
utxoObjectsToUse, satoshisBeingUsed, mintsWithoutFee); // utxoObjectsToUse, satoshisBeingUsed, mintsWithoutFee);
//
int vsize = (tmpTx['transaction'] as Transaction).virtualSize(); // int vsize = (tmpTx['transaction'] as Transaction).virtualSize();
final Decimal dvsize = Decimal.fromInt(vsize); // final Decimal dvsize = Decimal.fromInt(vsize);
//
final feesObject = await fees; // final feesObject = await fees;
//
final Decimal fastFee = Format.satoshisToAmount(feesObject.fast); // final Decimal fastFee = Format.satoshisToAmount(feesObject.fast);
int firoFee = // int firoFee =
(dvsize * fastFee * Decimal.fromInt(100000)).toDouble().ceil(); // (dvsize * fastFee * Decimal.fromInt(100000)).toDouble().ceil();
// int firoFee = (vsize * feesObject.fast * (1 / 1000.0) * 100000000).ceil(); // // int firoFee = (vsize * feesObject.fast * (1 / 1000.0) * 100000000).ceil();
//
if (firoFee < vsize) { // if (firoFee < vsize) {
firoFee = vsize + 1; // firoFee = vsize + 1;
} // }
firoFee = firoFee + 10; // firoFee = firoFee + 10;
int satoshiAmountToSend = satoshisBeingUsed - firoFee; // int satoshiAmountToSend = satoshisBeingUsed - firoFee;
//
var mintsWithFee = await createMintsFromAmount(satoshiAmountToSend); // var mintsWithFee = await createMintsFromAmount(satoshiAmountToSend);
//
Map<String, dynamic> transaction = await buildMintTransaction( // Map<String, dynamic> transaction = await buildMintTransaction(
utxoObjectsToUse, satoshiAmountToSend, mintsWithFee); // utxoObjectsToUse, satoshiAmountToSend, mintsWithFee);
transaction['transaction'] = ""; // transaction['transaction'] = "";
Logging.instance.log(transaction.toString(), level: LogLevel.Info); // Logging.instance.log(transaction.toString(), level: LogLevel.Info);
Logging.instance.log(transaction['txHex'], level: LogLevel.Info); // Logging.instance.log(transaction['txHex'], level: LogLevel.Info);
return transaction; // return transaction;
} // }
Future<List<Map<String, dynamic>>> createMintsFromAmount(int total) async { Future<List<Map<String, dynamic>>> createMintsFromAmount(int total) async {
var tmpTotal = total; var tmpTotal = total;
var index = 0; var index = 0;
var mints = <Map<String, dynamic>>[]; var mints = <Map<String, dynamic>>[];
final next_free_mint_index = final nextFreeMintIndex =
DB.instance.get<dynamic>(boxName: walletId, key: 'mintIndex') as int; DB.instance.get<dynamic>(boxName: walletId, key: 'mintIndex') as int;
while (tmpTotal > 0) { while (tmpTotal > 0) {
final mintValue = min(tmpTotal, MINT_LIMIT); final mintValue = min(tmpTotal, MINT_LIMIT);
final mint = await _getMintHex( final mint = await _getMintHex(
mintValue, mintValue,
next_free_mint_index + index, nextFreeMintIndex + index,
); );
mints.add({ mints.add({
"value": mintValue, "value": mintValue,
"script": mint, "script": mint,
"index": next_free_mint_index + index, "index": nextFreeMintIndex + index,
"publicCoin": "", "publicCoin": "",
}); });
tmpTotal = tmpTotal - MINT_LIMIT; tmpTotal = tmpTotal - MINT_LIMIT;
@ -2072,17 +2077,14 @@ class FiroWallet extends CoinServiceAPI {
joinsplits.add(tx.txid); joinsplits.add(tx.txid);
} }
} }
if (lelantusCoins != null) { for (final coin
for (final coin in lelantusCoins.fold(<LelantusCoin>[], (previousValue, element) {
in lelantusCoins.fold(<LelantusCoin>[], (previousValue, element) { (previousValue as List<LelantusCoin>).add(element.values.first);
(previousValue as List<LelantusCoin>).add(element.values.first); return previousValue;
return previousValue; })) {
})) { if (jindexes != null) {
if (jindexes != null) { if (jindexes.contains(coin.index) && !joinsplits.contains(coin.txId)) {
if (jindexes.contains(coin.index) && joinsplits.add(coin.txId);
!joinsplits.contains(coin.txId)) {
joinsplits.add(coin.txId);
}
} }
} }
} }
@ -2096,13 +2098,13 @@ class FiroWallet extends CoinServiceAPI {
// update all of joinsplits that are now confirmed. // update all of joinsplits that are now confirmed.
for (final tx in updatedJSplit) { for (final tx in updatedJSplit) {
final currenttx = listLelantusTxData[tx.txid]; final currentTx = listLelantusTxData[tx.txid];
if (currenttx == null) { if (currentTx == null) {
// this send was accidentally not included in the list // this send was accidentally not included in the list
listLelantusTxData[tx.txid] = tx; listLelantusTxData[tx.txid] = tx;
continue; continue;
} }
if (currenttx.confirmedStatus != tx.confirmedStatus) { if (currentTx.confirmedStatus != tx.confirmedStatus) {
listLelantusTxData[tx.txid] = tx; listLelantusTxData[tx.txid] = tx;
} }
} }
@ -2113,16 +2115,16 @@ class FiroWallet extends CoinServiceAPI {
final listTxData = txData.getAllTransactions(); final listTxData = txData.getAllTransactions();
listTxData.forEach((key, value) { listTxData.forEach((key, value) {
// ignore change addresses // ignore change addresses
bool hasAtLeastOneRecieve = false; bool hasAtLeastOneReceive = false;
int howManyRecieveInputs = 0; int howManyReceiveInputs = 0;
for (var element in value.inputs) { for (var element in value.inputs) {
if (listLelantusTxData.containsKey(element.txid) && if (listLelantusTxData.containsKey(element.txid) &&
listLelantusTxData[element.txid]!.txType == "Received" listLelantusTxData[element.txid]!.txType == "Received"
// && // &&
// listLelantusTxData[element.txid].subType != "mint" // listLelantusTxData[element.txid].subType != "mint"
) { ) {
hasAtLeastOneRecieve = true; hasAtLeastOneReceive = true;
howManyRecieveInputs++; howManyReceiveInputs++;
} }
} }
@ -2131,11 +2133,11 @@ class FiroWallet extends CoinServiceAPI {
// Every receive should be listed whether minted or not. // Every receive should be listed whether minted or not.
listLelantusTxData[value.txid] = value; listLelantusTxData[value.txid] = value;
} else if (value.txType == "Sent" && } else if (value.txType == "Sent" &&
hasAtLeastOneRecieve && hasAtLeastOneReceive &&
value.subType == "mint") { value.subType == "mint") {
// use mint sends to update receives with user readable values. // use mint sends to update receives with user readable values.
int sharedFee = value.fees ~/ howManyRecieveInputs; int sharedFee = value.fees ~/ howManyReceiveInputs;
for (var element in value.inputs) { for (var element in value.inputs) {
if (listLelantusTxData.containsKey(element.txid) && if (listLelantusTxData.containsKey(element.txid) &&
@ -2203,7 +2205,7 @@ class FiroWallet extends CoinServiceAPI {
final List<Map<dynamic, LelantusCoin>> lelantusCoins = final List<Map<dynamic, LelantusCoin>> lelantusCoins =
getLelantusCoinMap(); getLelantusCoinMap();
List<Map<dynamic, LelantusCoin>> coins; List<Map<dynamic, LelantusCoin>> coins;
if (lelantusCoins == null || lelantusCoins.isEmpty) { if (lelantusCoins.isEmpty) {
coins = []; coins = [];
} else { } else {
coins = [...lelantusCoins]; coins = [...lelantusCoins];
@ -2213,16 +2215,16 @@ class FiroWallet extends CoinServiceAPI {
// This is a joinsplit // This is a joinsplit
// Update all of the coins that have been spent. // Update all of the coins that have been spent.
for (final lcoinmap in coins) { for (final lCoinMap in coins) {
final lcoin = lcoinmap.values.first; final lCoin = lCoinMap.values.first;
if ((transactionInfo['spendCoinIndexes'] as List<int>) if ((transactionInfo['spendCoinIndexes'] as List<int>)
.contains(lcoin.index)) { .contains(lCoin.index)) {
lcoinmap[lcoinmap.keys.first] = LelantusCoin( lCoinMap[lCoinMap.keys.first] = LelantusCoin(
lcoin.index, lCoin.index,
lcoin.value, lCoin.value,
lcoin.publicCoin, lCoin.publicCoin,
lcoin.txId, lCoin.txId,
lcoin.anonymitySetId, lCoin.anonymitySetId,
true); true);
} }
} }
@ -2835,7 +2837,7 @@ class FiroWallet extends CoinServiceAPI {
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: walletId, key: 'latest_utxo_model', value: dataModel); boxName: walletId, key: 'latest_utxo_model', value: dataModel);
return dataModel; return dataModel;
} catch (e, s) { } catch (e) {
// Logging.instance.log("Output fetch unsuccessful: $e\n$s"); // Logging.instance.log("Output fetch unsuccessful: $e\n$s");
final latestTxModel = final latestTxModel =
DB.instance.get<dynamic>(boxName: walletId, key: 'latest_utxo_model') DB.instance.get<dynamic>(boxName: walletId, key: 'latest_utxo_model')
@ -3096,7 +3098,7 @@ class FiroWallet extends CoinServiceAPI {
); );
// clear cache // clear cache
_cachedElectrumXClient.clearSharedTransactionCache(coin: coin); await _cachedElectrumXClient.clearSharedTransactionCache(coin: coin);
// back up data // back up data
await _rescanBackup(); await _rescanBackup();
@ -3687,7 +3689,7 @@ class FiroWallet extends CoinServiceAPI {
this.isActive = isActive; this.isActive = isActive;
}; };
Future<dynamic> GetCoinsToJoinSplit( Future<dynamic> getCoinsToJoinSplit(
int required, int required,
) async { ) async {
List<DartLelantusEntry> coins = await _getLelantusEntry(); List<DartLelantusEntry> coins = await _getLelantusEntry();
@ -3696,7 +3698,7 @@ class FiroWallet extends CoinServiceAPI {
} }
int availableBalance = coins.fold( int availableBalance = coins.fold(
0, (previousValue, element) => (previousValue as int) + element.amount); 0, (previousValue, element) => previousValue + element.amount);
if (required > availableBalance) { if (required > availableBalance) {
return false; return false;
@ -3707,21 +3709,21 @@ class FiroWallet extends CoinServiceAPI {
(a.amount != b.amount ? a.amount > b.amount : a.height < b.height) (a.amount != b.amount ? a.amount > b.amount : a.height < b.height)
? -1 ? -1
: 1); : 1);
int spend_val = 0; int spendVal = 0;
List<DartLelantusEntry> coinsToSpend = []; List<DartLelantusEntry> coinsToSpend = [];
while (spend_val < required) { while (spendVal < required) {
if (coins.isEmpty) { if (coins.isEmpty) {
break; break;
} }
DartLelantusEntry? choosen; DartLelantusEntry? chosen;
int need = required - spend_val; int need = required - spendVal;
var itr = coins.first; var itr = coins.first;
if (need >= itr.amount) { if (need >= itr.amount) {
choosen = itr; chosen = itr;
coins.remove(itr); coins.remove(itr);
} else { } else {
for (int index = coins.length - 1; index != 0; index--) { for (int index = coins.length - 1; index != 0; index--) {
@ -3730,32 +3732,32 @@ class FiroWallet extends CoinServiceAPI {
if (coinIt.amount >= need && if (coinIt.amount >= need &&
(index - 1 == 0 || nextItr.amount != coinIt.amount)) { (index - 1 == 0 || nextItr.amount != coinIt.amount)) {
choosen = coinIt; chosen = coinIt;
coins.remove(choosen); coins.remove(chosen);
break; break;
} }
} }
} }
spend_val += choosen!.amount; spendVal += chosen!.amount;
coinsToSpend.insert(coinsToSpend.length, choosen); coinsToSpend.insert(coinsToSpend.length, chosen);
} }
// sort by group id ay ascending order. it is mandatory for creting proper joinsplit // sort by group id ay ascending order. it is mandatory for creating proper joinsplit
coinsToSpend.sort((a, b) => a.anonymitySetId < b.anonymitySetId ? 1 : -1); coinsToSpend.sort((a, b) => a.anonymitySetId < b.anonymitySetId ? 1 : -1);
int changeToMint = spend_val - required; int changeToMint = spendVal - required;
List<int> indices = []; List<int> indices = [];
for (var l in coinsToSpend) { for (var l in coinsToSpend) {
indices.add(l.index); indices.add(l.index);
} }
List<DartLelantusEntry> coinsToBeSpent_out = []; List<DartLelantusEntry> coinsToBeSpentOut = [];
coinsToBeSpent_out.addAll(coinsToSpend); coinsToBeSpentOut.addAll(coinsToSpend);
return {"changeToMint": changeToMint, "coinsToSpend": coinsToBeSpent_out}; return {"changeToMint": changeToMint, "coinsToSpend": coinsToBeSpentOut};
} }
Future<int> EstimateJoinSplitFee( Future<int> estimateJoinSplitFee(
int spendAmount, int spendAmount,
) async { ) async {
int fee; int fee;
@ -3764,7 +3766,7 @@ class FiroWallet extends CoinServiceAPI {
for (fee = 0;;) { for (fee = 0;;) {
int currentRequired = spendAmount; int currentRequired = spendAmount;
var map = await GetCoinsToJoinSplit(currentRequired); var map = await getCoinsToJoinSplit(currentRequired);
if (map is bool && !map) { if (map is bool && !map) {
return 0; return 0;
} }
@ -3791,7 +3793,7 @@ class FiroWallet extends CoinServiceAPI {
@override @override
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async { Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
int fee = await EstimateJoinSplitFee(satoshiAmount); int fee = await estimateJoinSplitFee(satoshiAmount);
return fee; return fee;
} }

View file

@ -386,11 +386,11 @@ class MockFiroWallet extends _i1.Mock implements _i7.FiroWallet {
returnValue: Future<void>.value(), returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i8.Future<void>); returnValueForMissingStub: Future<void>.value()) as _i8.Future<void>);
@override @override
_i8.Future<dynamic> GetCoinsToJoinSplit(int? required) => _i8.Future<dynamic> getCoinsToJoinSplit(int? required) =>
(super.noSuchMethod(Invocation.method(#GetCoinsToJoinSplit, [required]), (super.noSuchMethod(Invocation.method(#GetCoinsToJoinSplit, [required]),
returnValue: Future<dynamic>.value()) as _i8.Future<dynamic>); returnValue: Future<dynamic>.value()) as _i8.Future<dynamic>);
@override @override
_i8.Future<int> EstimateJoinSplitFee(int? spendAmount) => (super.noSuchMethod( _i8.Future<int> estimateJoinSplitFee(int? spendAmount) => (super.noSuchMethod(
Invocation.method(#EstimateJoinSplitFee, [spendAmount]), Invocation.method(#EstimateJoinSplitFee, [spendAmount]),
returnValue: Future<int>.value(0)) as _i8.Future<int>); returnValue: Future<int>.value(0)) as _i8.Future<int>);
@override @override