@bitcoinerlab/descriptors 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Bitcoin Descriptors Library
2
2
 
3
- This library is designed to parse and create Bitcoin Descriptors, including Miniscript, and generate Partially Signed Bitcoin Transactions (PSBTs). It also provides PSBT finalizers and signers for single-signature, BIP32, and Hardware Wallets.
3
+ This library is designed to parse and create Bitcoin Descriptors, including Miniscript, and generate Partially Signed Bitcoin Transactions (PSBTs). It also provides PSBT signers and finalizers for single-signature, BIP32, and Hardware Wallets.
4
4
 
5
5
  ## Features
6
6
 
@@ -10,7 +10,7 @@ This library is designed to parse and create Bitcoin Descriptors, including Mini
10
10
 
11
11
  ## Concepts
12
12
 
13
- This library has two main capabilities related to Bitcoin descriptors. Firstly, it can generate addresses and scriptPubKeys from descriptors. These addresses and scriptPubKeys can be used to receive funds from other parties. Secondly, the library is able to sign and spend unspent outputs described by those same descriptors. In order to do this, the descriptors must first be set into a PSBT.
13
+ This library has two main capabilities related to Bitcoin descriptors. Firstly, it can generate `addresses` and `scriptPubKeys` from descriptors. These `addresses` and `scriptPubKeys` can be used to receive funds from other parties. Secondly, the library is able to sign transactions and spend unspent outputs described by those same descriptors. In order to do this, the descriptors must first be set into a PSBT.
14
14
 
15
15
  If you are not familiar with _Bitcoin descriptors_ and _partially signed Bitcoin transactions (PSBTs)_, click on the section below to expand and read more about these concepts.
16
16
 
@@ -37,6 +37,8 @@ PSBTs come in handy when working with descriptors, especially when using scripts
37
37
 
38
38
  Before we dive in, it's worth mentioning that we have several comprehensive guides available covering different aspects of the library. These guides provide explanations and code examples in interactive playgrounds, allowing you to see the changes in the output as you modify the code. This hands-on learning experience, combined with clear explanations, helps you better understand how to use the library effectively. [Check out the available guides here](https://bitcoinerlab.com/guides).
39
39
 
40
+ Furthermore, we've meticulously documented our API. For an in-depth look into Classes, functions, and types, head over [here](https://bitcoinerlab.com/modules/descriptors/api).
41
+
40
42
  To use this library (and accompanying libraries), you can install them using:
41
43
 
42
44
  ```bash
@@ -47,163 +49,175 @@ npm install @bitcoinerlab/secp256k1
47
49
 
48
50
  The library can be split into four main parts:
49
51
 
50
- - The `Descriptor` class, which is the core component that parses descriptors and can be used to finalize partially signed Bitcoin transactions (PSBTs).
51
- - `keyExpressions` and `scriptExpressions`, which provide functions to create descriptor and key expressions (strings) from structured data, making it easier to work with complex descriptors.
52
+ - The `Output` class is the central component for managing descriptors. It facilitates the creation of outputs to receive funds and enables the signing and finalization of PSBTs (Partially Signed Bitcoin Transactions) for spending UTXOs (Unspent Transaction Outputs).
52
53
  - PSBT signers and finalizers, which are used to manage the signing and finalization of PSBTs.
54
+ - `keyExpressions` and `scriptExpressions`, which provide functions to create key and standard descriptor expressions (strings) from structured data.
53
55
  - Hardware wallet integration, which provides support for interacting with hardware wallets such as Ledger devices.
54
56
 
55
- ### Descriptor class
57
+ ### Output class
56
58
 
57
- The Descriptor class is created dynamically by providing a cryptographic secp256k1 engine as shown below:
59
+ The `Output` class is dynamically created by providing a cryptographic secp256k1 engine as shown below:
58
60
 
59
61
  ```javascript
60
- import * as secp256k1 from '@bitcoinerlab/secp256k1';
62
+ import * as ecc from '@bitcoinerlab/secp256k1';
61
63
  import * as descriptors from '@bitcoinerlab/descriptors';
