56 lines
1.9 KiB
JavaScript
56 lines
1.9 KiB
JavaScript
|
|
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
|