Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: move legacy draft & finalizeAndSign from DashWallet.js to here #35

Merged
merged 6 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 93 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,52 @@ above, there were 2 inputs and 2 outputs. The example is truncated for brevity.
# API

<!--
rg '^\s+Tx\.'
rg '^\s+Tx\.[A-Z_]+ ='
-->

```txt
Tx.HEADER_SIZE // 10
Tx.MIN_INPUT_SIZE // 147
Tx.MAX_INPUT_SIZE // 150
Tx.MAX_INPUT_PAD // 3
Tx.OUTPUT_SIZE // 34
```text
Tx.SATOSHIS // 1_000_00000
Tx.LEGACY_DUST // 02000

Tx.HEADER_SIZE // 10
Tx.MIN_INPUT_SIZE // 147
Tx.MAX_INPUT_SIZE // 149
Tx.MAX_INPUT_PAD // 2
Tx.OUTPUT_SIZE // 34
```

```text
Tx.create({ sign, getPrivateKey });
tx.hashAndSignAll(txInfo);
tx.legacy.draftSingleOutput({ utxos, inputs, output });
tx.legacy.finalizePresorted(txDraft, keys);

Tx.appraise({ inputs, outputs });
Tx.getId(txHex);

// Byte-level helpers
Tx.utils.toVarInt(n);
Tx.utils.toVarIntSize(n);
Tx.utils.reverseHex(hex);
Tx.utils.bytesToHex(bytes);
Tx.utils.hexToBytes(hex);
Tx.utils.strToHex(str);

// Low-level helpers
Tx.createRaw(txInfoMinimal);
Tx.createHashable(txInfo, inputIndex);
Tx.createSigned(txInfoSigned);
Tx.hashPartial(txHex);

// Deprecated
Tx.createLegacyTx(coins, outputs, changeOutput);
Tx.utils.hexToU8 // Tx.utils.hexToBytes;
Tx.utils.u8ToHex // Tx.utils.bytesToHex;

// Not API-locked, May change
Tx.utils.sign(privateKey, txHashBytes);
Tx.utils.toPublicKey(privKeyBytes);
Tx.utils.addrToPubKeyHash(addr);
```

```js
Expand All @@ -280,14 +317,16 @@ Tx.OUTPUT_SIZE // 34
Tx.create({ sign, getPrivateKey });

/**
* Estimates the min, mid, and max sizes of (fees for) a transaction.
* Estimates the min, mid, and max sizes of (fees for) a transaction (including memos).
* (if in doubt, start with the mid - its's 75% likely to match the signed size)
* (non-deterministic because signed size is based on the variable-size signature)
*/
Tx.appraise({ inputs, outputs });
// { min: 191, mid: 192, max: 193 }

/**
* Deprecated. Use `dashTx.legacy.draftSingleOutput()` instead.
*
* Magic. The old kind.
*
* Calculates totals, fees and output change, AND selects
Expand All @@ -300,15 +339,52 @@ Tx.createLegacyTx(coins, outputs, changeOutput);
// { version, inputs, outputs, changeIndex, locktime}
// let change = txInfo.outputs[txInfo.changeIndex];

/**
* Creates the variety of required hashable transactions
* (one per each input), signs them, and then constructs
* a broadcastable transaction.
*
* Note: your inputs and outputs will be sorted according to
* "Lexicographical Indexing of Transaction Inputs and Outputs"
*/
tx.hashAndSignAll(txInfo);
{
/**
* Creates the variety of required hashable transactions
* (one per each input), signs them, and then constructs
* a broadcastable transaction.
*
* Note: your inputs and outputs should be sorted according to
* "Lexicographical Indexing of Transaction Inputs and Outputs":
*
* txInfo.inputs.sort(Tx.sortInputs)
* txInfo.outputs.sort(Tx.sortOutputs)
*/
tx.hashAndSignAll(txInfo);

/**
* Drafts a multiple-input, single-output transaction.
* (each `input.address` and the `output.address` may be set before or after)
*
* Sending Modes:
* - "Automatic Coin Selection": use `utxos`, NOT `inputs`
* - "Coin Control" : use `inputs`, NOT `utxos`
* - "Full Balance Transfer" : use `inputs`, NOT `utxos` and
* set `output.satoshis = null`
*
* Change:
* - `txDraft.change` is a reference to the relevant `txDraft.outputs[i]`
* - `txDraft.change.address` MUST be set before signing the transaction
*
* BIP-69 Secure Sorting must be done AFTER setting each `address`
* - `Tx.sortInputs(txDraft.inputs)`
* - `Tx.sortOutputs(txDraft.outputs)`
*/
let txDraft = tx.legacy.draftSingleOutput({ utxos, inputs, output });

/**
* Signs the draft with variations to find a signature whose fee will
* closely match `txDraft.feeTarget`.
*
* - `inputs` and `outputs` MUST be sorted BEFORE calling this
* - `txDraft.feeTarget` should be at least 10% likely
* - the likelihood of `fees.min` is `1 / Math.pow(4, inputs.length)`
* - the likelihood of `fees.mid` is 75%
* - the likelihood of `fees.max` is 100%
*/
let txSummary = tx.legacy.finalizePresorted(txDraft, keys);
}

/**
* Creates an "null" transaction with minimal information.
Expand Down
Loading
Loading