@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.
@@ -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
- const bip341 = require('bitcoinjs-lib/src/payments/bip341');
10
- const bip371 = require('bitcoinjs-lib/src/psbt/bip371');
11
- const psbtUtils = require('bitcoinjs-lib/src/psbt/psbtutils');
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;
@@ -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
- if (signatures !== 'DANGEROUSLY_USE_FAKE_SIGNATURES')
1166
- return signatures;
1167
- return __classPrivateFieldGet(this, _Output_instances, "m", _Output_resolveMiniscriptSignersPubKeys).call(this).map(pubkey => ({
1168
- pubkey,
1169
- // https://transactionfee.info/charts/bitcoin-script-ecdsa-length/
1170
- signature: new Uint8Array(ECDSA_FAKE_SIGNATURE_SIZE)
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 resolveTaprootSignatures = () => {
1177
- if (signatures !== 'DANGEROUSLY_USE_FAKE_SIGNATURES')
1178
- return signatures;
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
- if (signatures.length !== 1)
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 = signatures[0];
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 resolvedTapTreeInfo = __classPrivateFieldGet(this, _Output_tapTreeInfo, "f");
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.1",
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": "^4.0.0",
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",