@node-dlc/core
Version:
77 lines • 2.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.dualFundingCoinSelect = exports.dualFees = exports.dustThreshold = void 0;
const messaging_1 = require("@node-dlc/messaging");
const TxFinalizer_1 = require("./TxFinalizer");
const TX_INPUT_SIZE = {
LEGACY: 148,
P2SH: 92,
BECH32: 69,
};
const inputBytes = () => {
return BigInt(TX_INPUT_SIZE.BECH32);
};
const dustThreshold = (feeRate) => {
return BigInt(inputBytes()) * feeRate;
};
exports.dustThreshold = dustThreshold;
// order by descending value, minus the inputs approximate fee
const utxoScore = (x, feeRate) => {
return BigInt(x.value) - feeRate * inputBytes();
};
const dualFees = (feeRate, numInputs, numContracts) => {
const input = new messaging_1.FundingInput();
input.maxWitnessLen = 108;
input.redeemScript = Buffer.from('', 'hex');
const fakeSPK = Buffer.from('0014663117d27e78eb432505180654e603acb30e8a4a', 'hex');
const offerInputs = Array.from({ length: numInputs }, () => input);
const acceptInputs = Array.from({ length: 1 }, () => input);
return new TxFinalizer_1.DualFundingTxFinalizer(offerInputs, fakeSPK, fakeSPK, acceptInputs, fakeSPK, fakeSPK, feeRate, numContracts).offerFees;
};
exports.dualFees = dualFees;
/**
* Selects UTXOs for dual funding
* @param utxos - UTXOs to select from
* @param collaterals - Collaterals to fund (just one for non-batch tx)
* @param feeRate - Fee rate in satoshis per byte
* @returns Inputs and fee
* @description
* Add inputs until we reach or surpass the target value (or deplete)
* Worst-case: O(n)
*/
const dualFundingCoinSelect = (utxos, collaterals, // in satoshis
feeRate) => {
utxos = [...utxos].sort((a, b) => Number(utxoScore(b, feeRate) - utxoScore(a, feeRate)));
let inAccum = 0;
const inputs = [];
const outAccum = collaterals.reduce((acc, val) => acc + val, BigInt(0)) +
(0, exports.dustThreshold)(feeRate); // sum of collaterals
for (let i = 0; i < utxos.length; ++i) {
const utxo = utxos[i];
const utxoBytes = inputBytes();
const utxoFee = feeRate * utxoBytes;
const utxoValue = utxo.value;
// skip detrimental input
if (utxoFee > utxo.value) {
if (i === utxos.length - 1)
return {
fee: (0, exports.dualFees)(feeRate, 1, collaterals.length),
inputs: [],
};
continue;
}
inAccum += utxoValue;
inputs.push(utxo);
const fee = (0, exports.dualFees)(feeRate, inputs.length, collaterals.length);
// go again?
if (inAccum < outAccum + fee)
continue;
return { inputs, fee };
}
return {
fee: (0, exports.dualFees)(feeRate, 1, collaterals.length),
inputs: [],
};
};
exports.dualFundingCoinSelect = dualFundingCoinSelect;
//# sourceMappingURL=CoinSelect.js.map