From e851e5c75c14d6ad1fb0032b6980de3b5a71912c Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 14 Aug 2024 21:25:16 -0600 Subject: [PATCH] WIP: tweaking draft single vs draft multi --- dashtx.js | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/dashtx.js b/dashtx.js index 921c487..76e2810 100644 --- a/dashtx.js +++ b/dashtx.js @@ -412,24 +412,37 @@ var DashTx = ("object" === typeof module && exports) || {}; * @returns {TxDraft} */ txInst.legacy.draftSingleOutput = function ({ utxos, inputs, output }) { + let outputs = [output]; + return txInst.legacy._draft({ utxos, inputs, outputs }); + }; + + /** + * @param {Object} opts + * @param {Array?} [opts.inputs] + * @param {Array?} [opts.utxos] + * @param {Array} opts.outputs + * @returns {TxDraft} + */ + txInst.legacy._draft = function ({ utxos, inputs, outputs }) { let fullTransfer = false; + let sats = DashTx.sum(outputs); if (!inputs) { inputs = DashTx._legacyMustSelectInputs({ - utxos: utxos, - satoshis: output.satoshis, + utxos, + outputs, }); if (!inputs) { // tsc can't tell that 'inputs' was just guaranteed throw new Error(`type checker workaround`); } } else { - fullTransfer = !output.satoshis; + fullTransfer = !sats; } let totalAvailable = DashTx.sum(inputs); //@ts-ignore - TODO update typedefs - let fees = DashTx.appraise({ inputs: inputs, outputs: [output] }); + let fees = DashTx.appraise({ inputs: inputs, outputs: outputs }); //let EXTRA_SIG_BYTES_PER_INPUT = 2; let CHANCE_INPUT_SIGS_HAVE_NO_EXTRA_BYTES = 1 / 4; @@ -448,15 +461,17 @@ var DashTx = ("object" === typeof module && exports) || {}; feeTarget += likelyPadByteSize; } - let recip = Object.assign({}, output); - if (!recip.satoshis) { - recip.satoshis = totalAvailable + -feeTarget; + if (!sats) { + if (outputs.length === 1) { + let recip = Object.assign({}, outputs[0]); + recip.satoshis = totalAvailable + -feeTarget; + outputs = [recip]; + } } - let outputs = [recip]; let change; let changeSats = - totalAvailable + -recip.satoshis + -feeTarget + -DashTx.OUTPUT_SIZE; + totalAvailable + -sats + -feeTarget + -DashTx.OUTPUT_SIZE; let hasChange = changeSats > DashTx.LEGACY_DUST; if (hasChange) { change = { address: "", satoshis: changeSats }; @@ -465,7 +480,7 @@ var DashTx = ("object" === typeof module && exports) || {}; } else { change = null; // Re: Dash Direct: we round in favor of the network (exact payments) - feeTarget = totalAvailable + -recip.satoshis; + feeTarget = totalAvailable + -sats; } let txInfoRaw = { @@ -949,7 +964,7 @@ var DashTx = ("object" === typeof module && exports) || {}; throw err; } - let selected = Tx._legacySelectOptimalUtxos(utxos, satoshis); + let selected = Tx._legacySelectOptimalUtxos(utxos, satoshis, 1); if (!selected.length) { throw Tx._createInsufficientFundsError(utxos, satoshis); } @@ -961,10 +976,10 @@ var DashTx = ("object" === typeof module && exports) || {}; * @template {Pick} T * @param {Array} utxos * @param {Uint53} outputSats + * @param {Uint32} [numOutputs] * @return {Array} */ - Tx._legacySelectOptimalUtxos = function (utxos, outputSats) { - let numOutputs = 1; + Tx._legacySelectOptimalUtxos = function (utxos, outputSats, numOutputs = 1) { let extraSize = 0; let fees = DashTx._appraiseCounts(utxos.length, numOutputs, extraSize); @@ -1373,7 +1388,7 @@ var DashTx = ("object" === typeof module && exports) || {}; Tx.sum = function (coins) { let balance = 0; for (let utxo of coins) { - let sats = utxo.satoshis; + let sats = utxo.satoshis || 0; balance += sats; }