diff --git a/package-lock.json b/package-lock.json index 93795eb..8f43df4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitcoinerlab/descriptors", - "version": "2.0.1", + "version": "2.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@bitcoinerlab/descriptors", - "version": "2.0.1", + "version": "2.0.2", "license": "MIT", "dependencies": { "@bitcoinerlab/miniscript": "^1.2.1", diff --git a/package.json b/package.json index 0933382..bb3a28d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@bitcoinerlab/descriptors", "description": "This library parses and creates Bitcoin Miniscript Descriptors and generates Partially Signed Bitcoin Transactions (PSBTs). It provides PSBT finalizers and signers for single-signature, BIP32 and Hardware Wallets.", "homepage": "https://github.com/bitcoinerlab/descriptors", - "version": "2.0.1", + "version": "2.0.2", "author": "Jose-Luis Landabaso", "license": "MIT", "repository": { diff --git a/src/descriptors.ts b/src/descriptors.ts index c362c18..e6a9161 100644 --- a/src/descriptors.ts +++ b/src/descriptors.ts @@ -704,7 +704,8 @@ export function DescriptorsFactory(ecc: TinySecp256k1Interface) { //signatures don't matter const fakeSignatures = signersPubKeys.map(pubkey => ({ pubkey, - signature: Buffer.alloc(64, 0) + // https://transactionfee.info/charts/bitcoin-script-ecdsa-length/ + signature: Buffer.alloc(72, 0) })); const { nLockTime, nSequence } = satisfyMiniscript({ expandedMiniscript, @@ -715,6 +716,50 @@ export function DescriptorsFactory(ecc: TinySecp256k1Interface) { return { nLockTime, nSequence }; } else return undefined; } + + /** + * Retrieves the byte length of the script satisfaction for a Miniscript-based + * descriptor, using only the expression, signers' public keys, and preimages + * provided in the constructor. + * + * Useful in scenarios like coin selection algorithms for transaction creation, + * where signatures are not yet available. Since signatures are still to be + * computed, the function assigns a standard length of 72 bytes for each + * signature. However, note that this may not always be completely accurate, + * as approximately 50% of signatures are 71 bytes in length + * (source: https://transactionfee.info/charts/bitcoin-script-ecdsa-length/). + * The function returns the byte length for a worst-case scenario. + * + * @returns The byte length of the compiled script satisfaction, or `undefined` + * if this was not a miniscript-based descriptor. + */ + getScriptSatisfactionSize(): number | undefined { + const miniscript = this.#miniscript; + const preimages = this.#preimages; + const expandedMiniscript = this.#expandedMiniscript; + const expansionMap = this.#expansionMap; + const signersPubKeys = this.#signersPubKeys; + //Create a method. solvePreimages to solve them. + if (miniscript) { + if (expandedMiniscript === undefined || expansionMap === undefined) + throw new Error( + `Error: cannot get script satisfactions from not expanded miniscript ${miniscript}` + ); + //We create some fakeSignatures since we may not have them yet. + const fakeSignatures = signersPubKeys.map(pubkey => ({ + pubkey, + // https://transactionfee.info/charts/bitcoin-script-ecdsa-length/ + signature: Buffer.alloc(72, 0) + })); + const { scriptSatisfaction } = satisfyMiniscript({ + expandedMiniscript, + expansionMap, + signatures: fakeSignatures, + preimages + }); + return scriptSatisfaction.length; + } else return undefined; + } /** * Creates and returns an instance of bitcoinjs-lib * [`Payment`](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/payments/index.ts)'s interface with the `scriptPubKey` of this `Output`.