@xlink-network/xlink-sdk
Version:
84 lines (76 loc) • 2.34 kB
text/typescript
import * as btc from "@scure/btc-signer"
import { isNotNull } from "../utils/typeHelpers"
import { BitcoinNetwork, isSameUTXO, UTXOBasic } from "./bitcoinHelpers"
import { createTransaction } from "./createTransaction"
import { prepareTransaction } from "./prepareTransaction"
import {
GetConfirmedSpendableUTXOFn,
reselectSpendableUTXOsFactory,
} from "./selectUTXOs"
export interface InscriptionRecipient {
inscriptionUtxo: UTXOBasic
addressScriptPubKey: Uint8Array
}
export async function createSendInscriptionTransaction(options: {
network: BitcoinNetwork
inscriptionRecipients: InscriptionRecipient[]
changeAddressScriptPubKey: Uint8Array
opReturnData?: Uint8Array[]
availableFeeUtxos: UTXOBasic[]
feeRate: bigint
getUTXOSpendable: GetConfirmedSpendableUTXOFn
}): Promise<{
tx: btc.Transaction
inscriptionUtxoInputIndices: number[]
bitcoinUtxoInputIndices: number[]
}> {
const opReturnData = options.opReturnData ?? []
const recipients = options.inscriptionRecipients.map(r => ({
addressScriptPubKey: r.addressScriptPubKey,
satsAmount: r.inscriptionUtxo.amount,
}))
const selectedUTXOs = await Promise.all(
options.inscriptionRecipients.map(r =>
options.getUTXOSpendable(r.inscriptionUtxo),
),
).then(utxos => utxos.filter(isNotNull))
const {
inputs,
recipients: newRecipients,
changeAmount,
} = await prepareTransaction({
recipients,
changeAddressScriptPubKey: options.changeAddressScriptPubKey,
opReturnData,
feeRate: options.feeRate,
selectedUTXOs,
reselectSpendableUTXOs: reselectSpendableUTXOsFactory(
options.availableFeeUtxos.filter(
u => !selectedUTXOs.find(_u => isSameUTXO(u, _u)),
),
options.getUTXOSpendable,
),
})
const tx = createTransaction(
inputs,
newRecipients.concat(
changeAmount === 0n
? []
: {
addressScriptPubKey: options.changeAddressScriptPubKey,
satsAmount: changeAmount,
},
),
opReturnData,
)
const inscriptionCount = options.inscriptionRecipients.length
return {
tx,
inscriptionUtxoInputIndices: inputs
.slice(0, inscriptionCount)
.map((_, i) => i),
bitcoinUtxoInputIndices: inputs
.slice(inscriptionCount)
.map((_, i) => i + inscriptionCount),
}
}