Skip to content

Commit 6355522

Browse files
[Issue-4263] Prevent dust limit for bitcoin transaction
1 parent f6f8165 commit 6355522

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

packages/extension-base/src/utils/bitcoin/utxo-management.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export function determineUtxosForSpendAll ({ feeRate,
6767
if (!validateBitcoinAddress(recipient)) {
6868
throw new Error('Cannot calculate spend of invalid address type');
6969
}
70+
// TODO: Prevent dust limit when transferring all
7071

7172
const recipients = [recipient];
7273

@@ -107,6 +108,15 @@ export function determineUtxosForSpend ({ amount,
107108
throw new Error('Cannot calculate spend of invalid address type');
108109
}
109110

111+
const recipientAddressInfo = getBitcoinAddressInfo(recipient);
112+
const recipientDustLimit = BTC_DUST_AMOUNT[recipientAddressInfo.type] || 546;
113+
114+
if (amount < recipientDustLimit) {
115+
throw new Error(
116+
`Transfer amount ${amount} satoshis is below dust limit (${recipientDustLimit} satoshis for ${recipientAddressInfo.type})`
117+
);
118+
}
119+
110120
const orderedUtxos = utxos.sort((a, b) => b.value - a.value);
111121
const recipients = [recipient, sender];
112122
const filteredUtxos = filterUneconomicalUtxos({
@@ -156,13 +166,33 @@ export function determineUtxosForSpend ({ amount,
156166
throw new InsufficientFundsError();
157167
}
158168

169+
const senderAddressInfo = getBitcoinAddressInfo(sender);
170+
const dustLimit = BTC_DUST_AMOUNT[senderAddressInfo.type] || 546;
171+
159172
const outputs = [
160173
// outputs[0] = the desired amount going to recipient
161-
{ value: amount, address: recipient },
162-
// outputs[1] = the remainder to be returned to a change address
163-
{ value: amountLeft.toNumber(), address: sender }
174+
{ value: amount, address: recipient }
164175
];
165176

177+
if (amountLeft.gte(dustLimit)) {
178+
// outputs[1] = the remainder to be returned to a change address
179+
outputs.push({ value: amountLeft.toNumber(), address: sender });
180+
} else {
181+
console.warn(
182+
`Change output of ${amountLeft.toString()} satoshis is below dust limit (${dustLimit} satoshis for ${senderAddressInfo.type}). Omitting change output and adding to fee.`
183+
);
184+
// Increase the fee to use the remaining balance
185+
const newFee = sum.minus(amount).toNumber();
186+
187+
return {
188+
filteredUtxos,
189+
inputs: neededUtxos,
190+
outputs,
191+
size: sizeInfo.txVBytes,
192+
fee: newFee
193+
};
194+
}
195+
166196
return {
167197
filteredUtxos,
168198
inputs: neededUtxos,

0 commit comments

Comments
 (0)