62
- const { Descriptor } = descriptors.DescriptorsFactory(secp256k1);
64
+ const { Output } = descriptors.DescriptorsFactory(ecc);
63
65
  ```
64
66
 
65
- After that, you can obtain an instance for a descriptor expression, such as a wpkh expression, like this:
67
+ Once set up, you can obtain an instance for an output, described by a descriptor such as a `wpkh`, as follows:
66
68
 
67
69
  ```javascript
68
- const wpkhDescriptor = new Descriptor({
69
- expression:
70
+ const wpkhOutput = new Output({
71
+ descriptor:
70
72
  'wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)'
71
73
  });
72
74
  ```
73
75
 
74
- Here are the parameters that can be used to create a `new Descriptor`:
76
+ Refer to [the API](https://bitcoinerlab.com/modules/descriptors/api/classes/_Internal_.Output.html#constructor) for the complete list of parameters in the constructor.
77
+
78
+ The `Output` class [offers various helpful methods](https://bitcoinerlab.com/modules/descriptors/api/classes/_Internal_.Output.html), including `getAddress()`, which returns the address associated with the descriptor, `getScriptPubKey()`, which returns the `scriptPubKey` for the descriptor, `expand()`, which decomposes a descriptor into its elemental parts, `updatePsbtAsInput()` and `updatePsbtAsOutput()`.
79
+
80
+ The `updatePsbtAsInput()` method is an essential part of the library, responsible for adding an input to the PSBT corresponding to the UTXO described by the descriptor. Additionally, when the descriptor expresses an absolute time-spending condition, such as "This UTXO can only be spent after block N," `updatePsbtAsInput()` adds timelock information to the PSBT.
81
+
82
+ To call `updatePsbtAsInput()`, use the following syntax:
75
83
 
76
84
  ```javascript
77
- constructor({
78
- expression, // The descriptor string in ASCII format. It may include a "*"
79
- // to denote an arbitrary index.
80
- index, // The descriptor's index in the case of a range descriptor
81
- // (must be an integer >= 0).
82
- checksumRequired = false // Optional flag indicating if the descriptor is
83
- // required to include a checksum. Defaults to false.
84
- allowMiniscriptInP2SH = false, // Flag indicating if this instance can parse
85
- // and generate script satisfactions for
86
- // sh(miniscript) top-level expressions of
87
- // miniscripts. This is not recommended.
88
- network = networks.bitcoin, // One of bitcoinjs-lib `networks`
89
- // (https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/networks.js)
90
- // or another one with the same interface.
91
- preimages = [], // An array of preimages of type `Preimage`: `Preimage[]`.
92
- // This info is necessary to finalize Psbts.
93
- signersPubKeys // (Optional): An array of the public keys used for signing
94
- // the transaction when spending the output associated with
95
- // this descriptor. This parameter is only used if the
96
- // descriptor object is being used to finalize a transaction.
97
- // It is necessary to specify the spending path when working
98
- // with miniscript-based expressions that have multiple
99
- // spending paths. Set this parameter to an array containing
100
- // the public keys involved in the desired spending path.
101
- // Leave it `undefined` if you only need to generate the
102
- // `scriptPubKey` or `address` for a descriptor, or if all
103
- // the public keys involved in the descriptor will sign the
104
- // transaction. In the latter case, the satisfier will
105
- // automatically choose the most optimal spending path in terms
106
- // of tx size (if more than one path is available).
107
- // For more details on using this parameter, refer to this
108
- // Stack Exchange answer: https://bitcoin.stackexchange.com/a/118036/89665
109
- }: DescriptorInfo);
85
+ import { Psbt } from 'bitcoinjs-lib';
86
+ const psbt = new Psbt();
87
+ const inputFinalizer = output.updatePsbtAsInput({ psbt, txHex, vout });
110
88
  ```
111
89
 
112
- The `Descriptor` class offers various helpful methods, including `getAddress()`, which returns the address associated with the descriptor, `getScriptPubKey()`, which returns the scriptPubKey for the descriptor, `expand()`, which decomposes a descriptor into its elemental parts, `updatePsbt()` and `finalizePsbt()`.
90
+ Here, `psbt` refers to an instance of the [bitcoinjs-lib Psbt class](https://github.com/bitcoinjs/bitcoinjs-lib). The parameter `txHex` denotes a hex string that serializes the previous transaction containing this output. Meanwhile, `vout` is an integer that marks the position of the output within that transaction.
113
91
 
114
- The `updatePsbt()` method is an essential part of the library, responsible for adding an input to the PSBT corresponding to the UTXO (unspent transaction output) described by the descriptor. Additionally, when the descriptor expresses an absolute time-spending condition, such as "This UTXO can only be spent after block N," `updatePsbt()` adds timelock information to the PSBT.
92
+ The method returns the `inputFinalizer()` function. This finalizer function completes a PSBT input by adding the unlocking script (`scriptWitness` or `scriptSig`) that satisfies the previous output's spending conditions. Bear in mind that both `scriptSig` and `scriptWitness` incorporate signatures. As such, you should complete all necessary signing operations before calling `inputFinalizer()`. Detailed [explanations on the `inputFinalizer` method](#signers-and-finalizers-finalize-psbt-input) can be found in the Signers and Finalizers section.
115
93
 
116
- To call `updatePsbt()`, use the following syntax:
94
+ Conversely, `updatePsbtAsOutput` allows you to add an output to a PSBT. For instance, to configure a `psbt` that sends `10,000` sats to the SegWit address `bc1qgw6xanldsz959z45y4dszehx4xkuzf7nfhya8x`:
117
95
 
118
96
  ```javascript
119
- const inputIndex = descriptor.updatePsbt({ psbt, txHex, vout });
97
+ const recipientOutput =
98
+ new Output({ descriptor: `addr(bc1qgw6xanldsz959z45y4dszehx4xkuzf7nfhya8x)` });
99
+ recipientOutput.updatePsbtAsOutput({ psbt, value: 10000 });
120
100
  ```
121
101
 
122
- Here, `psbt` is an instance of a [bitconjs-lib Psbt class](https://github.com/bitcoinjs/bitcoinjs-lib), `txHex` is the hex string that serializes the previous transaction, and `vout` is an integer corresponding to the output index of the descriptor in the previous transaction. The method returns a number that corresponds to the input number that this descriptor will take in the `psbt`.
102
+ For further information on using the `Output` class, refer to the [comprehensive guides](https://bitcoinerlab.com/guides) that offer explanations and playgrounds to help learn the module. For specific details on the methods, refer directly to [the API](https://bitcoinerlab.com/modules/descriptors/api/classes/_Internal_.Output.html). For insights into the constructor, especially regarding the `signersPubKeys` parameter, as well as the usage of `updatePsbtAsInput`, `getAddress`, and `getScriptPubKey`, see this detailed [Stack Exchange answer](https://bitcoin.stackexchange.com/a/118036/89665).
123
103
 
124
- The `finalizePsbt()` method is the final step in adding the unlocking script (scriptWitness or scriptSig) that satisfies the spending condition to the transaction, effectively finalizing the Psbt. It should be called after all necessary signing operations have been completed. The syntax for calling this method is as follows:
104
+ #### Parsing Descriptors with `expand()`
125
105
 
126
- ```javascript
127
- descriptor.finalizePsbt({ index, psbt });
128
- ```
106
+ The `expand()` function serves as a mechanism to parse Bitcoin descriptors, unveiling a detailed breakdown of the descriptor's content. There are two main pathways to utilize this function:
129
107
 
130
- Here, `index` is the `inputIndex` obtained from the `updatePsbt()` method and `psbt` is an instance of a bitcoinjs-lib `Psbt` object.
108
+ ##### 1. Directly from an `Output` Instance
131
109
 
132
- For further information on using the Descriptor class, refer to the [comprehensive guides](https://bitcoinerlab.com/guides) that offer explanations and playgrounds to help learn the module. Additionally, a [Stack Exchange answer](https://bitcoin.stackexchange.com/a/118036/89665) provides a focused explanation on the constructor, specifically the `signersPubKeys` parameter, and the usage of `updatePsbt`, `finalizePsbt`, `getAddress`, and `getScriptPubKey`.
110
+ If you have already instantiated the `Output` class and created an output, you can directly use the [`expand()` method](https://bitcoinerlab.com/modules/descriptors/api/classes/_Internal_.Output.html#expand) on that `Output` instance. This method provides a straightforward way to parse descriptors without the need for additional utilities.
133
111
 
134
- #### Tip: Parsing descriptors without instantiating a class
112
+ ```javascript
113
+ const output = new Output({ descriptor: "your-descriptor-here" });
114
+ const result = output.expand();
115
+ ```
116
+
117
+ ##### 2. Through the `DescriptorsFactory`
135
118
 
136
- `DescriptorsFactory` provides a convenient `expand()` function that allows you to parse a descriptor expression without the need to instantiate the `Descriptor` class. This function can be used as follows:
119
+ If you haven't instantiated the `Output` class or simply prefer a standalone utility, the `DescriptorsFactory` provides an `expand()` function that allows you to directly parse the descriptor. For a comprehensive understanding of all the function arguments, refer to [this reference](https://bitcoinerlab.com/modules/descriptors/api/functions/DescriptorsFactory.html#DescriptorsFactory). Here's how you can use it:
137
120
 
138
121
  ```javascript
139
- const { expand } = descriptors.DescriptorsFactory(secp256k1);
122
+ const { expand } = descriptors.DescriptorsFactory(ecc);
140
123
  const result = expand({
141
- expression: 'sh(wsh(andor(pk(0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2),older(8640),pk([d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*))))',
142
- network: networks.testnet, // One of bitcoinjs-lib `networks`
143
- // (https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/networks.js)
144
- // or another one with the same interface.
145
- // Optional (defaults to bitcoin mainnet).
146
- allowMiniscriptInP2SH: true, // Optional flag to allow miniscript in P2SH.
147
- // Defaults to false.
148
- index, // Optional. The descriptor's index in the case of a range descriptor
149
- // (must be an integer >= 0). If not set for ranged descriptors, then
150
- // the function will return an expansionMap with ranged keyPaths and
151
- // won't compute Payment or scripts.
152
- checksumRequired = false // Optional flag indicating if the descriptor is
153
- // required to include a checksum. Defaults to false.
124
+ descriptor: "sh(wsh(andor(pk(0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2),older(8640),pk([d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*))))"
154
125
  });
155
126
  ```
156
127
 
157
- The `expand()` function returns an object with the following properties:
158
-
159
- - `payment: Payment | undefined`: The corresponding [bitcoinjs-lib Payment](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/payments/index.ts) for the provided expression, if applicable.
160
- - `expandedExpression: string | undefined`: The expanded descriptor expression.
161
- - `miniscript: string | undefined`: The extracted miniscript from the expression, if any.
162
- - `expansionMap: ExpansionMap | undefined`: A map of key expressions in the descriptor to their corresponding expanded keys.
163
- - `isSegwit: boolean | undefined`: A boolean indicating whether the descriptor represents a SegWit script.
164
- - `expandedMiniscript: string | undefined`: The expanded miniscript, if any.
165
- - `redeemScript: Buffer | undefined`: The redeem script for the descriptor, if applicable.
166
- - `witnessScript: Buffer | undefined`: The witness script for the descriptor, if applicable.
167
- - `isRanged: boolean` : Whether the expression represents a ranged descriptor.
168
- - `canonicalExpression` : This is the preferred or authoritative representation of the descriptor expression. It standardizes the descriptor by replacing indexes on wildcards and eliminating checksums.
128
+ Regardless of your chosen pathway, the outcome from `expand()` grants an insightful exploration into the descriptor's structure. For an exhaustive list of return properties, you can refer to [the API](https://bitcoinerlab.com/modules/descriptors/api/types/Expansion.html).
169
129
 
170
- For the example expression provided, the `expandedExpression` and a portion of the `expansionMap` would be as follows:
130
+ For illustration, given the descriptor above, the corresponding `expandedExpression` and a section of the `expansionMap` would appear as:
171
131
 
172
132
  ```javascript
173
- // expression: 'sh(wsh(andor(pk(0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2),older(8640),pk([d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*))))'
174
-
175
- expandedExpression: 'sh(wsh(andor(pk(@0),older(8640),pk(@1))))',
176
- expansionMap: {
177
- '@0': {
178
- keyExpression:
179
- '0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2'
180
- },
181
- '@1': {
182
- keyExpression:
183
- "[d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*",
184
- keyPath: '/1/2/3/4/*',
185
- originPath: "/49'/0'/0'",
186
- path: "m/49'/0'/0'/1/2/3/4/*",
187
- // Other relevant properties returned: `pubkey`, `ecpair` & `bip32` interfaces, `masterFingerprint`, etc.
188
- }
133
+ {
134
+ expandedExpression: 'sh(wsh(andor(pk(@0),older(8640),pk(@1))))',
135
+ expansionMap: {
136
+ '@0': {
137
+ keyExpression:
138
+ '0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2'
139
+ },
140
+ '@1': {
141
+ keyExpression:
142
+ "[d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*",
143
+ keyPath: '/1/2/3/4/*',
144
+ originPath: "/49'/0'/0'",
145
+ path: "m/49'/0'/0'/1/2/3/4/*",
146
+ // Other relevant properties returned: `pubkey`, `ecpair` & `bip32` interfaces, `masterFingerprint`, etc.
147
+ }
148
+ }
149
+ //...
189
150
  }
190
151
  ```
191
152
 
192
- ### keyExpressions and scriptExpressions
153
+ ### Signers and Finalizers
154
+
155
+ This library encompasses a PSBT finalizer as well as three distinct signers: ECPair for single-signatures, BIP32, and Ledger (specifically crafted for Ledger Wallet devices, with upcoming support for other devices planned).
156
+
157
+ To incorporate these functionalities, use the following import statement:
158
+
159
+ ```javascript
160
+ import { signers } from '@bitcoinerlab/descriptors';
161
+ ```
162
+
163
+ For signing operations, utilize the methods provided by the [`signers`](https://bitcoinerlab.com/modules/descriptors/api/modules/signers.html):
164
+
165
+ ```javascript
166
+ // For Ledger
167
+ await signers.signLedger({ psbt, ledgerManager });
168
+
169
+ // For BIP32 - https://github.com/bitcoinjs/bip32
170
+ signers.signBIP32({ psbt, masterNode });
171
+
172
+ // For ECPair - https://github.com/bitcoinjs/ecpair
173
+ signers.signECPair({ psbt, ecpair }); // Here, `ecpair` is an instance of the bitcoinjs-lib ECPairInterface
174
+ ```
175
+
176
+ Detailed information on Ledger integration will be provided in subsequent sections.
177
+
178
+ <a name="signers-and-finalizers-finalize-psbt-input"></a>
179
+
180
+ #### Finalizing the `psbt`
193
181
 
194
- This library also includes a set of function helpers that facilitate the generation of the `expression` parameter in the constructor of the `Descriptor` class. These helpers are located under the `scriptExpressions` module, which can be imported using the following statement:
182
+ When finalizing the `psbt`, the [`updatePsbtAsInput` method](https://bitcoinerlab.com/modules/descriptors/api/classes/_Internal_.Output.html#updatePsbtAsInput) plays a key role. When invoked, the `output.updatePsbtAsInput()` sets up the `psbt` by designating the output as an input and, if required, adjusts the transaction locktime. In addition, it returns a `inputFinalizer` function tailored for this specific `psbt` input.
183
+
184
+ ##### Procedure:
185
+
186
+ 1. For each unspent output from a previous transaction that you're referencing in a `psbt` as an input to be spent, call the `updatePsbtAsInput` method:
187
+
188
+ ```javascript
189
+ const inputFinalizer = output.updatePsbtAsInput({ psbt, txHex, vout });
190
+ ```
191
+
192
+ 2. Once you've completed the necessary signing operations on the `psbt`, use the returned finalizer function on each input:
193
+
194
+ ```javascript
195
+ inputFinalizer({ psbt });
196
+ ```
197
+
198
+ ##### Important Notes:
199
+
200
+ - The finalizer function returned from `updatePsbtAsInput` adds the necessary unlocking script (`scriptWitness` or `scriptSig`) that satisfies the `Output`'s spending conditions. Remember, both `scriptSig` and `scriptWitness` contain signatures. Ensure that all necessary signing operations are completed before finalizing.
201
+
202
+ - When using `updatePsbtAsInput`, the `txHex` parameter is crucial. For Segwit inputs, you can choose to pass `txId` and `value` instead of `txHex`. However, ensure the accuracy of the `value` to avoid potential fee attacks. When unsure, use `txHex` and skip `txId` and `value`.
203
+
204
+ - Hardware wallets require the [full `txHex` for Segwit](https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd).
205
+
206
+ ### Key Expressions and Script Expressions
207
+
208
+ This library also provides a series of function helpers designed to streamline the generation of `descriptor` strings. These strings can serve as input parameters in the `Output` class constructor. These helpers are nested within the `scriptExpressions` module. You can import them as illustrated below:
195
209
 
196
210
  ```javascript
197
211
  import { scriptExpressions } from '@bitcoinerlab/descriptors';
198
212
  ```
199
213
 
200
- `scriptExpressions` includes functions that generate script expressions for commonly used script expressions. Some of the available functions are `pkhBIP32()`, `shWpkhBIP32`, `wpkhBIP32`, `pkhLedger()`, `shWpkhLedger` and `wpkhLedger`.
214
+ Within the `scriptExpressions` module, there are functions designed to generate descriptors for commonly used scripts. Some examples include `pkhBIP32()`, `shWpkhBIP32()`, `wpkhBIP32()`, `pkhLedger()`, `shWpkhLedger()`, and `wpkhLedger()`. Refer to [the API](https://bitcoinerlab.com/modules/descriptors/api/modules/scriptExpressions.html#expand) for a detailed list and further information.
201
215
 
202
216
  When using BIP32-based descriptors, the following parameters are required for the `scriptExpressions` functions:
203
217
 
204
218
  ```javascript
205
219
  pkhBIP32(params: {
206
- masterNode: BIP32Interface; //A bitcoinjs-lib instance of a BIP32 object.
220
+ masterNode: BIP32Interface; //bitcoinjs-lib BIP32 - https://github.com/bitcoinjs/bip32
207
221
  network?: Network; //A bitcoinjs-lib network
208
222
  account: number;
209
223
  change?: number | undefined; //0 -> external (receive), 1 -> internal (change)
@@ -213,11 +227,11 @@ pkhBIP32(params: {
213
227
  })
214
228
  ```
215
229
 
216
- For Ledger, `ledgerClient` and `ledgerState` are used instead of `masterNode`. These will be explained later when we discuss Ledger integration.
230
+ For functions suffixed with *Ledger* (designed to generate descriptors for Ledger Hardware devices), replace `masterNode` with `ledgerManager`. Detailed information on Ledger integration will be provided in the following section.
217
231
 
218
- The `keyExpressions` category includes functions that generate string representations of key expressions for public keys. This is useful when working with miniscript-based descriptors.
232
+ The `keyExpressions` category includes functions that generate string representations of key expressions for public keys.
219
233
 
220
- This library includes the following `keyExpressions`: `keyExpressionBIP32` and `keyExpressionLedger`. They can be imported as follows:
234
+ This library includes the following `keyExpressions`: [`keyExpressionBIP32`](https://bitcoinerlab.com/modules/descriptors/api/functions/keyExpressionBIP32.html) and [`keyExpressionLedger`](https://bitcoinerlab.com/modules/descriptors/api/functions/keyExpressionLedger.html). They can be imported as follows:
221
235
 
222
236
  ```javascript
223
237
  import {
@@ -230,7 +244,7 @@ The parameters required for these functions are:
230
244
 
231
245
  ```javascript
232
246
  function keyExpressionBIP32({
233
- masterNode: BIP32Interface;
247
+ masterNode: BIP32Interface; //bitcoinjs-lib BIP32 - https://github.com/bitcoinjs/bip32
234
248
  originPath: string;
235
249
  change?: number | undefined; //0 -> external (receive), 1 -> internal (change)
236
250
  index?: number | undefined | '*';
@@ -239,35 +253,13 @@ function keyExpressionBIP32({
239
253
  });
240
254
  ```
241
255
 
242
- For Ledger, `ledgerClient` and `ledgerState` are used instead of `masterNode`.
243
-
244
- Both functions will generate strings that fully define BIP32 keys. For example: `[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*`. Read [Bitcoin Core descriptors documentation](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) to learn more about Key Expressions.
245
-
246
- ### Signers and Finalizers
247
-
248
- This library provides a Psbt finalizer and three types of signers: ECPair for single-signature, BIP32, and Ledger (for Ledger Wallet devices, with plans for other devices).
249
-
250
- To use them, import them as follows:
251
-
252
- ```javascript
253
- import { signers, finalizePsbt } from '@bitcoinerlab/descriptors';
254
- ```
255
-
256
- To sign with the signers:
256
+ For the `keyExpressionLedger` function, you'd use `ledgerManager` instead of `masterNode`.
257
257
 
258
- ```javascript
259
- await signers.signLedger({
260
- ledgerClient,
261
- ledgerState,
262
- psbt,
263
- descriptors: psbtInputDescriptors
264
- });
265
- //Here psbtInputDescriptors is an array of descriptors odered by their respective inputIndex in the psbt
266
- signers.signBIP32({ psbt, masterNode });
267
- signers.signECPair({ psbt, ecpair }); //Where ecpair is an instance of bitcoinjs-lib ECPairInterface
258
+ Both functions will generate strings that fully define BIP32 keys. For example:
259
+ ```text
260
+ [d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*
268
261
  ```
269
-
270
- To finalize the `psbt`, you can either call the method `finalizePsbtInput({ index, psbt })` on each descriptor, passing as arguments the `psbt` and its input `index`, or call the helper function: `finalizePsbt({psbt, descriptors })`. In the latter case, `descriptors` is an array of descriptors ordered by their respective input index in the `psbt`.
262
+ Read [Bitcoin Core descriptors documentation](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) to learn more about Key Expressions.
271
263
 
272
264
  ### Hardware Wallet Integration
273
265
 
@@ -301,6 +293,7 @@ await ledger.assertLedgerApp({
301
293
  });
302
294
 
303
295
  const ledgerClient = new AppClient(transport);
296
+ const ledgerManager = { ledgerClient, ledgerState: {}, ecc, network };
304
297
  ```
305
298
 
306
299
  Here, `transport` is an instance of a Transport object that allows communication with Ledger devices. You can use any of the transports [provided by Ledger](https://github.com/LedgerHQ/ledger-live#libs---libraries).
@@ -309,8 +302,7 @@ To register the policies of non-standard descriptors on the Ledger device, use t
309
302
 
310
303
  ```javascript
311
304
  await ledger.registerLedgerWallet({
312
- ledgerClient,
313
- ledgerState,
305
+ ledgerManager,
314
306
  descriptor: wshDescriptor,
315
307
  policyName: 'BitcoinerLab'
316
308
  });
@@ -318,7 +310,9 @@ await ledger.registerLedgerWallet({
318
310
 
319
311
  This code will auto-skip the policy registration process if it already exists. Please refer to [Ledger documentation](https://github.com/LedgerHQ/app-bitcoin-new/blob/develop/doc/wallet.md) to learn more about their Wallet Policies registration procedures.
320
312
 
321
- Finally, `ledgerState` is an object used to store information related to Ledger devices. Although Ledger devices themselves are stateless, this object can be used to store information such as xpubs, master fingerprints, and wallet policies. You can pass an initially empty object that will be updated with more information as it is used. The object can be serialized and stored for future use.
313
+ Finally, `ledgerManager.ledgerState` is an object used to store information related to Ledger devices. Although Ledger devices themselves are stateless, this object can be used to store information such as xpubs, master fingerprints, and wallet policies. You can pass an initially empty object that will be updated with more information as it is used. The object can be serialized and stored for future use.
314
+
315
+ The [API reference for the ledger module](https://bitcoinerlab.com/modules/descriptors/api/variables/ledger.html) provides a comprehensive list of functions related to the Ledger Hardware Wallet, along with detailed explanations of their parameters and behavior.
322
316
 
323
317
  <a name="documentation"></a>
324
318
 
@@ -326,10 +320,11 @@ Finally, `ledgerState` is an object used to store information related to Ledger
326
320
 
327
321
  For more information, refer to the following resources:
328
322
 
329
- - [Guides](https://bitcoinerlab.com/guides): Comprehensive explanations and playgrounds to help you learn how to use the module.
330
- - [Stack Exchange answer](https://bitcoin.stackexchange.com/a/118036/89665): Focused explanation on the constructor, specifically the `signersPubKeys` parameter, and the usage of `updatePsbt`, `finalizePsbt`, `getAddress`, and `getScriptPubKey`.
331
- - [Integration tests](https://github.com/bitcoinerlab/descriptors/tree/main/test/integration): Well-commented code examples showcasing the usage of all functions in the module.
332
- - API Documentation: Auto-generated documentation from the source code, providing detailed information about the library and its methods. To generate the API documentation locally, follow these commands:
323
+ - **[Guides](https://bitcoinerlab.com/guides)**: Comprehensive explanations and playgrounds to help you learn how to use the module.
324
+ - **[API](https://bitcoinerlab.com/modules/descriptors/api)**: Dive into the details of the Classes, functions, and types.
325
+ - **[Stack Exchange answer](https://bitcoin.stackexchange.com/a/118036/89665)**: Focused explanation on the constructor, specifically the `signersPubKeys` parameter, and the usage of `updatePsbtAsInput`, `getAddress`, and `getScriptPubKey`.
326
+ - **[Integration tests](https://github.com/bitcoinerlab/descriptors/tree/main/test/integration)**: Well-commented code examples showcasing the usage of all functions in the module.
327
+ - **Local Documentation**: Generate comprehensive API documentation from the source code:
333
328
 
334
329
  ```bash
335
330
  git clone https://github.com/bitcoinerlab/descriptors
@@ -340,8 +335,6 @@ For more information, refer to the following resources:
340
335
 
341
336
  The generated documentation will be available in the `docs/` directory. Open the `index.html` file to view the documentation.
342
337
 
343
- Please note that not all the functions have been fully documented yet. However, you can easily understand their usage by reading the source code or by checking the integration tests or playgrounds.
344
-
345
338
  ## Authors and Contributors
346
339
 
347
340
  The project was initially developed and is currently maintained by [Jose-Luis Landabaso](https://github.com/landabaso). Contributions and help from other developers are welcome.
@@ -1,2 +1,6 @@
1
1
  export declare const CHECKSUM_CHARSET: string;
2
+ /**
3
+ * Implements the Bitcoin descriptor's checksum algorithm described in
4
+ * {@link https://github.com/bitcoin/bitcoin/blob/master/src/script/descriptor.cpp}
5
+ */
2
6
  export declare const DescriptorChecksum: (span: string) => string;
package/dist/checksum.js CHANGED
@@ -20,6 +20,10 @@ const PolyMod = (c, val) => {
20
20
  return c;
21
21
  };
22
22
  exports.CHECKSUM_CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
23
+ /**
24
+ * Implements the Bitcoin descriptor's checksum algorithm described in
25
+ * {@link https://github.com/bitcoin/bitcoin/blob/master/src/script/descriptor.cpp}
26
+ */
23
27
  const DescriptorChecksum = (span) => {
24
28
  const INPUT_CHARSET = '0123456789()[],\'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#"\\ ';
25
29
  let c = 1n;