@bitcoinerlab/descriptors 1.1.1 → 2.0.1
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 +138 -145
- package/dist/checksum.d.ts +4 -0
- package/dist/checksum.js +4 -0
- package/dist/descriptors.d.ts +415 -37
- package/dist/descriptors.js +283 -130
- package/dist/index.d.ts +25 -5
- package/dist/index.js +12 -2
- package/dist/keyExpressions.d.ts +54 -5
- package/dist/keyExpressions.js +30 -2
- package/dist/ledger.d.ts +89 -12
- package/dist/ledger.js +241 -28
- package/dist/scriptExpressions.d.ts +73 -28
- package/dist/scriptExpressions.js +28 -4
- package/dist/signers.d.ts +34 -1
- package/dist/signers.js +102 -41
- package/dist/types.d.ts +71 -39
- package/package.json +3 -2
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
|
|
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 `
|
|
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
|
-
###
|
|
57
|
+
### Output class
|
|
56
58
|
|
|
57
|
-
The
|
|
59
|
+
The `Output` class is dynamically created by providing a cryptographic secp256k1 engine as shown below:
|
|
58
60
|
|
|
59
61
|
```javascript
|
|
60
|
-
import * as
|
|
62
|
+
import * as ecc from '@bitcoinerlab/secp256k1';
|
|
61
63
|
import * as descriptors from '@bitcoinerlab/descriptors';
|
|
62
|
-
const {
|
|
64
|
+
const { Output } = descriptors.DescriptorsFactory(ecc);
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
|
|
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
|
|
69
|
-
|
|
70
|
+
const wpkhOutput = new Output({
|
|
71
|
+
descriptor:
|
|
70
72
|
'wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)'
|
|
71
73
|
});
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
});
|
|
85
|
+
import { Psbt } from 'bitcoinjs-lib';
|
|
86
|
+
const psbt = new Psbt();
|
|
87
|
+
const inputFinalizer = output.updatePsbtAsInput({ psbt, txHex, vout });
|
|
110
88
|
```
|
|
111
89
|
|
|
112
|
-
|
|
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 `
|
|
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
|
-
|
|
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
|
|
97
|
+
const recipientOutput =
|
|
98
|
+
new Output({ descriptor: `addr(bc1qgw6xanldsz959z45y4dszehx4xkuzf7nfhya8x)` });
|
|
99
|
+
recipientOutput.updatePsbtAsOutput({ psbt, value: 10000 });
|
|
120
100
|
```
|
|
121
101
|
|
|
122
|
-
|
|
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
|
-
|
|
104
|
+
#### Parsing Descriptors with `expand()`
|
|
125
105
|
|
|
126
|
-
|
|
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
|
-
|
|
108
|
+
##### 1. Directly from an `Output` Instance
|
|
131
109
|
|
|
132
|
-
|
|
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
|
-
|
|
112
|
+
```javascript
|
|
113
|
+
const output = new Output({ descriptor: "your-descriptor-here" });
|
|
114
|
+
const result = output.expand();
|
|
115
|
+
```
|
|
135
116
|
|
|
136
|
-
|
|
117
|
+
##### 2. Through the `DescriptorsFactory`
|
|
118
|
+
|
|
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(
|
|
122
|
+
const { expand } = descriptors.DescriptorsFactory(ecc);
|
|
140
123
|
const result = expand({
|
|
141
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
###
|
|
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).
|
|
193
156
|
|
|
194
|
-
|
|
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`
|
|
181
|
+
|
|
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`
|
|
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; //
|
|
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, `
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
|
|
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)
|
|
330
|
-
- [
|
|
331
|
-
- [
|
|
332
|
-
-
|
|
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.
|
package/dist/checksum.d.ts
CHANGED
|
@@ -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;
|