mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
fix: sp input calc (#1756)
This commit is contained in:
@@ -784,6 +784,7 @@ abstract class ElectrumWalletBase
|
||||
Future<EstimatedTxResult> estimateTxForAmount(
|
||||
int credentialsAmount,
|
||||
List<BitcoinOutput> outputs,
|
||||
List<BitcoinOutput> updatedOutputs,
|
||||
int feeRate, {
|
||||
int? inputsCount,
|
||||
String? memo,
|
||||
@@ -812,6 +813,7 @@ abstract class ElectrumWalletBase
|
||||
return estimateTxForAmount(
|
||||
credentialsAmount,
|
||||
outputs,
|
||||
updatedOutputs,
|
||||
feeRate,
|
||||
inputsCount: utxoDetails.utxos.length + 1,
|
||||
memo: memo,
|
||||
@@ -824,19 +826,30 @@ abstract class ElectrumWalletBase
|
||||
}
|
||||
|
||||
final changeAddress = await walletAddresses.getChangeAddress(
|
||||
outputs: outputs,
|
||||
outputs: updatedOutputs,
|
||||
utxoDetails: utxoDetails,
|
||||
);
|
||||
final address = RegexUtils.addressTypeFromStr(changeAddress, network);
|
||||
updatedOutputs.add(BitcoinOutput(
|
||||
address: address,
|
||||
value: BigInt.from(amountLeftForChangeAndFee),
|
||||
isChange: true,
|
||||
));
|
||||
outputs.add(BitcoinOutput(
|
||||
address: address,
|
||||
value: BigInt.from(amountLeftForChangeAndFee),
|
||||
isChange: true,
|
||||
));
|
||||
|
||||
// calcFee updates the silent payment outputs to calculate the tx size accounting
|
||||
// for taproot addresses, but if more inputs are needed to make up for fees,
|
||||
// the silent payment outputs need to be recalculated for the new inputs
|
||||
var temp = outputs.map((output) => output).toList();
|
||||
int fee = await calcFee(
|
||||
utxos: utxoDetails.utxos,
|
||||
outputs: outputs,
|
||||
// Always take only not updated bitcoin outputs here so for every estimation
|
||||
// the SP outputs are re-generated to the proper taproot addresses
|
||||
outputs: temp,
|
||||
network: network,
|
||||
memo: memo,
|
||||
feeRate: feeRate,
|
||||
@@ -844,18 +857,25 @@ abstract class ElectrumWalletBase
|
||||
vinOutpoints: utxoDetails.vinOutpoints,
|
||||
);
|
||||
|
||||
updatedOutputs.clear();
|
||||
updatedOutputs.addAll(temp);
|
||||
|
||||
if (fee == 0) {
|
||||
throw BitcoinTransactionNoFeeException();
|
||||
}
|
||||
|
||||
int amount = credentialsAmount;
|
||||
final lastOutput = outputs.last;
|
||||
final lastOutput = updatedOutputs.last;
|
||||
final amountLeftForChange = amountLeftForChangeAndFee - fee;
|
||||
|
||||
print(amountLeftForChangeAndFee);
|
||||
|
||||
if (!_isBelowDust(amountLeftForChange)) {
|
||||
// Here, lastOutput already is change, return the amount left without the fee to the user's address.
|
||||
updatedOutputs[updatedOutputs.length - 1] = BitcoinOutput(
|
||||
address: lastOutput.address,
|
||||
value: BigInt.from(amountLeftForChange),
|
||||
isSilentPayment: lastOutput.isSilentPayment,
|
||||
isChange: true,
|
||||
);
|
||||
outputs[outputs.length - 1] = BitcoinOutput(
|
||||
address: lastOutput.address,
|
||||
value: BigInt.from(amountLeftForChange),
|
||||
@@ -864,6 +884,7 @@ abstract class ElectrumWalletBase
|
||||
);
|
||||
} else {
|
||||
// If has change that is lower than dust, will end up with tx rejected by network rules, so estimate again without the added change
|
||||
updatedOutputs.removeLast();
|
||||
outputs.removeLast();
|
||||
|
||||
// Still has inputs to spend before failing
|
||||
@@ -871,16 +892,18 @@ abstract class ElectrumWalletBase
|
||||
return estimateTxForAmount(
|
||||
credentialsAmount,
|
||||
outputs,
|
||||
updatedOutputs,
|
||||
feeRate,
|
||||
inputsCount: utxoDetails.utxos.length + 1,
|
||||
memo: memo,
|
||||
hasSilentPayment: hasSilentPayment,
|
||||
useUnconfirmed: useUnconfirmed ?? spendingAllConfirmedCoins,
|
||||
coinTypeToSpendFrom: coinTypeToSpendFrom,
|
||||
);
|
||||
}
|
||||
|
||||
final estimatedSendAll = await estimateSendAllTx(
|
||||
outputs,
|
||||
updatedOutputs,
|
||||
feeRate,
|
||||
memo: memo,
|
||||
coinTypeToSpendFrom: coinTypeToSpendFrom,
|
||||
@@ -913,10 +936,12 @@ abstract class ElectrumWalletBase
|
||||
if (spendingAllCoins) {
|
||||
throw BitcoinTransactionWrongBalanceException();
|
||||
} else {
|
||||
updatedOutputs.removeLast();
|
||||
outputs.removeLast();
|
||||
return estimateTxForAmount(
|
||||
credentialsAmount,
|
||||
outputs,
|
||||
updatedOutputs,
|
||||
feeRate,
|
||||
inputsCount: utxoDetails.utxos.length + 1,
|
||||
memo: memo,
|
||||
@@ -1029,6 +1054,9 @@ abstract class ElectrumWalletBase
|
||||
: feeRate(transactionCredentials.priority!);
|
||||
|
||||
EstimatedTxResult estimatedTx;
|
||||
final updatedOutputs =
|
||||
outputs.map((e) => BitcoinOutput(address: e.address, value: e.value)).toList();
|
||||
|
||||
if (sendAll) {
|
||||
estimatedTx = await estimateSendAllTx(
|
||||
outputs,
|
||||
@@ -1042,6 +1070,7 @@ abstract class ElectrumWalletBase
|
||||
estimatedTx = await estimateTxForAmount(
|
||||
credentialsAmount,
|
||||
outputs,
|
||||
updatedOutputs,
|
||||
feeRateInt,
|
||||
memo: memo,
|
||||
hasSilentPayment: hasSilentPayment,
|
||||
@@ -1052,7 +1081,7 @@ abstract class ElectrumWalletBase
|
||||
if (walletInfo.isHardwareWallet) {
|
||||
final transaction = await buildHardwareWalletTransaction(
|
||||
utxos: estimatedTx.utxos,
|
||||
outputs: outputs,
|
||||
outputs: updatedOutputs,
|
||||
publicKeys: estimatedTx.publicKeys,
|
||||
fee: BigInt.from(estimatedTx.fee),
|
||||
network: network,
|
||||
@@ -1092,7 +1121,7 @@ abstract class ElectrumWalletBase
|
||||
} else {
|
||||
txb = BitcoinTransactionBuilder(
|
||||
utxos: estimatedTx.utxos,
|
||||
outputs: outputs,
|
||||
outputs: updatedOutputs,
|
||||
fee: BigInt.from(estimatedTx.fee),
|
||||
network: network,
|
||||
memo: estimatedTx.memo,
|
||||
|
||||
Reference in New Issue
Block a user