From c2b1ad4e403cf3ed1a76fd6f9507e80560c34891 Mon Sep 17 00:00:00 2001 From: Jamie Ford Date: Thu, 21 Nov 2024 13:15:44 +1100 Subject: [PATCH] fix: bouncer lock utxos after selection --- bouncer/shared/send_btc.ts | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/bouncer/shared/send_btc.ts b/bouncer/shared/send_btc.ts index f79f53e090..95aad18f5f 100644 --- a/bouncer/shared/send_btc.ts +++ b/bouncer/shared/send_btc.ts @@ -12,25 +12,33 @@ export const btcClient = new Client({ }); export async function selectInputs(amount: number) { - // List unspent UTXOs - const utxos = await btcClient.listUnspent(); + return btcClientMutex.runExclusive(async () => { + // List unspent UTXOs + const utxos = await btcClient.listUnspent(); - // Find a UTXO with enough funds - const utxo = utxos.find((u) => u.amount >= amount); - if (!utxo) throw new Error('Insufficient funds'); - // TODO: be able to select more than one UTXO + // Find a UTXO with enough funds + const utxo = utxos.find((u) => u.amount >= amount); + if (!utxo) throw new Error('Insufficient funds'); + // TODO: be able to select more than one UTXO - const change = utxo.amount - amount; + // Lock the selected UTXO to prevent it from being used in another transaction + await btcClient.lockUnspent(false, [{ txid: utxo.txid, vout: utxo.vout }]); - // Prepare the transaction inputs and outputs - const inputs = [ - { - txid: utxo.txid, - vout: utxo.vout, - }, - ]; + const change = utxo.amount - amount; - return { inputs, change }; + // Prepare the transaction inputs + const inputs = [ + { + txid: utxo.txid, + vout: utxo.vout, + }, + ]; + + return { + inputs, + change, + }; + }); } export async function waitForBtcTransaction(txid: string, confirmations = 1) {