import { Psbt } from 'bitcoinjs-lib'; import { digibyte } from '../core/index.js'; // Construct an unsigned PSBT from a set of UTXOs and destination outputs. // Does not add a change output — the caller decides change amount and // address. Does not compute fees — the caller must have already subtracted // fee from outputs. export function buildPsbt(params, network = digibyte) { const psbt = new Psbt({ network }); const inputs = params.sortBip69 === false ? params.inputs : sortInputs(params.inputs); const outputs = params.sortBip69 === false ? params.outputs : sortOutputs(params.outputs); for (const u of inputs) { psbt.addInput(inputToPsbtInput(u)); } for (const o of outputs) { psbt.addOutput({ address: o.address, value: o.value }); } return psbt; } function inputToPsbtInput(u) { const input = { hash: u.txid, index: u.vout, }; if (u.witness) { input.witnessUtxo = { script: Buffer.from(u.witness.scriptHex, 'hex'), value: u.witness.value, }; } if (u.nonWitnessTxHex) { input.nonWitnessUtxo = Buffer.from(u.nonWitnessTxHex, 'hex'); } if (u.redeemScriptHex) { input.redeemScript = Buffer.from(u.redeemScriptHex, 'hex'); } if (u.tapInternalKeyHex) { input.tapInternalKey = Buffer.from(u.tapInternalKeyHex, 'hex'); } return input; } // BIP69 lexicographic ordering. Improves privacy by not revealing input // selection order (which can hint at wallet coin-selection strategy). function sortInputs(inputs) { return [...inputs].sort((a, b) => { const cmp = a.txid.localeCompare(b.txid); return cmp !== 0 ? cmp : a.vout - b.vout; }); } function sortOutputs(outputs) { return [...outputs].sort((a, b) => { if (a.value !== b.value) return a.value - b.value; return a.address.localeCompare(b.address); }); } //# sourceMappingURL=build.js.map