@kukks/bitcoin-descriptors 3.1.0 → 3.2.2

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
@@ -6,12 +6,13 @@ This library parses and creates Bitcoin Miniscript Descriptors and generates Par
6
6
 
7
7
  ## Differences from upstream
8
8
 
9
- This fork migrates the entire library from `bitcoinjs-lib` to the [`@scure/btc-signer`](https://github.com/nicolo-ribaudo/scure-btc-signer) and [`@noble`](https://github.com/nicolo-ribaudo/noble-curves) ecosystem. Key differences:
9
+ This fork migrates the entire library from `bitcoinjs-lib` to the [`@scure/btc-signer`](https://github.com/paulmillr/scure-btc-signer) and [`@noble`](https://github.com/paulmillr/noble-curves) ecosystem. Key differences:
10
10
 
11
11
  - **`Buffer` replaced with `Uint8Array`** across the entire public API. All methods that previously returned or accepted `Buffer` now use `Uint8Array`. This is a **breaking change**.
12
- - **Dependencies replaced**: `bitcoinjs-lib`, `ecpair`, `bip32`, `tiny-secp256k1` are no longer used. The library now depends on `@scure/btc-signer`, `@scure/bip32`, `@noble/curves`, `@noble/hashes`, and `@scure/base`.
12
+ - **Dependencies replaced**: `bitcoinjs-lib`, `ecpair`, `bip32`, `tiny-secp256k1` are no longer used. The library now depends on [`@scure/btc-signer`](https://github.com/paulmillr/scure-btc-signer), [`@scure/bip32`](https://github.com/paulmillr/scure-bip32), [`@noble/curves`](https://github.com/paulmillr/noble-curves), [`@noble/hashes`](https://github.com/paulmillr/noble-hashes), and [`@scure/base`](https://github.com/paulmillr/scure-base).
13
+ - **Built-in adapters**: Ships `nobleECPair` and `scureBIP32` adapters — no more boilerplate. `DescriptorsFactory()` works with zero arguments.
13
14
  - **PSBT class**: Uses `Transaction` from `@scure/btc-signer` instead of `Psbt` from `bitcoinjs-lib`.
14
- - **Ledger support removed**: The `ledger` module and all Ledger-related functions (`signLedger`, `keyExpressionLedger`, `pkhLedger`, `shWpkhLedger`, `wpkhLedger`, etc.) have been removed.
15
+ - **Ledger support removed**: The `ledger` module and all Ledger-related functions have been removed.
15
16
  - **`lodash.memoize` removed**: Replaced with an inline memoize helper.
16
17
  - **Package renamed** from `@bitcoinerlab/descriptors` to `@kukks/bitcoin-descriptors`.
17
18
 
@@ -19,18 +20,62 @@ This fork migrates the entire library from `bitcoinjs-lib` to the [`@scure/btc-s
19
20
 
20
21
  ```bash
21
22
  npm install @kukks/bitcoin-descriptors
23
+ ```
24
+
25
+ If you use **miniscript-based descriptors** (`sh(wsh(...))`, `sh(...)`, `wsh(...)` with miniscript expressions), install the optional peer dependency:
26
+
27
+ ```bash
22
28
  npm install @bitcoinerlab/miniscript
23
29
  ```
24
30
 
31
+ Standard descriptors (`pkh`, `wpkh`, `sh(wpkh(...))`, `tr`, `multi`, `sortedmulti`, `addr`) work without it.
32
+
33
+ ## Quick Start
34
+
35
+ ```typescript
36
+ import { DescriptorsFactory } from '@kukks/bitcoin-descriptors';
37
+
38
+ // Zero-config — uses built-in @noble/curves + @scure/bip32 adapters
39
+ const { Output, expand } = DescriptorsFactory();
40
+
41
+ const output = new Output({
42
+ descriptor: 'wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)'
43
+ });
44
+
45
+ console.log(output.getAddress());
46
+ ```
47
+
48
+ Or use the pre-built default factory:
49
+
50
+ ```typescript
51
+ import { defaultFactory } from '@kukks/bitcoin-descriptors';
52
+
53
+ const { Output } = defaultFactory;
54
+ ```
55
+
56
+ ### Bring your own adapters
57
+
58
+ If you need custom `ECPairAPI` or `BIP32API` implementations, you can still pass them explicitly:
59
+
60
+ ```typescript
61
+ import { DescriptorsFactory } from '@kukks/bitcoin-descriptors';
62
+ import type { ECPairAPI, BIP32API } from '@kukks/bitcoin-descriptors';
63
+
64
+ const { Output } = DescriptorsFactory({ ECPair: myECPair, BIP32: myBIP32 });
65
+ ```
66
+
67
+ The built-in adapters are also available as standalone exports:
68
+
69
+ ```typescript
70
+ import { nobleECPair, scureBIP32 } from '@kukks/bitcoin-descriptors';
71
+ ```
72
+
25
73
  ## Features
26
74
 
27
75
  - Parses and creates [Bitcoin Descriptors](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) (including those based on the [Miniscript language](https://bitcoinerlab.com/modules/miniscript)).
28
76
  - Generates Partially Signed Bitcoin Transactions (PSBTs).
29
77
  - Provides PSBT finalizers and signers for single-signature and BIP32 wallets.
30
-
31
- ## Concepts
32
-
33
- 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.
78
+ - Ships built-in adapters for `@noble/curves` and `@scure/bip32` — zero boilerplate needed.
34
79
 
35
80
  <details>
36
81
  <summary>Concepts</summary>
@@ -61,21 +106,15 @@ The library can be split into three main parts:
61
106
 
62
107
  ### Output class
63
108
 
64
- The `Output` class is dynamically created by providing `ECPair` and `BIP32` factory APIs:
65
-
66
- ```javascript
67
- import * as descriptors from '@kukks/bitcoin-descriptors';
68
- const { Output } = descriptors.DescriptorsFactory({ ECPair, BIP32 });
69
- ```
109
+ The `Output` class is created via `DescriptorsFactory`:
70
110
 
71
- Here, `ECPair` and `BIP32` are implementations of the `ECPairAPI` and `BIP32API` interfaces. These interfaces now use `Uint8Array` instead of `Buffer` for all binary data (public keys, private keys, signatures, etc.).
111
+ ```typescript
112
+ import { DescriptorsFactory } from '@kukks/bitcoin-descriptors';
72
113
 
73
- Once set up, you can obtain an instance for an output:
114
+ const { Output } = DescriptorsFactory();
74
115
 
75
- ```javascript
76
116
  const wpkhOutput = new Output({
77
- descriptor:
78
- 'wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)'
117
+ descriptor: 'wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)'
79
118
  });
80
119
  ```
81
120
 
@@ -83,33 +122,35 @@ For miniscript-based descriptors, the `signersPubKeys` parameter in the construc
83
122
 
84
123
  The `Output` class offers various helpful methods, including `getAddress()`, `getScriptPubKey()` (returns `Uint8Array`), `expand()`, `updatePsbtAsInput()` and `updatePsbtAsOutput()`.
85
124
 
86
- The library supports a wide range of descriptor types, including:
87
- - Pay-to-Public-Key-Hash (P2PKH): `pkh(KEY)`
88
- - Pay-to-Witness-Public-Key-Hash (P2WPKH): `wpkh(KEY)`
89
- - Pay-to-Script-Hash (P2SH): `sh(SCRIPT)`
90
- - Pay-to-Witness-Script-Hash (P2WSH): `wsh(SCRIPT)`
91
- - Pay-to-Taproot (P2TR) with single key: `tr(KEY)`
92
- - Address-based descriptors: `addr(ADDRESS)`, including Taproot addresses
125
+ The library supports a wide range of descriptor types, including:
126
+ - Pay-to-Public-Key-Hash (P2PKH): `pkh(KEY)`
127
+ - Pay-to-Witness-Public-Key-Hash (P2WPKH): `wpkh(KEY)`
128
+ - Pay-to-Script-Hash (P2SH): `sh(SCRIPT)`
129
+ - Pay-to-Witness-Script-Hash (P2WSH): `wsh(SCRIPT)`
130
+ - Pay-to-Taproot (P2TR) with single key: `tr(KEY)`
131
+ - Address-based descriptors: `addr(ADDRESS)`, including Taproot addresses
93
132
 
94
133
  #### Working with PSBTs
95
134
 
96
135
  This library uses `Transaction` from `@scure/btc-signer` as the PSBT class:
97
136
 
98
- ```javascript
137
+ ```typescript
99
138
  import { Transaction } from '@scure/btc-signer';
139
+
100
140
  const psbt = new Transaction({ allowUnknownOutputs: true, disableScriptCheck: true });
101
141
  const inputFinalizer = output.updatePsbtAsInput({ psbt, txHex, vout });
102
142
  ```
103
143
 
104
- Here, `psbt` refers to an instance of the [`@scure/btc-signer` Transaction class](https://github.com/nicolo-ribaudo/scure-btc-signer). 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.
144
+ Here, `psbt` refers to an instance of the [`@scure/btc-signer` Transaction class](https://github.com/paulmillr/scure-btc-signer). 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.
105
145
 
106
146
  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. Complete all necessary signing operations before calling `inputFinalizer()`.
107
147
 
108
148
  To add an output:
109
149
 
110
- ```javascript
111
- const recipientOutput =
112
- new Output({ descriptor: `addr(bc1qgw6xanldsz959z45y4dszehx4xkuzf7nfhya8x)` });
150
+ ```typescript
151
+ const recipientOutput = new Output({
152
+ descriptor: 'addr(bc1qgw6xanldsz959z45y4dszehx4xkuzf7nfhya8x)'
153
+ });
113
154
  recipientOutput.updatePsbtAsOutput({ psbt, value: 10000 });
114
155
  ```
115
156
 
@@ -117,15 +158,15 @@ recipientOutput.updatePsbtAsOutput({ psbt, value: 10000 });
117
158
 
118
159
  The `expand()` function parses Bitcoin descriptors into their component parts:
119
160
 
120
- ```javascript
161
+ ```typescript
121
162
  const output = new Output({ descriptor: "your-descriptor-here" });
122
163
  const result = output.expand();
123
164
  ```
124
165
 
125
166
  Or through the factory:
126
167
 
127
- ```javascript
128
- const { expand } = descriptors.DescriptorsFactory({ ECPair, BIP32 });
168
+ ```typescript
169
+ const { expand } = DescriptorsFactory();
129
170
  const result = expand({
130
171
  descriptor: "sh(wsh(andor(pk(0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2),older(8640),pk([d34db33f/49'/0'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/1/2/3/4/*))))"
131
172
  });
@@ -135,7 +176,7 @@ const result = expand({
135
176
 
136
177
  This library includes two signers: ECPair (single-signature) and BIP32.
137
178
 
138
- ```javascript
179
+ ```typescript
139
180
  import { signers } from '@kukks/bitcoin-descriptors';
140
181
 
141
182
  // For BIP32
@@ -149,13 +190,13 @@ signers.signECPair({ psbt, ecpair });
149
190
 
150
191
  1. For each unspent output, call `updatePsbtAsInput`:
151
192
 
152
- ```javascript
193
+ ```typescript
153
194
  const inputFinalizer = output.updatePsbtAsInput({ psbt, txHex, vout });
154
195
  ```
155
196
 
156
197
  2. After signing, finalize each input:
157
198
 
158
- ```javascript
199
+ ```typescript
159
200
  inputFinalizer({ psbt });
160
201
  ```
161
202
 
@@ -163,7 +204,7 @@ signers.signECPair({ psbt, ecpair });
163
204
 
164
205
  Helper functions for generating descriptor strings:
165
206
 
166
- ```javascript
207
+ ```typescript
167
208
  import { scriptExpressions, keyExpressionBIP32 } from '@kukks/bitcoin-descriptors';
168
209
  ```
169
210
 
@@ -171,7 +212,7 @@ The `scriptExpressions` module includes functions like `pkhBIP32()`, `shWpkhBIP3
171
212
 
172
213
  The `keyExpressionBIP32` function generates BIP32 key expression strings:
173
214
 
174
- ```javascript
215
+ ```typescript
175
216
  keyExpressionBIP32({
176
217
  masterNode, // BIP32Interface
177
218
  originPath, // e.g. "/44'/0'/0'"
@@ -181,6 +222,36 @@ keyExpressionBIP32({
181
222
  });
182
223
  ```
183
224
 
225
+ ## API Reference
226
+
227
+ ### Exports
228
+
229
+ | Export | Type | Description |
230
+ |--------|------|-------------|
231
+ | `DescriptorsFactory` | function | Creates `Output`, `expand`, `parseKeyExpression` — params optional (defaults to built-in adapters) |
232
+ | `defaultFactory` | object | Pre-built factory using built-in adapters |
233
+ | `nobleECPair` | `ECPairAPI` | Built-in ECPair adapter using `@noble/curves` secp256k1 |
234
+ | `scureBIP32` | `BIP32API` | Built-in BIP32 adapter using `@scure/bip32` |
235
+ | `signers` | namespace | `signECPair`, `signBIP32` and related signing functions |
236
+ | `scriptExpressions` | namespace | `pkhBIP32`, `shWpkhBIP32`, `wpkhBIP32`, etc. |
237
+ | `keyExpressionBIP32` | function | Generate BIP32 key expression strings |
238
+ | `networks` | object | `bitcoin`, `testnet`, `regtest` network definitions |
239
+ | `checksum` | function | Compute/validate descriptor checksums |
240
+
241
+ ### Types
242
+
243
+ | Type | Description |
244
+ |------|-------------|
245
+ | `ECPairAPI` | Factory interface for creating key pairs |
246
+ | `ECPairInterface` | Key pair instance with `sign`, `verify`, `publicKey`, etc. |
247
+ | `BIP32API` | Factory interface for creating HD keys (`fromSeed`, `fromBase58`, etc.) |
248
+ | `BIP32Interface` | HD key instance with `derivePath`, `derive`, `sign`, etc. |
249
+ | `OutputInstance` | Instance returned by `new Output(...)` |
250
+ | `Network` | Network configuration (`bitcoin`, `testnet`, `regtest`) |
251
+ | `PsbtLike` | PSBT interface (compatible with `@scure/btc-signer` Transaction) |
252
+ | `KeyInfo` | Parsed key expression data |
253
+ | `Expansion` | Parsed descriptor expansion data |
254
+
184
255
  ## Building from source
185
256
 
186
257
  ```bash
@@ -6,7 +6,23 @@ import { hash160 } from '@scure/btc-signer/utils.js';
6
6
  import { hex } from '@scure/base';
7
7
  import { parseKeyExpression } from './keyExpressions.js';
8
8
  import * as RE from './re.js';
9
- import { compileMiniscript, satisfier } from '@bitcoinerlab/miniscript';
9
+ import { createRequire } from 'module';
10
+ // Lazy-load @bitcoinerlab/miniscript (optional peer dependency).
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ let _miniscriptLib;
13
+ function getMiniscriptLib() {
14
+ if (!_miniscriptLib) {
15
+ try {
16
+ const require = createRequire(import.meta.url);
17
+ _miniscriptLib = require('@bitcoinerlab/miniscript');
18
+ }
19
+ catch {
20
+ throw new Error('@bitcoinerlab/miniscript is required for miniscript descriptors. ' +
21
+ 'Install it: npm install @bitcoinerlab/miniscript');
22
+ }
23
+ }
24
+ return _miniscriptLib;
25
+ }
10
26
  /**
11
27
  * Expand a miniscript to a generalized form using variables instead of key
12
28
  * expressions. Variables will be of this form: @0, @1, ...
@@ -84,7 +100,7 @@ function substituteAsm({ expandedAsm, expansionMap }) {
84
100
  return asm;
85
101
  }
86
102
  export function miniscript2Script({ expandedMiniscript, expansionMap }) {
87
- const compiled = compileMiniscript(expandedMiniscript);
103
+ const compiled = getMiniscriptLib().compileMiniscript(expandedMiniscript);
88
104
  if (compiled.issane !== true) {
89
105
  throw new Error(`Error: Miniscript ${expandedMiniscript} is not sane`);
90
106
  }
@@ -128,7 +144,7 @@ export function satisfyMiniscript({ expandedMiniscript, expansionMap, signatures
128
144
  const expandedKnownsMap = { ...preimageMap, ...expandedSignatureMap };
129
145
  const knowns = Object.keys(expandedKnownsMap);
130
146
  //satisfier verifies again internally whether expandedKnownsMap with given knowns is sane
131
- const { nonMalleableSats } = satisfier(expandedMiniscript, { knowns });
147
+ const { nonMalleableSats } = getMiniscriptLib().satisfier(expandedMiniscript, { knowns });
132
148
  if (!Array.isArray(nonMalleableSats) || !nonMalleableSats[0])
133
149
  throw new Error(`Error: unresolvable miniscript ${expandedMiniscript}`);
134
150
  let sat;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@kukks/bitcoin-descriptors",
3
3
  "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.",
4
4
  "homepage": "https://github.com/Kukks/descriptors",
5
- "version": "3.1.0",
5
+ "version": "3.2.2",
6
6
  "author": "Jose-Luis Landabaso",
7
7
  "license": "MIT",
8
8
  "repository": {
@@ -51,14 +51,22 @@
51
51
  ],
52
52
  "devDependencies": {
53
53
  "@bitcoinerlab/configs": "^2.0.0",
54
+ "@bitcoinerlab/miniscript": "^1.4.3",
54
55
  "bip39": "^3.0.4",
55
56
  "bip65": "^1.0.3",
56
57
  "bip68": "^1.0.4",
57
58
  "regtest-client": "^0.2.1",
58
59
  "yargs": "^17.7.2"
59
60
  },
61
+ "peerDependencies": {
62
+ "@bitcoinerlab/miniscript": "^1.4.3"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "@bitcoinerlab/miniscript": {
66
+ "optional": true
67
+ }
68
+ },
60
69
  "dependencies": {
61
- "@bitcoinerlab/miniscript": "^1.4.3",
62
70
  "@noble/curves": "^2.0.1",
63
71
  "@noble/hashes": "^2.0.1",
64
72
  "@scure/base": "^2.0.0",