@kukks/bitcoin-descriptors 3.1.0 → 3.2.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 +109 -38
- package/dist/miniscript.js +19 -3
- package/package.json +10 -2
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/
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
111
|
+
```typescript
|
|
112
|
+
import { DescriptorsFactory } from '@kukks/bitcoin-descriptors';
|
|
72
113
|
|
|
73
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
```
|
|
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/
|
|
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
|
-
```
|
|
111
|
-
const recipientOutput =
|
|
112
|
-
|
|
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
|
-
```
|
|
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
|
-
```
|
|
128
|
-
const { expand } =
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
package/dist/miniscript.js
CHANGED
|
@@ -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 {
|
|
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
|
|
5
|
+
"version": "3.2.1",
|
|
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",
|