Skip to content

Instantly share code, notes, and snippets.

@losh11
Created March 21, 2025 12:31
Show Gist options
  • Save losh11/e37b51d29491b9578d6cdb388eddb905 to your computer and use it in GitHub Desktop.
Save losh11/e37b51d29491b9578d6cdb388eddb905 to your computer and use it in GitHub Desktop.
export const sendConvertPsbtTransaction = async (
amount: number,
destination: 'regular' | 'private',
) => {
try {
// new destination address
let type: number;
if (destination === 'private') {
type = 7;
} else {
type = 2;
}
const destinationAddress = await newLndAddress({type});
// lookup utxos
const listUnspentResponse = await walletKitListUnspent({});
if (!listUnspentResponse || !listUnspentResponse.utxos) {
throw new Error('Invalid response from ListUnspent');
}
const {utxos} = listUnspentResponse;
// filter mweb and non mweb utxos, sort by largest
// coin selection will use first largest available
const mwebUtxos = utxos
.filter(utxo => utxo.addressType === 6)
.sort((a, b) => Number(b.amountSat) - Number(a.amountSat));
const nonMwebUtxos = utxos
.filter(utxo => utxo.addressType !== 6)
.sort((a, b) => Number(b.amountSat) - Number(a.amountSat));
const {selectedUtxos, totalAmountSat} = selectUtxosForConversion(
destination === 'regular' ? mwebUtxos : nonMwebUtxos,
amount,
);
// check if selected UTXOs satisfy the amount
if (totalAmountSat < amount) {
throw new Error('Insufficient funds in UTXOs');
}
const outpointsArray = selectedUtxos
.map(utxo => utxo.outpoint)
.filter((outpoint): outpoint is OutPoint => outpoint !== undefined);
if (outpointsArray.length < 1 || outpointsArray === undefined) {
throw new Error('Outpoints empty!');
}
const psbt = await walletKitFundPsbt({
template: {
case: 'raw',
value: {
inputs: outpointsArray,
outputs: {
[destinationAddress.address]: BigInt(amount),
},
},
},
fees: {
case: 'targetConf',
value: 3,
},
});
const signedPsbt = await walletKitFinalizePsbt({
fundedPsbt: psbt.fundedPsbt,
});
const txHex = Buffer.from(signedPsbt.rawFinalTx).toString('hex');
const finalPsbt = Buffer.from(signedPsbt.signedPsbt).toString('base64');
console.log(txHex);
console.log(finalPsbt);
console.log(destinationAddress.address);
// transaction.ts:270 Error: rpc error: code = Unknown desc = error finalizing PSBT: found UTXO tx cde375a5aaa7d6878e44d502e04af28f34af3836ebb139242ae7f8adbfea1662 but it doesn't match PSBT's input 7e237d4d7a8fdfe941f6caa8aaec5fffcb70ce3084e0f8d99a12a87aa0f37059
await publishTransaction(txHex);
} catch (error) {
console.error(error);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment