@bitcoinerlab/descriptors 0.2.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.draft.md +84 -0
- package/README.md +74 -0
- package/dist/checksum.d.ts +2 -0
- package/dist/checksum.js +54 -0
- package/dist/descriptors.d.ts +15 -0
- package/dist/descriptors.js +627 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +53 -0
- package/dist/keyExpressions.d.ts +29 -0
- package/dist/keyExpressions.js +196 -0
- package/dist/ledger.d.ts +94 -0
- package/dist/ledger.js +283 -0
- package/dist/miniscript.d.ts +109 -0
- package/dist/miniscript.js +239 -0
- package/dist/psbt.d.ts +38 -0
- package/dist/psbt.js +197 -0
- package/dist/re.d.ts +21 -0
- package/dist/re.js +65 -0
- package/dist/scriptExpressions.d.ts +58 -0
- package/dist/scriptExpressions.js +52 -0
- package/dist/signers.d.ts +37 -0
- package/dist/signers.js +112 -0
- package/dist/types.d.ts +94 -0
- package/dist/types.js +4 -0
- package/package.json +83 -0
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2023 Jose-Luis Landabaso - https://bitcoinerlab.com
|
|
3
|
+
// Distributed under the MIT software license
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
+
}) : function(o, v) {
|
|
18
|
+
o["default"] = v;
|
|
19
|
+
});
|
|
20
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
21
|
+
if (mod && mod.__esModule) return mod;
|
|
22
|
+
var result = {};
|
|
23
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
24
|
+
__setModuleDefault(result, mod);
|
|
25
|
+
return result;
|
|
26
|
+
};
|
|
27
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
28
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
29
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
30
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
31
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
32
|
+
};
|
|
33
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
34
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
35
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
36
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.DescriptorsFactory = void 0;
|
|
40
|
+
const bitcoinjs_lib_1 = require("bitcoinjs-lib");
|
|
41
|
+
const { p2sh, p2wpkh, p2pkh, p2pk, p2wsh, p2tr } = bitcoinjs_lib_1.payments;
|
|
42
|
+
const bip32_1 = require("bip32");
|
|
43
|
+
const ecpair_1 = require("ecpair");
|
|
44
|
+
const psbt_1 = require("./psbt");
|
|
45
|
+
const checksum_1 = require("./checksum");
|
|
46
|
+
const keyExpressions_1 = require("./keyExpressions");
|
|
47
|
+
const RE = __importStar(require("./re"));
|
|
48
|
+
const miniscript_1 = require("./miniscript");
|
|
49
|
+
//See "Resource limitations" https://bitcoin.sipa.be/miniscript/
|
|
50
|
+
//https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-September/017306.html
|
|
51
|
+
const MAX_SCRIPT_ELEMENT_SIZE = 520;
|
|
52
|
+
const MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
|
|
53
|
+
const MAX_OPS_PER_SCRIPT = 201;
|
|
54
|
+
function countNonPushOnlyOPs(script) {
|
|
55
|
+
const decompile = bitcoinjs_lib_1.script.decompile(script);
|
|
56
|
+
if (!decompile)
|
|
57
|
+
throw new Error(`Error: cound not decompile ${script}`);
|
|
58
|
+
return decompile.filter(op => op > bitcoinjs_lib_1.script.OPS['OP_16']).length;
|
|
59
|
+
}
|
|
60
|
+
/*
|
|
61
|
+
* Returns a bare descriptor without checksum and particularized for a certain
|
|
62
|
+
* index (if desc was a range descriptor)
|
|
63
|
+
*/
|
|
64
|
+
function evaluate({ expression, checksumRequired, index }) {
|
|
65
|
+
const mChecksum = expression.match(String.raw `(${RE.reChecksum})$`);
|
|
66
|
+
if (mChecksum === null && checksumRequired === true)
|
|
67
|
+
throw new Error(`Error: descriptor ${expression} has not checksum`);
|
|
68
|
+
//evaluatedExpression: a bare desc without checksum and particularized for a certain
|
|
69
|
+
//index (if desc was a range descriptor)
|
|
70
|
+
let evaluatedExpression = expression;
|
|
71
|
+
if (mChecksum !== null) {
|
|
72
|
+
const checksum = mChecksum[0].substring(1); //remove the leading #
|
|
73
|
+
evaluatedExpression = expression.substring(0, expression.length - mChecksum[0].length);
|
|
74
|
+
if (checksum !== (0, checksum_1.DescriptorChecksum)(evaluatedExpression)) {
|
|
75
|
+
throw new Error(`Error: invalid descriptor checksum for ${expression}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const mWildcard = evaluatedExpression.match(/\*/g);
|
|
79
|
+
if (mWildcard && mWildcard.length > 0) {
|
|
80
|
+
if (index === undefined)
|
|
81
|
+
throw new Error(`Error: index was not provided for ranged descriptor`);
|
|
82
|
+
if (!Number.isInteger(index) || index < 0)
|
|
83
|
+
throw new Error(`Error: invalid index ${index}`);
|
|
84
|
+
//From https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md
|
|
85
|
+
//To prevent a combinatorial explosion of the search space, if more than
|
|
86
|
+
//one of the multi() key arguments is a BIP32 wildcard path ending in /* or
|
|
87
|
+
//*', the multi() expression only matches multisig scripts with the ith
|
|
88
|
+
//child key from each wildcard path in lockstep, rather than scripts with
|
|
89
|
+
//any combination of child keys from each wildcard path.
|
|
90
|
+
//We extend this reasoning for musig for all cases
|
|
91
|
+
evaluatedExpression = evaluatedExpression.replaceAll('*', index.toString());
|
|
92
|
+
}
|
|
93
|
+
return evaluatedExpression;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Builds the functions needed to operate with descriptors using an external elliptic curve (ecc) library.
|
|
97
|
+
* @param {Object} ecc - an object containing elliptic curve operations, such as [tiny-secp256k1](https://github.com/bitcoinjs/tiny-secp256k1) or [@bitcoinerlab/secp256k1](https://github.com/bitcoinerlab/secp256k1).
|
|
98
|
+
* @returns {Object} an object containing functions, `parse` and `checksum`.
|
|
99
|
+
* @namespace
|
|
100
|
+
*/
|
|
101
|
+
function DescriptorsFactory(ecc) {
|
|
102
|
+
var _Descriptor_instances, _Descriptor_payment, _Descriptor_preimages, _Descriptor_signersPubKeys, _Descriptor_miniscript, _Descriptor_witnessScript, _Descriptor_redeemScript, _Descriptor_isSegwit, _Descriptor_expandedExpression, _Descriptor_expandedMiniscript, _Descriptor_expansionMap, _Descriptor_network, _Descriptor_getTimeConstraints, _Descriptor_assertPsbtInput;
|
|
103
|
+
const BIP32 = (0, bip32_1.BIP32Factory)(ecc);
|
|
104
|
+
const ECPair = (0, ecpair_1.ECPairFactory)(ecc);
|
|
105
|
+
const signatureValidator = (pubkey, msghash, signature) => ECPair.fromPublicKey(pubkey).verify(msghash, signature);
|
|
106
|
+
/*
|
|
107
|
+
* Takes a string key expression (xpub, xprv, pubkey or wif) and parses it
|
|
108
|
+
*/
|
|
109
|
+
const parseKeyExpression = ({ keyExpression, isSegwit, network = bitcoinjs_lib_1.networks.bitcoin }) => {
|
|
110
|
+
return (0, keyExpressions_1.parseKeyExpression)({
|
|
111
|
+
keyExpression,
|
|
112
|
+
network,
|
|
113
|
+
...(typeof isSegwit === 'boolean' ? { isSegwit } : {}),
|
|
114
|
+
ECPair,
|
|
115
|
+
BIP32
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Expand a miniscript to a generalized form using variables instead of key
|
|
120
|
+
* expressions. Variables will be of this form: @0, @1, ...
|
|
121
|
+
* This is done so that it can be compiled with compileMiniscript and
|
|
122
|
+
* satisfied with satisfier.
|
|
123
|
+
* Also compute pubkeys from descriptors to use them later.
|
|
124
|
+
*/
|
|
125
|
+
function expandMiniscript({ miniscript, isSegwit, network = bitcoinjs_lib_1.networks.bitcoin }) {
|
|
126
|
+
return (0, miniscript_1.expandMiniscript)({
|
|
127
|
+
miniscript,
|
|
128
|
+
isSegwit,
|
|
129
|
+
network,
|
|
130
|
+
BIP32,
|
|
131
|
+
ECPair
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
class Descriptor {
|
|
135
|
+
/**
|
|
136
|
+
* @param {Object} params
|
|
137
|
+
* @param {number} params.index - The descriptor's index in the case of a range descriptor (must be an interger >=0).
|
|
138
|
+
* @param {string} params.descriptor - The descriptor.
|
|
139
|
+
* @param {boolean} [params.checksumRequired=false] - A flag indicating whether the descriptor is required to include a checksum.
|
|
140
|
+
* @param {object} [params.network=networks.bitcoin] One of bitcoinjs-lib [`networks`](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/networks.js) (or another one following the same interface).
|
|
141
|
+
*
|
|
142
|
+
* @see {@link https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/payments/index.d.ts}
|
|
143
|
+
* @throws {Error} - when descriptor is invalid
|
|
144
|
+
*/
|
|
145
|
+
constructor({ expression, index, checksumRequired = false, allowMiniscriptInP2SH = false, network = bitcoinjs_lib_1.networks.bitcoin, preimages = [], signersPubKeys }) {
|
|
146
|
+
var _a, _b, _c, _d, _e, _f;
|
|
147
|
+
_Descriptor_instances.add(this);
|
|
148
|
+
_Descriptor_payment.set(this, void 0);
|
|
149
|
+
_Descriptor_preimages.set(this, []);
|
|
150
|
+
_Descriptor_signersPubKeys.set(this, void 0);
|
|
151
|
+
_Descriptor_miniscript.set(this, void 0);
|
|
152
|
+
_Descriptor_witnessScript.set(this, void 0);
|
|
153
|
+
_Descriptor_redeemScript.set(this, void 0);
|
|
154
|
+
//isSegwit true if witnesses are needed to the spend coins sent to this descriptor.
|
|
155
|
+
//may be unset because we may get addr(P2SH) which we don't know if they have segwit.
|
|
156
|
+
_Descriptor_isSegwit.set(this, void 0);
|
|
157
|
+
_Descriptor_expandedExpression.set(this, void 0);
|
|
158
|
+
_Descriptor_expandedMiniscript.set(this, void 0);
|
|
159
|
+
_Descriptor_expansionMap.set(this, void 0);
|
|
160
|
+
_Descriptor_network.set(this, void 0);
|
|
161
|
+
__classPrivateFieldSet(this, _Descriptor_network, network, "f");
|
|
162
|
+
__classPrivateFieldSet(this, _Descriptor_preimages, preimages, "f");
|
|
163
|
+
if (typeof expression !== 'string')
|
|
164
|
+
throw new Error(`Error: invalid descriptor type`);
|
|
165
|
+
//Verify and remove checksum (if exists) and
|
|
166
|
+
//particularize range descriptor for index (if desc is range descriptor)
|
|
167
|
+
const evaluatedExpression = evaluate({
|
|
168
|
+
expression,
|
|
169
|
+
...(index !== undefined ? { index } : {}),
|
|
170
|
+
checksumRequired
|
|
171
|
+
});
|
|
172
|
+
//addr(ADDR)
|
|
173
|
+
if (evaluatedExpression.match(RE.reAddrAnchored)) {
|
|
174
|
+
const matchedAddress = evaluatedExpression.match(RE.reAddrAnchored)?.[1]; //[1]-> whatever is found addr(->HERE<-)
|
|
175
|
+
if (!matchedAddress)
|
|
176
|
+
throw new Error(`Error: could not get an address in ${evaluatedExpression}`);
|
|
177
|
+
let output;
|
|
178
|
+
let payment;
|
|
179
|
+
try {
|
|
180
|
+
output = bitcoinjs_lib_1.address.toOutputScript(matchedAddress, network);
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
throw new Error(`Error: invalid address ${matchedAddress}`);
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
payment = p2pkh({ output, network });
|
|
187
|
+
}
|
|
188
|
+
catch (e) { }
|
|
189
|
+
try {
|
|
190
|
+
payment = p2sh({ output, network });
|
|
191
|
+
}
|
|
192
|
+
catch (e) { }
|
|
193
|
+
try {
|
|
194
|
+
payment = p2wpkh({ output, network });
|
|
195
|
+
}
|
|
196
|
+
catch (e) { }
|
|
197
|
+
try {
|
|
198
|
+
payment = p2wsh({ output, network });
|
|
199
|
+
}
|
|
200
|
+
catch (e) { }
|
|
201
|
+
try {
|
|
202
|
+
payment = p2tr({ output, network });
|
|
203
|
+
}
|
|
204
|
+
catch (e) { }
|
|
205
|
+
if (!payment) {
|
|
206
|
+
throw new Error(`Error: invalid address ${matchedAddress}`);
|
|
207
|
+
}
|
|
208
|
+
__classPrivateFieldSet(this, _Descriptor_payment, payment, "f");
|
|
209
|
+
}
|
|
210
|
+
//pk(KEY)
|
|
211
|
+
else if (evaluatedExpression.match(RE.rePkAnchored)) {
|
|
212
|
+
__classPrivateFieldSet(this, _Descriptor_isSegwit, false, "f");
|
|
213
|
+
const keyExpression = evaluatedExpression.match(RE.reKeyExp)?.[0];
|
|
214
|
+
if (!keyExpression)
|
|
215
|
+
throw new Error(`Error: keyExpression could not me extracted`);
|
|
216
|
+
if (evaluatedExpression !== `pk(${keyExpression})`)
|
|
217
|
+
throw new Error(`Error: invalid expression ${expression}`);
|
|
218
|
+
__classPrivateFieldSet(this, _Descriptor_expandedExpression, 'pk(@0)', "f");
|
|
219
|
+
__classPrivateFieldSet(this, _Descriptor_expansionMap, {
|
|
220
|
+
'@0': parseKeyExpression({
|
|
221
|
+
keyExpression,
|
|
222
|
+
network,
|
|
223
|
+
isSegwit: __classPrivateFieldGet(this, _Descriptor_isSegwit, "f")
|
|
224
|
+
})
|
|
225
|
+
}, "f");
|
|
226
|
+
const pubkey = __classPrivateFieldGet(this, _Descriptor_expansionMap, "f")['@0'].pubkey;
|
|
227
|
+
//Note there exists no address for p2pk, but we can still use the script
|
|
228
|
+
__classPrivateFieldSet(this, _Descriptor_payment, p2pk({ pubkey, network }), "f");
|
|
229
|
+
}
|
|
230
|
+
//pkh(KEY) - legacy
|
|
231
|
+
else if (evaluatedExpression.match(RE.rePkhAnchored)) {
|
|
232
|
+
__classPrivateFieldSet(this, _Descriptor_isSegwit, false, "f");
|
|
233
|
+
const keyExpression = evaluatedExpression.match(RE.reKeyExp)?.[0];
|
|
234
|
+
if (!keyExpression)
|
|
235
|
+
throw new Error(`Error: keyExpression could not me extracted`);
|
|
236
|
+
if (evaluatedExpression !== `pkh(${keyExpression})`)
|
|
237
|
+
throw new Error(`Error: invalid expression ${expression}`);
|
|
238
|
+
__classPrivateFieldSet(this, _Descriptor_expandedExpression, 'pkh(@0)', "f");
|
|
239
|
+
__classPrivateFieldSet(this, _Descriptor_expansionMap, {
|
|
240
|
+
'@0': parseKeyExpression({
|
|
241
|
+
keyExpression,
|
|
242
|
+
network,
|
|
243
|
+
isSegwit: __classPrivateFieldGet(this, _Descriptor_isSegwit, "f")
|
|
244
|
+
})
|
|
245
|
+
}, "f");
|
|
246
|
+
const pubkey = __classPrivateFieldGet(this, _Descriptor_expansionMap, "f")['@0'].pubkey;
|
|
247
|
+
__classPrivateFieldSet(this, _Descriptor_payment, p2pkh({ pubkey, network }), "f");
|
|
248
|
+
}
|
|
249
|
+
//sh(wpkh(KEY)) - nested segwit
|
|
250
|
+
else if (evaluatedExpression.match(RE.reShWpkhAnchored)) {
|
|
251
|
+
__classPrivateFieldSet(this, _Descriptor_isSegwit, true, "f");
|
|
252
|
+
const keyExpression = evaluatedExpression.match(RE.reKeyExp)?.[0];
|
|
253
|
+
if (!keyExpression)
|
|
254
|
+
throw new Error(`Error: keyExpression could not me extracted`);
|
|
255
|
+
if (evaluatedExpression !== `sh(wpkh(${keyExpression}))`)
|
|
256
|
+
throw new Error(`Error: invalid expression ${expression}`);
|
|
257
|
+
__classPrivateFieldSet(this, _Descriptor_expandedExpression, 'sh(wpkh(@0))', "f");
|
|
258
|
+
__classPrivateFieldSet(this, _Descriptor_expansionMap, {
|
|
259
|
+
'@0': parseKeyExpression({
|
|
260
|
+
keyExpression,
|
|
261
|
+
network,
|
|
262
|
+
isSegwit: __classPrivateFieldGet(this, _Descriptor_isSegwit, "f")
|
|
263
|
+
})
|
|
264
|
+
}, "f");
|
|
265
|
+
const pubkey = __classPrivateFieldGet(this, _Descriptor_expansionMap, "f")['@0'].pubkey;
|
|
266
|
+
__classPrivateFieldSet(this, _Descriptor_payment, p2sh({ redeem: p2wpkh({ pubkey, network }), network }), "f");
|
|
267
|
+
const redeemScript = __classPrivateFieldGet(this, _Descriptor_payment, "f").redeem?.output;
|
|
268
|
+
if (!redeemScript)
|
|
269
|
+
throw new Error(`Error: could not calculate redeemScript for ${expression}`);
|
|
270
|
+
__classPrivateFieldSet(this, _Descriptor_redeemScript, redeemScript, "f");
|
|
271
|
+
}
|
|
272
|
+
//wpkh(KEY) - native segwit
|
|
273
|
+
else if (evaluatedExpression.match(RE.reWpkhAnchored)) {
|
|
274
|
+
__classPrivateFieldSet(this, _Descriptor_isSegwit, true, "f");
|
|
275
|
+
const keyExpression = evaluatedExpression.match(RE.reKeyExp)?.[0];
|
|
276
|
+
if (!keyExpression)
|
|
277
|
+
throw new Error(`Error: keyExpression could not me extracted`);
|
|
278
|
+
if (evaluatedExpression !== `wpkh(${keyExpression})`)
|
|
279
|
+
throw new Error(`Error: invalid expression ${expression}`);
|
|
280
|
+
__classPrivateFieldSet(this, _Descriptor_expandedExpression, 'wpkh(@0)', "f");
|
|
281
|
+
__classPrivateFieldSet(this, _Descriptor_expansionMap, {
|
|
282
|
+
'@0': parseKeyExpression({
|
|
283
|
+
keyExpression,
|
|
284
|
+
network,
|
|
285
|
+
isSegwit: __classPrivateFieldGet(this, _Descriptor_isSegwit, "f")
|
|
286
|
+
})
|
|
287
|
+
}, "f");
|
|
288
|
+
const pubkey = __classPrivateFieldGet(this, _Descriptor_expansionMap, "f")['@0'].pubkey;
|
|
289
|
+
__classPrivateFieldSet(this, _Descriptor_payment, p2wpkh({ pubkey, network }), "f");
|
|
290
|
+
}
|
|
291
|
+
//sh(wsh(miniscript))
|
|
292
|
+
else if (evaluatedExpression.match(RE.reShWshMiniscriptAnchored)) {
|
|
293
|
+
__classPrivateFieldSet(this, _Descriptor_isSegwit, true, "f");
|
|
294
|
+
const miniscript = evaluatedExpression.match(RE.reShWshMiniscriptAnchored)?.[1]; //[1]-> whatever is found sh(wsh(->HERE<-))
|
|
295
|
+
if (!miniscript)
|
|
296
|
+
throw new Error(`Error: could not get miniscript in ${evaluatedExpression}`);
|
|
297
|
+
__classPrivateFieldSet(this, _Descriptor_miniscript, miniscript, "f");
|
|
298
|
+
(_a = this, _b = this, {
|
|
299
|
+
expandedMiniscript: ({ set value(_g) { __classPrivateFieldSet(_a, _Descriptor_expandedMiniscript, _g, "f"); } }).value,
|
|
300
|
+
expansionMap: ({ set value(_g) { __classPrivateFieldSet(_b, _Descriptor_expansionMap, _g, "f"); } }).value
|
|
301
|
+
} = expandMiniscript({
|
|
302
|
+
miniscript,
|
|
303
|
+
isSegwit: __classPrivateFieldGet(this, _Descriptor_isSegwit, "f"),
|
|
304
|
+
network
|
|
305
|
+
}));
|
|
306
|
+
__classPrivateFieldSet(this, _Descriptor_expandedExpression, `sh(wsh(${__classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f")}))`, "f");
|
|
307
|
+
const script = (0, miniscript_1.miniscript2Script)({
|
|
308
|
+
expandedMiniscript: __classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f"),
|
|
309
|
+
expansionMap: __classPrivateFieldGet(this, _Descriptor_expansionMap, "f")
|
|
310
|
+
});
|
|
311
|
+
__classPrivateFieldSet(this, _Descriptor_witnessScript, script, "f");
|
|
312
|
+
if (script.byteLength > MAX_STANDARD_P2WSH_SCRIPT_SIZE) {
|
|
313
|
+
throw new Error(`Error: script is too large, ${script.byteLength} bytes is larger than ${MAX_STANDARD_P2WSH_SCRIPT_SIZE} bytes`);
|
|
314
|
+
}
|
|
315
|
+
const nonPushOnlyOps = countNonPushOnlyOPs(script);
|
|
316
|
+
if (nonPushOnlyOps > MAX_OPS_PER_SCRIPT) {
|
|
317
|
+
throw new Error(`Error: too many non-push ops, ${nonPushOnlyOps} non-push ops is larger than ${MAX_OPS_PER_SCRIPT}`);
|
|
318
|
+
}
|
|
319
|
+
__classPrivateFieldSet(this, _Descriptor_payment, p2sh({
|
|
320
|
+
redeem: p2wsh({ redeem: { output: script, network }, network }),
|
|
321
|
+
network
|
|
322
|
+
}), "f");
|
|
323
|
+
const redeemScript = __classPrivateFieldGet(this, _Descriptor_payment, "f").redeem?.output;
|
|
324
|
+
if (!redeemScript)
|
|
325
|
+
throw new Error(`Error: could not calculate redeemScript for ${expression}`);
|
|
326
|
+
__classPrivateFieldSet(this, _Descriptor_redeemScript, redeemScript, "f");
|
|
327
|
+
}
|
|
328
|
+
//sh(miniscript)
|
|
329
|
+
else if (evaluatedExpression.match(RE.reShMiniscriptAnchored)) {
|
|
330
|
+
//isSegwit false because we know it's a P2SH of a miniscript and not a
|
|
331
|
+
//P2SH that embeds a witness payment.
|
|
332
|
+
__classPrivateFieldSet(this, _Descriptor_isSegwit, false, "f");
|
|
333
|
+
const miniscript = evaluatedExpression.match(RE.reShMiniscriptAnchored)?.[1]; //[1]-> whatever is found sh(->HERE<-)
|
|
334
|
+
if (!miniscript)
|
|
335
|
+
throw new Error(`Error: could not get miniscript in ${evaluatedExpression}`);
|
|
336
|
+
if (allowMiniscriptInP2SH === false &&
|
|
337
|
+
//These top-level expressions within sh are allowed within sh.
|
|
338
|
+
//They can be parsed with miniscript2Script, but first we must make sure
|
|
339
|
+
//that other expressions are not accepted (unless forced with allowMiniscriptInP2SH).
|
|
340
|
+
miniscript.search(/^(pk\(|pkh\(|wpkh\(|combo\(|multi\(|sortedmulti\(|multi_a\(|sortedmulti_a\()/) !== 0) {
|
|
341
|
+
throw new Error(`Error: Miniscript expressions can only be used in wsh`);
|
|
342
|
+
}
|
|
343
|
+
__classPrivateFieldSet(this, _Descriptor_miniscript, miniscript, "f");
|
|
344
|
+
(_c = this, _d = this, {
|
|
345
|
+
expandedMiniscript: ({ set value(_g) { __classPrivateFieldSet(_c, _Descriptor_expandedMiniscript, _g, "f"); } }).value,
|
|
346
|
+
expansionMap: ({ set value(_g) { __classPrivateFieldSet(_d, _Descriptor_expansionMap, _g, "f"); } }).value
|
|
347
|
+
} = expandMiniscript({
|
|
348
|
+
miniscript,
|
|
349
|
+
isSegwit: __classPrivateFieldGet(this, _Descriptor_isSegwit, "f"),
|
|
350
|
+
network
|
|
351
|
+
}));
|
|
352
|
+
__classPrivateFieldSet(this, _Descriptor_expandedExpression, `sh(${__classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f")})`, "f");
|
|
353
|
+
const script = (0, miniscript_1.miniscript2Script)({
|
|
354
|
+
expandedMiniscript: __classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f"),
|
|
355
|
+
expansionMap: __classPrivateFieldGet(this, _Descriptor_expansionMap, "f")
|
|
356
|
+
});
|
|
357
|
+
__classPrivateFieldSet(this, _Descriptor_redeemScript, script, "f");
|
|
358
|
+
if (script.byteLength > MAX_SCRIPT_ELEMENT_SIZE) {
|
|
359
|
+
throw new Error(`Error: P2SH script is too large, ${script.byteLength} bytes is larger than ${MAX_SCRIPT_ELEMENT_SIZE} bytes`);
|
|
360
|
+
}
|
|
361
|
+
const nonPushOnlyOps = countNonPushOnlyOPs(script);
|
|
362
|
+
if (nonPushOnlyOps > MAX_OPS_PER_SCRIPT) {
|
|
363
|
+
throw new Error(`Error: too many non-push ops, ${nonPushOnlyOps} non-push ops is larger than ${MAX_OPS_PER_SCRIPT}`);
|
|
364
|
+
}
|
|
365
|
+
__classPrivateFieldSet(this, _Descriptor_payment, p2sh({ redeem: { output: script, network }, network }), "f");
|
|
366
|
+
if (Buffer.compare(script, this.getRedeemScript()) !== 0)
|
|
367
|
+
throw new Error(`Error: redeemScript was not correctly set to the payment in expression ${expression}`);
|
|
368
|
+
}
|
|
369
|
+
//wsh(miniscript)
|
|
370
|
+
else if (evaluatedExpression.match(RE.reWshMiniscriptAnchored)) {
|
|
371
|
+
__classPrivateFieldSet(this, _Descriptor_isSegwit, true, "f");
|
|
372
|
+
const miniscript = evaluatedExpression.match(RE.reWshMiniscriptAnchored)?.[1]; //[1]-> whatever is found wsh(->HERE<-)
|
|
373
|
+
if (!miniscript)
|
|
374
|
+
throw new Error(`Error: could not get miniscript in ${evaluatedExpression}`);
|
|
375
|
+
__classPrivateFieldSet(this, _Descriptor_miniscript, miniscript, "f");
|
|
376
|
+
(_e = this, _f = this, {
|
|
377
|
+
expandedMiniscript: ({ set value(_g) { __classPrivateFieldSet(_e, _Descriptor_expandedMiniscript, _g, "f"); } }).value,
|
|
378
|
+
expansionMap: ({ set value(_g) { __classPrivateFieldSet(_f, _Descriptor_expansionMap, _g, "f"); } }).value
|
|
379
|
+
} = expandMiniscript({
|
|
380
|
+
miniscript,
|
|
381
|
+
isSegwit: __classPrivateFieldGet(this, _Descriptor_isSegwit, "f"),
|
|
382
|
+
network
|
|
383
|
+
}));
|
|
384
|
+
__classPrivateFieldSet(this, _Descriptor_expandedExpression, `wsh(${__classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f")})`, "f");
|
|
385
|
+
const script = (0, miniscript_1.miniscript2Script)({
|
|
386
|
+
expandedMiniscript: __classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f"),
|
|
387
|
+
expansionMap: __classPrivateFieldGet(this, _Descriptor_expansionMap, "f")
|
|
388
|
+
});
|
|
389
|
+
__classPrivateFieldSet(this, _Descriptor_witnessScript, script, "f");
|
|
390
|
+
if (script.byteLength > MAX_STANDARD_P2WSH_SCRIPT_SIZE) {
|
|
391
|
+
throw new Error(`Error: script is too large, ${script.byteLength} bytes is larger than ${MAX_STANDARD_P2WSH_SCRIPT_SIZE} bytes`);
|
|
392
|
+
}
|
|
393
|
+
const nonPushOnlyOps = countNonPushOnlyOPs(script);
|
|
394
|
+
if (nonPushOnlyOps > MAX_OPS_PER_SCRIPT) {
|
|
395
|
+
throw new Error(`Error: too many non-push ops, ${nonPushOnlyOps} non-push ops is larger than ${MAX_OPS_PER_SCRIPT}`);
|
|
396
|
+
}
|
|
397
|
+
__classPrivateFieldSet(this, _Descriptor_payment, p2wsh({ redeem: { output: script, network }, network }), "f");
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
throw new Error(`Error: Could not parse descriptor ${expression}`);
|
|
401
|
+
}
|
|
402
|
+
if (signersPubKeys) {
|
|
403
|
+
__classPrivateFieldSet(this, _Descriptor_signersPubKeys, signersPubKeys, "f");
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
if (__classPrivateFieldGet(this, _Descriptor_expansionMap, "f")) {
|
|
407
|
+
__classPrivateFieldSet(this, _Descriptor_signersPubKeys, Object.values(__classPrivateFieldGet(this, _Descriptor_expansionMap, "f")).map(keyInfo => keyInfo.pubkey), "f");
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
//We should only miss expansionMap in addr() expressions:
|
|
411
|
+
if (!evaluatedExpression.match(RE.reAddrAnchored)) {
|
|
412
|
+
throw new Error(`Error: expansionMap not available for expression ${expression} that is not an address`);
|
|
413
|
+
}
|
|
414
|
+
__classPrivateFieldSet(this, _Descriptor_signersPubKeys, [this.getScriptPubKey()], "f");
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
getPayment() {
|
|
419
|
+
return __classPrivateFieldGet(this, _Descriptor_payment, "f");
|
|
420
|
+
}
|
|
421
|
+
getAddress() {
|
|
422
|
+
if (!__classPrivateFieldGet(this, _Descriptor_payment, "f").address)
|
|
423
|
+
throw new Error(`Error: could extract an address from the payment`);
|
|
424
|
+
return __classPrivateFieldGet(this, _Descriptor_payment, "f").address;
|
|
425
|
+
}
|
|
426
|
+
getScriptPubKey() {
|
|
427
|
+
if (!__classPrivateFieldGet(this, _Descriptor_payment, "f").output)
|
|
428
|
+
throw new Error(`Error: could extract output.script from the payment`);
|
|
429
|
+
return __classPrivateFieldGet(this, _Descriptor_payment, "f").output;
|
|
430
|
+
}
|
|
431
|
+
getScriptSatisfaction(signatures) {
|
|
432
|
+
const miniscript = __classPrivateFieldGet(this, _Descriptor_miniscript, "f");
|
|
433
|
+
const expandedMiniscript = __classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f");
|
|
434
|
+
const expansionMap = __classPrivateFieldGet(this, _Descriptor_expansionMap, "f");
|
|
435
|
+
if (miniscript === undefined ||
|
|
436
|
+
expandedMiniscript === undefined ||
|
|
437
|
+
expansionMap === undefined)
|
|
438
|
+
throw new Error(`Error: cannot get satisfaction from not expanded miniscript ${miniscript}`);
|
|
439
|
+
//Note that we pass the nLockTime and nSequence that is deduced
|
|
440
|
+
//using preimages and signersPubKeys.
|
|
441
|
+
//satisfyMiniscript will make sure
|
|
442
|
+
//that the actual solution given, using real signatures, still meets the
|
|
443
|
+
//same nLockTime and nSequence constraints
|
|
444
|
+
const scriptSatisfaction = (0, miniscript_1.satisfyMiniscript)({
|
|
445
|
+
expandedMiniscript,
|
|
446
|
+
expansionMap,
|
|
447
|
+
signatures,
|
|
448
|
+
preimages: __classPrivateFieldGet(this, _Descriptor_preimages, "f"),
|
|
449
|
+
//Here we pass the TimeConstraints obtained using signersPubKeys to
|
|
450
|
+
//verify that the solutions found using the final signatures have not
|
|
451
|
+
//changed
|
|
452
|
+
timeConstraints: {
|
|
453
|
+
nLockTime: this.getLockTime(),
|
|
454
|
+
nSequence: this.getSequence()
|
|
455
|
+
}
|
|
456
|
+
}).scriptSatisfaction;
|
|
457
|
+
if (!scriptSatisfaction)
|
|
458
|
+
throw new Error(`Error: could not produce a valid satisfaction`);
|
|
459
|
+
return scriptSatisfaction;
|
|
460
|
+
}
|
|
461
|
+
getSequence() {
|
|
462
|
+
return __classPrivateFieldGet(this, _Descriptor_instances, "m", _Descriptor_getTimeConstraints).call(this)?.nSequence;
|
|
463
|
+
}
|
|
464
|
+
getLockTime() {
|
|
465
|
+
return __classPrivateFieldGet(this, _Descriptor_instances, "m", _Descriptor_getTimeConstraints).call(this)?.nLockTime;
|
|
466
|
+
}
|
|
467
|
+
getWitnessScript() {
|
|
468
|
+
return __classPrivateFieldGet(this, _Descriptor_witnessScript, "f");
|
|
469
|
+
}
|
|
470
|
+
getRedeemScript() {
|
|
471
|
+
return __classPrivateFieldGet(this, _Descriptor_redeemScript, "f");
|
|
472
|
+
}
|
|
473
|
+
getNetwork() {
|
|
474
|
+
return __classPrivateFieldGet(this, _Descriptor_network, "f");
|
|
475
|
+
}
|
|
476
|
+
isSegwit() {
|
|
477
|
+
return __classPrivateFieldGet(this, _Descriptor_isSegwit, "f");
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Updates a Psbt where the descriptor describes an utxo.
|
|
481
|
+
* The txHex (nonWitnessUtxo) and vout of the utxo must be passed.
|
|
482
|
+
*
|
|
483
|
+
* updatePsbt adds an input to the psbt and updates the tx locktime if needed.
|
|
484
|
+
* It also adds a new input to the Psbt based on txHex
|
|
485
|
+
* It returns the number of the input that is added.
|
|
486
|
+
* psbt and vout are mandatory. Also pass txHex.
|
|
487
|
+
*
|
|
488
|
+
* The following is not recommended but, alternatively, ONLY for Segwit inputs,
|
|
489
|
+
* you can pass txId and value, instead of txHex.
|
|
490
|
+
* If you do so, it is your responsibility to make sure that `value` is
|
|
491
|
+
* correct to avoid possible fee vulnerability attacks:
|
|
492
|
+
* https://github.com/bitcoinjs/bitcoinjs-lib/issues/1625
|
|
493
|
+
* Note that HW wallets require the full txHex also for Segwit anyways:
|
|
494
|
+
* https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd
|
|
495
|
+
*
|
|
496
|
+
* In doubt, simply pass txHex (and you can skip passing txId and value) and
|
|
497
|
+
* you shall be fine.
|
|
498
|
+
*/
|
|
499
|
+
updatePsbt({ psbt, txHex, txId, value, vout //vector output index
|
|
500
|
+
}) {
|
|
501
|
+
if (txHex === undefined) {
|
|
502
|
+
console.warn(`Warning: missing txHex may allow fee attacks`);
|
|
503
|
+
}
|
|
504
|
+
const isSegwit = this.isSegwit();
|
|
505
|
+
if (isSegwit === undefined) {
|
|
506
|
+
//This should only happen when using addr() expressions
|
|
507
|
+
throw new Error(`Error: could not determine whether this is a segwit descriptor`);
|
|
508
|
+
}
|
|
509
|
+
return (0, psbt_1.updatePsbt)({
|
|
510
|
+
psbt,
|
|
511
|
+
vout,
|
|
512
|
+
...(txHex !== undefined ? { txHex } : {}),
|
|
513
|
+
...(txId !== undefined ? { txId } : {}),
|
|
514
|
+
...(value !== undefined ? { value } : {}),
|
|
515
|
+
sequence: this.getSequence(),
|
|
516
|
+
locktime: this.getLockTime(),
|
|
517
|
+
keysInfo: __classPrivateFieldGet(this, _Descriptor_expansionMap, "f") ? Object.values(__classPrivateFieldGet(this, _Descriptor_expansionMap, "f")) : [],
|
|
518
|
+
scriptPubKey: this.getScriptPubKey(),
|
|
519
|
+
isSegwit,
|
|
520
|
+
witnessScript: this.getWitnessScript(),
|
|
521
|
+
redeemScript: this.getRedeemScript()
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
finalizePsbtInput({ index, psbt, validate = true }) {
|
|
525
|
+
if (validate &&
|
|
526
|
+
!psbt.validateSignaturesOfInput(index, signatureValidator)) {
|
|
527
|
+
throw new Error(`Error: invalid signatures on input ${index}`);
|
|
528
|
+
}
|
|
529
|
+
//An index must be passed since finding the index in the psbt cannot be
|
|
530
|
+
//done:
|
|
531
|
+
//Imagine the case where you received money twice to
|
|
532
|
+
//the same miniscript-based address. You would have the same scriptPubKey,
|
|
533
|
+
//same sequences, ... The descriptor does not store the hash of the previous
|
|
534
|
+
//transaction since it is a general Descriptor object. Indices must be kept
|
|
535
|
+
//out of the scope of this class and then passed.
|
|
536
|
+
const signatures = psbt.data.inputs[index]?.partialSig;
|
|
537
|
+
if (!signatures)
|
|
538
|
+
throw new Error(`Error: cannot finalize without signatures`);
|
|
539
|
+
__classPrivateFieldGet(this, _Descriptor_instances, "m", _Descriptor_assertPsbtInput).call(this, { index, psbt });
|
|
540
|
+
if (!__classPrivateFieldGet(this, _Descriptor_miniscript, "f")) {
|
|
541
|
+
//Use standard finalizers
|
|
542
|
+
psbt.finalizeInput(index);
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
const scriptSatisfaction = this.getScriptSatisfaction(signatures);
|
|
546
|
+
psbt.finalizeInput(index, (0, psbt_1.finalScriptsFuncFactory)(scriptSatisfaction, __classPrivateFieldGet(this, _Descriptor_network, "f")));
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
expand() {
|
|
550
|
+
return {
|
|
551
|
+
...(__classPrivateFieldGet(this, _Descriptor_expandedExpression, "f") !== undefined
|
|
552
|
+
? { expandedExpression: __classPrivateFieldGet(this, _Descriptor_expandedExpression, "f") }
|
|
553
|
+
: {}),
|
|
554
|
+
...(__classPrivateFieldGet(this, _Descriptor_miniscript, "f") !== undefined
|
|
555
|
+
? { miniscript: __classPrivateFieldGet(this, _Descriptor_miniscript, "f") }
|
|
556
|
+
: {}),
|
|
557
|
+
...(__classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f") !== undefined
|
|
558
|
+
? { expandedMiniscript: __classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f") }
|
|
559
|
+
: {}),
|
|
560
|
+
...(__classPrivateFieldGet(this, _Descriptor_expansionMap, "f") !== undefined
|
|
561
|
+
? { expansionMap: __classPrivateFieldGet(this, _Descriptor_expansionMap, "f") }
|
|
562
|
+
: {})
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
_Descriptor_payment = new WeakMap(), _Descriptor_preimages = new WeakMap(), _Descriptor_signersPubKeys = new WeakMap(), _Descriptor_miniscript = new WeakMap(), _Descriptor_witnessScript = new WeakMap(), _Descriptor_redeemScript = new WeakMap(), _Descriptor_isSegwit = new WeakMap(), _Descriptor_expandedExpression = new WeakMap(), _Descriptor_expandedMiniscript = new WeakMap(), _Descriptor_expansionMap = new WeakMap(), _Descriptor_network = new WeakMap(), _Descriptor_instances = new WeakSet(), _Descriptor_getTimeConstraints = function _Descriptor_getTimeConstraints() {
|
|
567
|
+
const miniscript = __classPrivateFieldGet(this, _Descriptor_miniscript, "f");
|
|
568
|
+
const preimages = __classPrivateFieldGet(this, _Descriptor_preimages, "f");
|
|
569
|
+
const expandedMiniscript = __classPrivateFieldGet(this, _Descriptor_expandedMiniscript, "f");
|
|
570
|
+
const expansionMap = __classPrivateFieldGet(this, _Descriptor_expansionMap, "f");
|
|
571
|
+
const signersPubKeys = __classPrivateFieldGet(this, _Descriptor_signersPubKeys, "f");
|
|
572
|
+
//Create a method. solvePreimages to solve them.
|
|
573
|
+
if (miniscript) {
|
|
574
|
+
if (expandedMiniscript === undefined || expansionMap === undefined)
|
|
575
|
+
throw new Error(`Error: cannot get time constraints from not expanded miniscript ${miniscript}`);
|
|
576
|
+
//We create some fakeSignatures since we may not have them yet.
|
|
577
|
+
//We only want to retrieve the nLockTime and nSequence of the satisfaction and
|
|
578
|
+
//signatures don't matter
|
|
579
|
+
const fakeSignatures = signersPubKeys.map(pubkey => ({
|
|
580
|
+
pubkey,
|
|
581
|
+
signature: Buffer.alloc(64, 0)
|
|
582
|
+
}));
|
|
583
|
+
const { nLockTime, nSequence } = (0, miniscript_1.satisfyMiniscript)({
|
|
584
|
+
expandedMiniscript,
|
|
585
|
+
expansionMap,
|
|
586
|
+
signatures: fakeSignatures,
|
|
587
|
+
preimages
|
|
588
|
+
});
|
|
589
|
+
return { nLockTime, nSequence };
|
|
590
|
+
}
|
|
591
|
+
else
|
|
592
|
+
return undefined;
|
|
593
|
+
}, _Descriptor_assertPsbtInput = function _Descriptor_assertPsbtInput({ psbt, index }) {
|
|
594
|
+
const input = psbt.data.inputs[index];
|
|
595
|
+
const txInput = psbt.txInputs[index];
|
|
596
|
+
if (!input || !txInput)
|
|
597
|
+
throw new Error(`Error: invalid input or txInput`);
|
|
598
|
+
const { sequence: inputSequence, index: vout } = txInput;
|
|
599
|
+
let scriptPubKey;
|
|
600
|
+
if (input.witnessUtxo)
|
|
601
|
+
scriptPubKey = input.witnessUtxo.script;
|
|
602
|
+
else {
|
|
603
|
+
if (!input.nonWitnessUtxo)
|
|
604
|
+
throw new Error(`Error: input should have either witnessUtxo or nonWitnessUtxo`);
|
|
605
|
+
const tx = bitcoinjs_lib_1.Transaction.fromBuffer(input.nonWitnessUtxo);
|
|
606
|
+
const out = tx.outs[vout];
|
|
607
|
+
if (!out)
|
|
608
|
+
throw new Error(`Error: utxo should exist`);
|
|
609
|
+
scriptPubKey = out.script;
|
|
610
|
+
}
|
|
611
|
+
const locktime = this.getLockTime() || 0;
|
|
612
|
+
let sequence = this.getSequence();
|
|
613
|
+
if (sequence === undefined && locktime !== 0)
|
|
614
|
+
sequence = 0xfffffffe;
|
|
615
|
+
if (sequence === undefined && locktime === 0)
|
|
616
|
+
sequence = 0xffffffff;
|
|
617
|
+
if (Buffer.compare(scriptPubKey, this.getScriptPubKey()) !== 0 ||
|
|
618
|
+
sequence !== inputSequence ||
|
|
619
|
+
locktime !== psbt.locktime ||
|
|
620
|
+
this.getWitnessScript() !== input.witnessScript ||
|
|
621
|
+
this.getRedeemScript() !== input.redeemScript) {
|
|
622
|
+
throw new Error(`Error: cannot finalize psbt index ${index} since it does not correspond to this descriptor`);
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
return { Descriptor, parseKeyExpression, ECPair, BIP32 };
|
|
626
|
+
}
|
|
627
|
+
exports.DescriptorsFactory = DescriptorsFactory;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Psbt } from 'bitcoinjs-lib';
|
|
2
|
+
import type { DescriptorInterface } from './types';
|
|
3
|
+
export { DescriptorInterface, DescriptorInterfaceConstructor, ParseKeyExpression } from './types';
|
|
4
|
+
export { DescriptorsFactory } from './descriptors';
|
|
5
|
+
export { DescriptorChecksum as checksum } from './checksum';
|
|
6
|
+
import * as signers from './signers';
|
|
7
|
+
export { signers };
|
|
8
|
+
export declare function finalizePsbt({ psbt, descriptors, validate }: {
|
|
9
|
+
psbt: Psbt;
|
|
10
|
+
descriptors: DescriptorInterface[];
|
|
11
|
+
validate?: boolean | undefined;
|
|
12
|
+
}): void;
|
|
13
|
+
export { keyExpressionBIP32, keyExpressionLedger } from './keyExpressions';
|
|
14
|
+
import * as scriptExpressions from './scriptExpressions';
|
|
15
|
+
export { scriptExpressions };
|
|
16
|
+
import { AppClient } from '@bitcoinerlab/ledger';
|
|
17
|
+
import { LedgerState, getLedgerMasterFingerPrint, getLedgerXpub, registerLedgerWallet, assertLedgerApp } from './ledger';
|
|
18
|
+
export declare const ledger: {
|
|
19
|
+
getLedgerMasterFingerPrint: typeof getLedgerMasterFingerPrint;
|
|
20
|
+
getLedgerXpub: typeof getLedgerXpub;
|
|
21
|
+
registerLedgerWallet: typeof registerLedgerWallet;
|
|
22
|
+
assertLedgerApp: typeof assertLedgerApp;
|
|
23
|
+
AppClient: typeof AppClient;
|
|
24
|
+
};
|
|
25
|
+
export type { LedgerState };
|