@bitcoinerlab/descriptors 3.0.1 → 3.0.3
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/dist/bitcoinjs-lib-internals.js +35 -3
- package/dist/descriptors.js +64 -24
- package/package.json +2 -2
|
@@ -6,9 +6,41 @@
|
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.isTaprootInput = exports.witnessStackToScriptWitness = exports.tweakKey = exports.toHashTree = exports.tapTweakHash = exports.tapleafHash = exports.findScriptPath = void 0;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
9
|
+
function resolveAbsoluteCjsPath(relativePath) {
|
|
10
|
+
try {
|
|
11
|
+
const entryPoint = require.resolve('bitcoinjs-lib');
|
|
12
|
+
const root = entryPoint.replace(/src[\\/]+cjs[\\/]+index\.cjs$/, '');
|
|
13
|
+
if (root === entryPoint)
|
|
14
|
+
return undefined;
|
|
15
|
+
return `${root}src/cjs/${relativePath}.cjs`;
|
|
16
|
+
}
|
|
17
|
+
catch (_err) {
|
|
18
|
+
void _err;
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function requireBitcoinJsInternal(relativePath) {
|
|
23
|
+
const candidatePaths = [
|
|
24
|
+
`bitcoinjs-lib/src/${relativePath}`,
|
|
25
|
+
`bitcoinjs-lib/src/cjs/${relativePath}.cjs`
|
|
26
|
+
];
|
|
27
|
+
const absoluteCjsPath = resolveAbsoluteCjsPath(relativePath);
|
|
28
|
+
if (absoluteCjsPath)
|
|
29
|
+
candidatePaths.push(absoluteCjsPath);
|
|
30
|
+
let lastError;
|
|
31
|
+
for (const modulePath of candidatePaths) {
|
|
32
|
+
try {
|
|
33
|
+
return require(modulePath);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
lastError = err;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
throw lastError;
|
|
40
|
+
}
|
|
41
|
+
const bip341 = requireBitcoinJsInternal('payments/bip341');
|
|
42
|
+
const bip371 = requireBitcoinJsInternal('psbt/bip371');
|
|
43
|
+
const psbtUtils = requireBitcoinJsInternal('psbt/psbtutils');
|
|
12
44
|
exports.findScriptPath = bip341.findScriptPath;
|
|
13
45
|
exports.tapleafHash = bip341.tapleafHash;
|
|
14
46
|
exports.tapTweakHash = bip341.tapTweakHash;
|
package/dist/descriptors.js
CHANGED
|
@@ -1162,24 +1162,56 @@ expansion=${expansion}, isPKH=${isPKH}, isWPKH=${isWPKH}, isSH=${isSH}, isTR=${i
|
|
|
1162
1162
|
return (0, varuint_bitcoin_1.encodingLength)(length) + length;
|
|
1163
1163
|
};
|
|
1164
1164
|
const resolveMiniscriptSignatures = () => {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1165
|
+
const signerPubKeys = __classPrivateFieldGet(this, _Output_instances, "m", _Output_resolveMiniscriptSignersPubKeys).call(this);
|
|
1166
|
+
if (signatures === 'DANGEROUSLY_USE_FAKE_SIGNATURES') {
|
|
1167
|
+
return signerPubKeys.map(pubkey => ({
|
|
1168
|
+
pubkey,
|
|
1169
|
+
// https://transactionfee.info/charts/bitcoin-script-ecdsa-length/
|
|
1170
|
+
signature: new Uint8Array(ECDSA_FAKE_SIGNATURE_SIZE)
|
|
1171
|
+
}));
|
|
1172
|
+
}
|
|
1173
|
+
const providedSignerPubKeysSet = new Set(signatures.map(sig => (0, uint8array_tools_1.toHex)(sig.pubkey)));
|
|
1174
|
+
const missingSignerPubKeys = signerPubKeys.filter(pubkey => !providedSignerPubKeysSet.has((0, uint8array_tools_1.toHex)(pubkey)));
|
|
1175
|
+
if (missingSignerPubKeys.length > 0)
|
|
1176
|
+
throw new Error(`Error: inputWeight expected signatures for all planned miniscript signers. Missing ${missingSignerPubKeys.length} signer(s)`);
|
|
1177
|
+
const signerPubKeysSet = new Set(signerPubKeys.map(pubkey => (0, uint8array_tools_1.toHex)(pubkey)));
|
|
1178
|
+
return signatures.filter(sig => signerPubKeysSet.has((0, uint8array_tools_1.toHex)(sig.pubkey)));
|
|
1172
1179
|
};
|
|
1173
1180
|
const taprootFakeSignatureSize = taprootSighash === 'SIGHASH_DEFAULT'
|
|
1174
1181
|
? TAPROOT_FAKE_SIGNATURE_SIZE
|
|
1175
1182
|
: TAPROOT_FAKE_SIGNATURE_SIZE + 1;
|
|
1176
|
-
const
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
return __classPrivateFieldGet(this, _Output_instances, "m", _Output_resolveTapTreeSignersPubKeys).call(this).map(pubkey => ({
|
|
1183
|
+
const resolvePlannedTaprootRequiredPubKeys = () => {
|
|
1184
|
+
const tapTreeSignerPubKeys = __classPrivateFieldGet(this, _Output_instances, "m", _Output_resolveTapTreeSignersPubKeys).call(this).map(tapMiniscript_1.normalizeTaprootPubkey);
|
|
1185
|
+
const taggedFakeSignatures = tapTreeSignerPubKeys.map((pubkey, index) => ({
|
|
1180
1186
|
pubkey,
|
|
1181
|
-
signature: new Uint8Array(taprootFakeSignatureSize)
|
|
1187
|
+
signature: new Uint8Array(taprootFakeSignatureSize).fill(index + 1)
|
|
1188
|
+
}));
|
|
1189
|
+
const plannedTaprootSatisfaction = this.getTapScriptSatisfaction(taggedFakeSignatures);
|
|
1190
|
+
const requiredPubkeys = taggedFakeSignatures
|
|
1191
|
+
.filter(fakeSignature => plannedTaprootSatisfaction.stackItems.some(stackItem => (0, uint8array_tools_1.compare)(stackItem, fakeSignature.signature) === 0))
|
|
1192
|
+
.map(fakeSignature => fakeSignature.pubkey);
|
|
1193
|
+
return Array.from(new Set(requiredPubkeys.map(pubkey => (0, uint8array_tools_1.toHex)(pubkey))))
|
|
1194
|
+
.map(hex => (0, uint8array_tools_1.fromHex)(hex))
|
|
1195
|
+
.map(tapMiniscript_1.normalizeTaprootPubkey);
|
|
1196
|
+
};
|
|
1197
|
+
const resolveTaprootSignatures = () => {
|
|
1198
|
+
if (signatures === 'DANGEROUSLY_USE_FAKE_SIGNATURES') {
|
|
1199
|
+
return __classPrivateFieldGet(this, _Output_instances, "m", _Output_resolveTapTreeSignersPubKeys).call(this).map(pubkey => ({
|
|
1200
|
+
pubkey,
|
|
1201
|
+
signature: new Uint8Array(taprootFakeSignatureSize)
|
|
1202
|
+
}));
|
|
1203
|
+
}
|
|
1204
|
+
const normalizedSignatures = signatures.map(sig => ({
|
|
1205
|
+
pubkey: (0, tapMiniscript_1.normalizeTaprootPubkey)(sig.pubkey),
|
|
1206
|
+
signature: sig.signature
|
|
1182
1207
|
}));
|
|
1208
|
+
const plannedRequiredPubKeys = resolvePlannedTaprootRequiredPubKeys();
|
|
1209
|
+
const providedTapTreeSignerPubKeysSet = new Set(normalizedSignatures.map(sig => (0, uint8array_tools_1.toHex)(sig.pubkey)));
|
|
1210
|
+
const missingTapTreeSignerPubKeys = plannedRequiredPubKeys.filter(pubkey => !providedTapTreeSignerPubKeysSet.has((0, uint8array_tools_1.toHex)(pubkey)));
|
|
1211
|
+
if (missingTapTreeSignerPubKeys.length > 0)
|
|
1212
|
+
throw new Error(`Error: inputWeight expected signatures for the planned taproot script-path satisfaction. Missing ${missingTapTreeSignerPubKeys.length} signer(s)`);
|
|
1213
|
+
const plannedRequiredPubKeysSet = new Set(plannedRequiredPubKeys.map(pubkey => (0, uint8array_tools_1.toHex)(pubkey)));
|
|
1214
|
+
return normalizedSignatures.filter(sig => plannedRequiredPubKeysSet.has((0, uint8array_tools_1.toHex)(sig.pubkey)));
|
|
1183
1215
|
};
|
|
1184
1216
|
const resolveTaprootSignatureSize = () => {
|
|
1185
1217
|
let length;
|
|
@@ -1187,9 +1219,26 @@ expansion=${expansion}, isPKH=${isPKH}, isWPKH=${isWPKH}, isSH=${isSH}, isTR=${i
|
|
|
1187
1219
|
length = taprootFakeSignatureSize;
|
|
1188
1220
|
}
|
|
1189
1221
|
else {
|
|
1190
|
-
|
|
1222
|
+
const normalizedSignatures = signatures.map(sig => ({
|
|
1223
|
+
pubkey: (0, tapMiniscript_1.normalizeTaprootPubkey)(sig.pubkey),
|
|
1224
|
+
signature: sig.signature
|
|
1225
|
+
}));
|
|
1226
|
+
const internalPubkey = this.getPayment().internalPubkey;
|
|
1227
|
+
if (!internalPubkey) {
|
|
1228
|
+
//addr() of tr addresses may not have internalPubkey
|
|
1229
|
+
if (normalizedSignatures.length !== 1)
|
|
1230
|
+
throw new Error('Error: inputWeight for addr(TR_ADDRESS) requires exactly one signature. Internal taproot pubkey is unavailable in addr() descriptors; use tr(KEY) for strict key matching.');
|
|
1231
|
+
const singleSignature = normalizedSignatures[0];
|
|
1232
|
+
if (!singleSignature)
|
|
1233
|
+
throw new Error('Signatures not present');
|
|
1234
|
+
length = singleSignature.signature.length;
|
|
1235
|
+
return (0, varuint_bitcoin_1.encodingLength)(length) + length;
|
|
1236
|
+
}
|
|
1237
|
+
const normalizedInternalPubkey = (0, tapMiniscript_1.normalizeTaprootPubkey)(internalPubkey);
|
|
1238
|
+
const keyPathSignatures = normalizedSignatures.filter(sig => (0, uint8array_tools_1.compare)(sig.pubkey, normalizedInternalPubkey) === 0);
|
|
1239
|
+
if (keyPathSignatures.length !== 1)
|
|
1191
1240
|
throw new Error('More than one signture was not expected');
|
|
1192
|
-
const singleSignature =
|
|
1241
|
+
const singleSignature = keyPathSignatures[0];
|
|
1193
1242
|
if (!singleSignature)
|
|
1194
1243
|
throw new Error('Signatures not present');
|
|
1195
1244
|
length = singleSignature.signature.length;
|
|
@@ -1197,7 +1246,6 @@ expansion=${expansion}, isPKH=${isPKH}, isWPKH=${isWPKH}, isSH=${isSH}, isTR=${i
|
|
|
1197
1246
|
return (0, varuint_bitcoin_1.encodingLength)(length) + length;
|
|
1198
1247
|
};
|
|
1199
1248
|
const taprootSpendPath = __classPrivateFieldGet(this, _Output_taprootSpendPath, "f");
|
|
1200
|
-
const tapLeaf = __classPrivateFieldGet(this, _Output_tapLeaf, "f");
|
|
1201
1249
|
if (expansion ? expansion.startsWith('pkh(') : isPKH) {
|
|
1202
1250
|
return (
|
|
1203
1251
|
// Non-segwit: (txid:32) + (vout:4) + (sequence:4) + (script_len:1) + (sig:73) + (pubkey:34)
|
|
@@ -1295,15 +1343,7 @@ expansion=${expansion}, isPKH=${isPKH}, isWPKH=${isWPKH}, isSH=${isSH}, isTR=${i
|
|
|
1295
1343
|
throw new Error('Should be SegwitTx');
|
|
1296
1344
|
if (taprootSpendPath === 'key')
|
|
1297
1345
|
return 41 * 4 + (0, varuint_bitcoin_1.encodingLength)(1) + resolveTaprootSignatureSize();
|
|
1298
|
-
const
|
|
1299
|
-
if (!resolvedTapTreeInfo)
|
|
1300
|
-
throw new Error(`Error: taproot tree info not available`);
|
|
1301
|
-
const taprootSatisfaction = (0, tapMiniscript_1.satisfyTapTree)({
|
|
1302
|
-
tapTreeInfo: resolvedTapTreeInfo,
|
|
1303
|
-
preimages: __classPrivateFieldGet(this, _Output_preimages, "f"),
|
|
1304
|
-
signatures: resolveTaprootSignatures(),
|
|
1305
|
-
...(tapLeaf !== undefined ? { tapLeaf } : {})
|
|
1306
|
-
});
|
|
1346
|
+
const taprootSatisfaction = this.getTapScriptSatisfaction(resolveTaprootSignatures());
|
|
1307
1347
|
return 41 * 4 + taprootSatisfaction.totalWitnessSize;
|
|
1308
1348
|
}
|
|
1309
1349
|
else if (isTR && (!expansion || expansion === 'tr(@0)')) {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@bitcoinerlab/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/bitcoinerlab/descriptors",
|
|
5
|
-
"version": "3.0.
|
|
5
|
+
"version": "3.0.3",
|
|
6
6
|
"author": "Jose-Luis Landabaso",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"@bitcoinerlab/miniscript": "^2.0.0",
|
|
71
71
|
"@bitcoinerlab/secp256k1": "^1.2.0",
|
|
72
|
-
"bip32": "^
|
|
72
|
+
"bip32": "^5.0.1",
|
|
73
73
|
"bitcoinjs-lib": "^7.0.1",
|
|
74
74
|
"ecpair": "^3.0.1",
|
|
75
75
|
"lodash.memoize": "^4.1.2",
|