Skip to content

Commit 493a822

Browse files
authored
Merge pull request #28 from bitcoinerlab/coinselect
Add getScriptSatisfactionSize function and fix signature size in getTimeConstraints
2 parents 1641233 + 899a820 commit 493a822

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@bitcoinerlab/descriptors",
33
"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.",
44
"homepage": "https://github.com/bitcoinerlab/descriptors",
5-
"version": "2.0.1",
5+
"version": "2.0.2",
66
"author": "Jose-Luis Landabaso",
77
"license": "MIT",
88
"repository": {

src/descriptors.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,8 @@ export function DescriptorsFactory(ecc: TinySecp256k1Interface) {
704704
//signatures don't matter
705705
const fakeSignatures = signersPubKeys.map(pubkey => ({
706706
pubkey,
707-
signature: Buffer.alloc(64, 0)
707+
// https://transactionfee.info/charts/bitcoin-script-ecdsa-length/
708+
signature: Buffer.alloc(72, 0)
708709
}));
709710
const { nLockTime, nSequence } = satisfyMiniscript({
710711
expandedMiniscript,
@@ -715,6 +716,50 @@ export function DescriptorsFactory(ecc: TinySecp256k1Interface) {
715716
return { nLockTime, nSequence };
716717
} else return undefined;
717718
}
719+
720+
/**
721+
* Retrieves the byte length of the script satisfaction for a Miniscript-based
722+
* descriptor, using only the expression, signers' public keys, and preimages
723+
* provided in the constructor.
724+
*
725+
* Useful in scenarios like coin selection algorithms for transaction creation,
726+
* where signatures are not yet available. Since signatures are still to be
727+
* computed, the function assigns a standard length of 72 bytes for each
728+
* signature. However, note that this may not always be completely accurate,
729+
* as approximately 50% of signatures are 71 bytes in length
730+
* (source: https://transactionfee.info/charts/bitcoin-script-ecdsa-length/).
731+
* The function returns the byte length for a worst-case scenario.
732+
*
733+
* @returns The byte length of the compiled script satisfaction, or `undefined`
734+
* if this was not a miniscript-based descriptor.
735+
*/
736+
getScriptSatisfactionSize(): number | undefined {
737+
const miniscript = this.#miniscript;
738+
const preimages = this.#preimages;
739+
const expandedMiniscript = this.#expandedMiniscript;
740+
const expansionMap = this.#expansionMap;
741+
const signersPubKeys = this.#signersPubKeys;
742+
//Create a method. solvePreimages to solve them.
743+
if (miniscript) {
744+
if (expandedMiniscript === undefined || expansionMap === undefined)
745+
throw new Error(
746+
`Error: cannot get script satisfactions from not expanded miniscript ${miniscript}`
747+
);
748+
//We create some fakeSignatures since we may not have them yet.
749+
const fakeSignatures = signersPubKeys.map(pubkey => ({
750+
pubkey,
751+
// https://transactionfee.info/charts/bitcoin-script-ecdsa-length/
752+
signature: Buffer.alloc(72, 0)
753+
}));
754+
const { scriptSatisfaction } = satisfyMiniscript({
755+
expandedMiniscript,
756+
expansionMap,
757+
signatures: fakeSignatures,
758+
preimages
759+
});
760+
return scriptSatisfaction.length;
761+
} else return undefined;
762+
}
718763
/**
719764
* Creates and returns an instance of bitcoinjs-lib
720765
* [`Payment`](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/payments/index.ts)'s interface with the `scriptPubKey` of this `Output`.

0 commit comments

Comments
 (0)