@scure/btc-signer 1.7.0 → 1.8.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.
Files changed (65) hide show
  1. package/README.md +52 -1
  2. package/esm/_type_test.js +1 -1
  3. package/esm/index.d.ts +12 -12
  4. package/esm/index.d.ts.map +1 -1
  5. package/esm/index.js +10 -10
  6. package/esm/index.js.map +1 -1
  7. package/esm/musig2.js +1 -1
  8. package/esm/p2p.d.ts +38 -0
  9. package/esm/p2p.d.ts.map +1 -0
  10. package/esm/p2p.js +156 -0
  11. package/esm/p2p.js.map +1 -0
  12. package/esm/payment.d.ts +77 -21
  13. package/esm/payment.d.ts.map +1 -1
  14. package/esm/payment.js +63 -60
  15. package/esm/payment.js.map +1 -1
  16. package/esm/psbt.d.ts +1 -1
  17. package/esm/psbt.d.ts.map +1 -1
  18. package/esm/psbt.js +2 -35
  19. package/esm/psbt.js.map +1 -1
  20. package/esm/script.js +1 -1
  21. package/esm/transaction.d.ts +56 -4
  22. package/esm/transaction.d.ts.map +1 -1
  23. package/esm/transaction.js +151 -8
  24. package/esm/transaction.js.map +1 -1
  25. package/esm/utxo.d.ts +3 -55
  26. package/esm/utxo.d.ts.map +1 -1
  27. package/esm/utxo.js +5 -114
  28. package/esm/utxo.js.map +1 -1
  29. package/index.d.ts +12 -12
  30. package/index.d.ts.map +1 -1
  31. package/index.js +58 -58
  32. package/index.js.map +1 -1
  33. package/musig2.d.ts +1 -1
  34. package/musig2.js +2 -2
  35. package/p2p.d.ts +38 -0
  36. package/p2p.d.ts.map +1 -0
  37. package/p2p.js +158 -0
  38. package/p2p.js.map +1 -0
  39. package/package.json +11 -11
  40. package/payment.d.ts +77 -21
  41. package/payment.d.ts.map +1 -1
  42. package/payment.js +81 -78
  43. package/payment.js.map +1 -1
  44. package/psbt.d.ts +1 -1
  45. package/psbt.d.ts.map +1 -1
  46. package/psbt.js +22 -55
  47. package/psbt.js.map +1 -1
  48. package/script.js +3 -3
  49. package/src/_type_test.ts +1 -1
  50. package/src/index.ts +12 -12
  51. package/src/musig2.ts +1 -1
  52. package/src/p2p.ts +158 -0
  53. package/src/payment.ts +160 -75
  54. package/src/psbt.ts +2 -36
  55. package/src/script.ts +1 -1
  56. package/src/transaction.ts +156 -12
  57. package/src/utxo.ts +9 -111
  58. package/transaction.d.ts +56 -4
  59. package/transaction.d.ts.map +1 -1
  60. package/transaction.js +222 -75
  61. package/transaction.js.map +1 -1
  62. package/utxo.d.ts +3 -55
  63. package/utxo.d.ts.map +1 -1
  64. package/utxo.js +43 -156
  65. package/utxo.js.map +1 -1
package/transaction.js CHANGED
@@ -1,23 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Transaction = exports.SigHash = exports.SignatureHash = exports.def = exports.Decimal = exports.DEFAULT_SEQUENCE = exports.DEFAULT_LOCKTIME = exports.DEFAULT_VERSION = exports.PRECISION = void 0;
3
+ exports.Transaction = exports.SigHash = exports.SignatureHash = exports.def = exports.Decimal = exports.DEFAULT_SEQUENCE = exports.DEFAULT_LOCKTIME = exports.DEFAULT_VERSION = exports.PRECISION = exports.toVsize = void 0;
4
4
  exports.cloneDeep = cloneDeep;
5
5
  exports.inputBeforeSign = inputBeforeSign;
6
+ exports.getPrevOut = getPrevOut;
7
+ exports.normalizeInput = normalizeInput;
8
+ exports.getInputType = getInputType;
6
9
  exports.PSBTCombine = PSBTCombine;
7
10
  exports.bip32Path = bip32Path;
8
11
  const base_1 = require("@scure/base");
9
12
  const P = require("micro-packed");
10
- const payment_js_1 = require("./payment.js");
11
- const psbt = require("./psbt.js"); // circular
12
- const script_js_1 = require("./script.js");
13
+ const payment_ts_1 = require("./payment.js");
14
+ const psbt = require("./psbt.js");
15
+ const script_ts_1 = require("./script.js");
13
16
  const u = require("./utils.js");
14
- const utils_js_1 = require("./utils.js");
15
- const utxo_js_1 = require("./utxo.js"); // circular
17
+ const utils_ts_1 = require("./utils.js");
16
18
  const EMPTY32 = new Uint8Array(32);
17
19
  const EMPTY_OUTPUT = {
18
20
  amount: 0xffffffffffffffffn,
19
21
  script: P.EMPTY,
20
22
  };
23
+ const toVsize = (weight) => Math.ceil(weight / 4);
24
+ exports.toVsize = toVsize;
21
25
  exports.PRECISION = 8;
22
26
  exports.DEFAULT_VERSION = 2;
23
27
  exports.DEFAULT_LOCKTIME = 0;
@@ -30,7 +34,7 @@ function cloneDeep(obj) {
30
34
  if (Array.isArray(obj))
31
35
  return obj.map((i) => cloneDeep(i));
32
36
  // slice of nodejs Buffer doesn't copy
33
- else if ((0, utils_js_1.isBytes)(obj))
37
+ else if ((0, utils_ts_1.isBytes)(obj))
34
38
  return Uint8Array.from(obj);
35
39
  // immutable
36
40
  else if (['number', 'bigint', 'boolean', 'string', 'undefined'].includes(typeof obj))
@@ -68,7 +72,7 @@ var SigHash;
68
72
  SigHash[SigHash["SINGLE_ANYONECANPAY"] = 131] = "SINGLE_ANYONECANPAY";
69
73
  })(SigHash || (exports.SigHash = SigHash = {}));
70
74
  function getTaprootKeys(privKey, pubKey, internalKey, merkleRoot = P.EMPTY) {
71
- if ((0, utils_js_1.equalBytes)(internalKey, pubKey)) {
75
+ if ((0, utils_ts_1.equalBytes)(internalKey, pubKey)) {
72
76
  privKey = u.taprootTweakPrivKey(privKey, merkleRoot);
73
77
  pubKey = u.pubSchnorr(privKey);
74
78
  }
@@ -166,6 +170,149 @@ function validateOpts(opts) {
166
170
  }
167
171
  return Object.freeze(_opts);
168
172
  }
173
+ // NOTE: we cannot do this inside PSBTInput coder, because there is no index/txid at this point!
174
+ function validateInput(i) {
175
+ if (i.nonWitnessUtxo && i.index !== undefined) {
176
+ const last = i.nonWitnessUtxo.outputs.length - 1;
177
+ if (i.index > last)
178
+ throw new Error(`validateInput: index(${i.index}) not in nonWitnessUtxo`);
179
+ const prevOut = i.nonWitnessUtxo.outputs[i.index];
180
+ if (i.witnessUtxo &&
181
+ (!(0, utils_ts_1.equalBytes)(i.witnessUtxo.script, prevOut.script) || i.witnessUtxo.amount !== prevOut.amount))
182
+ throw new Error('validateInput: witnessUtxo different from nonWitnessUtxo');
183
+ if (i.txid) {
184
+ const outputs = i.nonWitnessUtxo.outputs;
185
+ if (outputs.length - 1 < i.index)
186
+ throw new Error('nonWitnessUtxo: incorect output index');
187
+ // At this point, we are using previous tx output to create new input.
188
+ // Script safety checks are unnecessary:
189
+ // - User has no control over previous tx. If somebody send money in same tx
190
+ // as unspendable output, we still want user able to spend money
191
+ // - We still want some checks to notify user about possible errors early
192
+ // in case user wants to use wrong input by mistake
193
+ // - Worst case: tx will be rejected by nodes. Still better than disallowing user
194
+ // to spend real input, no matter how broken it looks
195
+ const tx = Transaction.fromRaw(script_ts_1.RawTx.encode(i.nonWitnessUtxo), {
196
+ allowUnknownOutputs: true,
197
+ disableScriptCheck: true,
198
+ allowUnknownInputs: true,
199
+ });
200
+ const txid = base_1.hex.encode(i.txid);
201
+ // PSBTv2 vectors have non-final tx in inputs
202
+ if (tx.isFinal && tx.id !== txid)
203
+ throw new Error(`nonWitnessUtxo: wrong txid, exp=${txid} got=${tx.id}`);
204
+ }
205
+ }
206
+ return i;
207
+ }
208
+ // Normalizes input
209
+ function getPrevOut(input) {
210
+ if (input.nonWitnessUtxo) {
211
+ if (input.index === undefined)
212
+ throw new Error('Unknown input index');
213
+ return input.nonWitnessUtxo.outputs[input.index];
214
+ }
215
+ else if (input.witnessUtxo)
216
+ return input.witnessUtxo;
217
+ else
218
+ throw new Error('Cannot find previous output info');
219
+ }
220
+ function normalizeInput(i, cur, allowedFields, disableScriptCheck = false, allowUnknown = false) {
221
+ let { nonWitnessUtxo, txid } = i;
222
+ // String support for common fields. We usually prefer Uint8Array to avoid errors
223
+ // like hex looking string accidentally passed, however, in case of nonWitnessUtxo
224
+ // it is better to expect string, since constructing this complex object will be
225
+ // difficult for user
226
+ if (typeof nonWitnessUtxo === 'string')
227
+ nonWitnessUtxo = base_1.hex.decode(nonWitnessUtxo);
228
+ if ((0, utils_ts_1.isBytes)(nonWitnessUtxo))
229
+ nonWitnessUtxo = script_ts_1.RawTx.decode(nonWitnessUtxo);
230
+ if (!('nonWitnessUtxo' in i) && nonWitnessUtxo === undefined)
231
+ nonWitnessUtxo = cur?.nonWitnessUtxo;
232
+ if (typeof txid === 'string')
233
+ txid = base_1.hex.decode(txid);
234
+ // TODO: if we have nonWitnessUtxo, we can extract txId from here
235
+ if (txid === undefined)
236
+ txid = cur?.txid;
237
+ let res = { ...cur, ...i, nonWitnessUtxo, txid };
238
+ if (!('nonWitnessUtxo' in i) && res.nonWitnessUtxo === undefined)
239
+ delete res.nonWitnessUtxo;
240
+ if (res.sequence === undefined)
241
+ res.sequence = exports.DEFAULT_SEQUENCE;
242
+ if (res.tapMerkleRoot === null)
243
+ delete res.tapMerkleRoot;
244
+ res = psbt.mergeKeyMap(psbt.PSBTInput, res, cur, allowedFields, allowUnknown);
245
+ psbt.PSBTInputCoder.encode(res); // Validates that everything is correct at this point
246
+ let prevOut;
247
+ if (res.nonWitnessUtxo && res.index !== undefined)
248
+ prevOut = res.nonWitnessUtxo.outputs[res.index];
249
+ else if (res.witnessUtxo)
250
+ prevOut = res.witnessUtxo;
251
+ if (prevOut && !disableScriptCheck)
252
+ (0, payment_ts_1.checkScript)(prevOut && prevOut.script, res.redeemScript, res.witnessScript);
253
+ return res;
254
+ }
255
+ function getInputType(input, allowLegacyWitnessUtxo = false) {
256
+ let txType = 'legacy';
257
+ let defaultSighash = SignatureHash.ALL;
258
+ const prevOut = getPrevOut(input);
259
+ const first = payment_ts_1.OutScript.decode(prevOut.script);
260
+ let type = first.type;
261
+ let cur = first;
262
+ const stack = [first];
263
+ if (first.type === 'tr') {
264
+ defaultSighash = SignatureHash.DEFAULT;
265
+ return {
266
+ txType: 'taproot',
267
+ type: 'tr',
268
+ last: first,
269
+ lastScript: prevOut.script,
270
+ defaultSighash,
271
+ sighash: input.sighashType || defaultSighash,
272
+ };
273
+ }
274
+ else {
275
+ if (first.type === 'wpkh' || first.type === 'wsh')
276
+ txType = 'segwit';
277
+ if (first.type === 'sh') {
278
+ if (!input.redeemScript)
279
+ throw new Error('inputType: sh without redeemScript');
280
+ let child = payment_ts_1.OutScript.decode(input.redeemScript);
281
+ if (child.type === 'wpkh' || child.type === 'wsh')
282
+ txType = 'segwit';
283
+ stack.push(child);
284
+ cur = child;
285
+ type += `-${child.type}`;
286
+ }
287
+ // wsh can be inside sh
288
+ if (cur.type === 'wsh') {
289
+ if (!input.witnessScript)
290
+ throw new Error('inputType: wsh without witnessScript');
291
+ let child = payment_ts_1.OutScript.decode(input.witnessScript);
292
+ if (child.type === 'wsh')
293
+ txType = 'segwit';
294
+ stack.push(child);
295
+ cur = child;
296
+ type += `-${child.type}`;
297
+ }
298
+ const last = stack[stack.length - 1];
299
+ if (last.type === 'sh' || last.type === 'wsh')
300
+ throw new Error('inputType: sh/wsh cannot be terminal type');
301
+ const lastScript = payment_ts_1.OutScript.encode(last);
302
+ const res = {
303
+ type,
304
+ txType,
305
+ last,
306
+ lastScript,
307
+ defaultSighash,
308
+ sighash: input.sighashType || defaultSighash,
309
+ };
310
+ if (txType === 'legacy' && !allowLegacyWitnessUtxo && !input.nonWitnessUtxo) {
311
+ throw new Error(`Transaction/sign: legacy input without nonWitnessUtxo, can result in attack that forces paying higher fees. Pass allowLegacyWitnessUtxo=true, if you sure`);
312
+ }
313
+ return res;
314
+ }
315
+ }
169
316
  class Transaction {
170
317
  constructor(opts = {}) {
171
318
  this.global = {};
@@ -179,7 +326,7 @@ class Transaction {
179
326
  }
180
327
  // Import
181
328
  static fromRaw(raw, opts = {}) {
182
- const parsed = script_js_1.RawTx.decode(raw);
329
+ const parsed = script_ts_1.RawTx.decode(raw);
183
330
  const tx = new Transaction({ ...opts, version: parsed.version, lockTime: parsed.lockTime });
184
331
  for (const o of parsed.outputs)
185
332
  tx.addOutput(o);
@@ -215,7 +362,7 @@ class Transaction {
215
362
  const tx = new Transaction({ ...opts, version, lockTime, PSBTVersion });
216
363
  // We need slice here, because otherwise
217
364
  const inputCount = PSBTVersion === 0 ? unsigned?.inputs.length : parsed.global.inputCount;
218
- tx.inputs = parsed.inputs.slice(0, inputCount).map((i, j) => ({
365
+ tx.inputs = parsed.inputs.slice(0, inputCount).map((i, j) => validateInput({
219
366
  finalScriptSig: P.EMPTY,
220
367
  ...parsed.global.unsignedTx?.inputs[j],
221
368
  ...i,
@@ -238,7 +385,7 @@ class Transaction {
238
385
  // 'PSBT version=0 export for transaction without inputs disabled, please use version=2. Please check `toPSBT` method for explanation.'
239
386
  // );
240
387
  // }
241
- const inputs = this.inputs.map((i) => psbt.cleanPSBTFields(PSBTVersion, psbt.PSBTInput, i));
388
+ const inputs = this.inputs.map((i) => validateInput(psbt.cleanPSBTFields(PSBTVersion, psbt.PSBTInput, i)));
242
389
  for (const inp of inputs) {
243
390
  // Don't serialize empty fields
244
391
  if (inp.partialSig && !inp.partialSig.length)
@@ -257,7 +404,7 @@ class Transaction {
257
404
  - Parsing of PSBTv0 depends on unsignedTx (it looks for input count here)
258
405
  - BIP-174 requires old serialization format (without witnesses) inside global, which solves this
259
406
  */
260
- global.unsignedTx = script_js_1.RawOldTx.decode(script_js_1.RawOldTx.encode({
407
+ global.unsignedTx = script_ts_1.RawOldTx.decode(script_ts_1.RawOldTx.encode({
261
408
  version: this.version,
262
409
  lockTime: this.lockTime,
263
410
  inputs: this.inputs.map(inputBeforeSign).map((i) => ({
@@ -402,25 +549,25 @@ class Transaction {
402
549
  let out = 32;
403
550
  // Outputs
404
551
  const outputs = this.outputs.map(outputBeforeSign);
405
- out += 4 * script_js_1.CompactSizeLen.encode(this.outputs.length).length;
552
+ out += 4 * script_ts_1.CompactSizeLen.encode(this.outputs.length).length;
406
553
  for (const o of outputs)
407
- out += 32 + 4 * script_js_1.VarBytes.encode(o.script).length;
554
+ out += 32 + 4 * script_ts_1.VarBytes.encode(o.script).length;
408
555
  // Inputs
409
556
  if (this.hasWitnesses)
410
557
  out += 2;
411
- out += 4 * script_js_1.CompactSizeLen.encode(this.inputs.length).length;
558
+ out += 4 * script_ts_1.CompactSizeLen.encode(this.inputs.length).length;
412
559
  for (const i of this.inputs) {
413
- out += 160 + 4 * script_js_1.VarBytes.encode(i.finalScriptSig || P.EMPTY).length;
560
+ out += 160 + 4 * script_ts_1.VarBytes.encode(i.finalScriptSig || P.EMPTY).length;
414
561
  if (this.hasWitnesses && i.finalScriptWitness)
415
- out += script_js_1.RawWitness.encode(i.finalScriptWitness).length;
562
+ out += script_ts_1.RawWitness.encode(i.finalScriptWitness).length;
416
563
  }
417
564
  return out;
418
565
  }
419
566
  get vsize() {
420
- return (0, utxo_js_1.toVsize)(this.weight);
567
+ return (0, exports.toVsize)(this.weight);
421
568
  }
422
569
  toBytes(withScriptSig = false, withWitness = false) {
423
- return script_js_1.RawTx.encode({
570
+ return script_ts_1.RawTx.encode({
424
571
  version: this.version,
425
572
  lockTime: this.lockTime,
426
573
  inputs: this.inputs.map(inputBeforeSign).map((i) => ({
@@ -464,7 +611,7 @@ class Transaction {
464
611
  addInput(input, _ignoreSignStatus = false) {
465
612
  if (!_ignoreSignStatus && !this.signStatus().addInput)
466
613
  throw new Error('Tx has signed inputs, cannot add new one');
467
- this.inputs.push((0, utxo_js_1.normalizeInput)(input, undefined, undefined, this.opts.disableScriptCheck));
614
+ this.inputs.push(normalizeInput(input, undefined, undefined, this.opts.disableScriptCheck));
468
615
  return this.inputs.length - 1;
469
616
  }
470
617
  updateInput(idx, input, _ignoreSignStatus = false) {
@@ -475,7 +622,7 @@ class Transaction {
475
622
  if (!status.addInput || status.inputs.includes(idx))
476
623
  allowedFields = psbt.PSBTInputUnsignedKeys;
477
624
  }
478
- this.inputs[idx] = (0, utxo_js_1.normalizeInput)(input, this.inputs[idx], allowedFields, this.opts.disableScriptCheck, this.opts.allowUnknown);
625
+ this.inputs[idx] = normalizeInput(input, this.inputs[idx], allowedFields, this.opts.disableScriptCheck, this.opts.allowUnknown);
479
626
  }
480
627
  // Output stuff
481
628
  checkOutputIdx(idx) {
@@ -486,11 +633,11 @@ class Transaction {
486
633
  this.checkOutputIdx(idx);
487
634
  return cloneDeep(this.outputs[idx]);
488
635
  }
489
- getOutputAddress(idx, network = utils_js_1.NETWORK) {
636
+ getOutputAddress(idx, network = utils_ts_1.NETWORK) {
490
637
  const out = this.getOutput(idx);
491
638
  if (!out.script)
492
639
  return;
493
- return (0, payment_js_1.Address)(network).encode(payment_js_1.OutScript.decode(out.script));
640
+ return (0, payment_ts_1.Address)(network).encode(payment_ts_1.OutScript.decode(out.script));
494
641
  }
495
642
  get outputsLength() {
496
643
  return this.outputs.length;
@@ -512,11 +659,11 @@ class Transaction {
512
659
  psbt.PSBTOutputCoder.encode(res);
513
660
  if (res.script &&
514
661
  !this.opts.allowUnknownOutputs &&
515
- payment_js_1.OutScript.decode(res.script).type === 'unknown') {
662
+ payment_ts_1.OutScript.decode(res.script).type === 'unknown') {
516
663
  throw new Error('Transaction/output: unknown output script type, there is a chance that input is unspendable. Pass allowUnknownOutputs=true, if you sure');
517
664
  }
518
665
  if (!this.opts.disableScriptCheck)
519
- (0, payment_js_1.checkScript)(res.script, res.redeemScript, res.witnessScript);
666
+ (0, payment_ts_1.checkScript)(res.script, res.redeemScript, res.witnessScript);
520
667
  return res;
521
668
  }
522
669
  addOutput(o, _ignoreSignStatus = false) {
@@ -535,14 +682,14 @@ class Transaction {
535
682
  }
536
683
  this.outputs[idx] = this.normalizeOutput(output, this.outputs[idx], allowedFields);
537
684
  }
538
- addOutputAddress(address, amount, network = utils_js_1.NETWORK) {
539
- return this.addOutput({ script: payment_js_1.OutScript.encode((0, payment_js_1.Address)(network).decode(address)), amount });
685
+ addOutputAddress(address, amount, network = utils_ts_1.NETWORK) {
686
+ return this.addOutput({ script: payment_ts_1.OutScript.encode((0, payment_ts_1.Address)(network).decode(address)), amount });
540
687
  }
541
688
  // Utils
542
689
  get fee() {
543
690
  let res = 0n;
544
691
  for (const i of this.inputs) {
545
- const prevOut = (0, utxo_js_1.getPrevOut)(i);
692
+ const prevOut = getPrevOut(i);
546
693
  if (!prevOut)
547
694
  throw new Error('Empty input amount');
548
695
  res += prevOut.amount;
@@ -562,7 +709,7 @@ class Transaction {
562
709
  throw new Error(`Invalid input idx=${idx}`);
563
710
  if ((isSingle && idx >= this.outputs.length) || idx >= this.inputs.length)
564
711
  return P.U256BE.encode(1n);
565
- prevOutScript = script_js_1.Script.encode(script_js_1.Script.decode(prevOutScript).filter((i) => i !== 'CODESEPARATOR'));
712
+ prevOutScript = script_ts_1.Script.encode(script_ts_1.Script.decode(prevOutScript).filter((i) => i !== 'CODESEPARATOR'));
566
713
  let inputs = this.inputs
567
714
  .map(inputBeforeSign)
568
715
  .map((input, inputIdx) => ({
@@ -583,7 +730,7 @@ class Transaction {
583
730
  else if (isSingle) {
584
731
  outputs = outputs.slice(0, idx).fill(EMPTY_OUTPUT).concat([outputs[idx]]);
585
732
  }
586
- const tmpTx = script_js_1.RawTx.encode({
733
+ const tmpTx = script_ts_1.RawTx.encode({
587
734
  lockTime: this.lockTime,
588
735
  version: this.version,
589
736
  segwitFlag: false,
@@ -604,12 +751,12 @@ class Transaction {
604
751
  if (!isAny && !isSingle && !isNone)
605
752
  sequenceHash = u.sha256x2(...inputs.map((i) => P.U32LE.encode(i.sequence)));
606
753
  if (!isSingle && !isNone) {
607
- outputHash = u.sha256x2(...outputs.map(script_js_1.RawOutput.encode));
754
+ outputHash = u.sha256x2(...outputs.map(script_ts_1.RawOutput.encode));
608
755
  }
609
756
  else if (isSingle && idx < outputs.length)
610
- outputHash = u.sha256x2(script_js_1.RawOutput.encode(outputs[idx]));
757
+ outputHash = u.sha256x2(script_ts_1.RawOutput.encode(outputs[idx]));
611
758
  const input = inputs[idx];
612
- return u.sha256x2(P.I32LE.encode(this.version), inputHash, sequenceHash, P.bytes(32, true).encode(input.txid), P.U32LE.encode(input.index), script_js_1.VarBytes.encode(prevOutScript), P.U64LE.encode(amount), P.U32LE.encode(input.sequence), outputHash, P.U32LE.encode(this.lockTime), P.U32LE.encode(hashType));
759
+ return u.sha256x2(P.I32LE.encode(this.version), inputHash, sequenceHash, P.bytes(32, true).encode(input.txid), P.U32LE.encode(input.index), script_ts_1.VarBytes.encode(prevOutScript), P.U64LE.encode(amount), P.U32LE.encode(input.sequence), outputHash, P.U32LE.encode(this.lockTime), P.U32LE.encode(hashType));
613
760
  }
614
761
  preimageWitnessV1(idx, prevOutScript, hashType, amount, codeSeparator = -1, leafScript, leafVer = 0xc0, annex) {
615
762
  if (!Array.isArray(amount) || this.inputs.length !== amount.length)
@@ -630,36 +777,36 @@ class Transaction {
630
777
  out.push(...[
631
778
  inputs.map(TxHashIdx.encode),
632
779
  amount.map(P.U64LE.encode),
633
- prevOutScript.map(script_js_1.VarBytes.encode),
780
+ prevOutScript.map(script_ts_1.VarBytes.encode),
634
781
  inputs.map((i) => P.U32LE.encode(i.sequence)),
635
- ].map((i) => u.sha256((0, utils_js_1.concatBytes)(...i))));
782
+ ].map((i) => u.sha256((0, utils_ts_1.concatBytes)(...i))));
636
783
  }
637
784
  if (outType === SignatureHash.ALL) {
638
- out.push(u.sha256((0, utils_js_1.concatBytes)(...outputs.map(script_js_1.RawOutput.encode))));
785
+ out.push(u.sha256((0, utils_ts_1.concatBytes)(...outputs.map(script_ts_1.RawOutput.encode))));
639
786
  }
640
787
  const spendType = (annex ? 1 : 0) | (leafScript ? 2 : 0);
641
788
  out.push(new Uint8Array([spendType]));
642
789
  if (inType === SignatureHash.ANYONECANPAY) {
643
790
  const inp = inputs[idx];
644
- out.push(TxHashIdx.encode(inp), P.U64LE.encode(amount[idx]), script_js_1.VarBytes.encode(prevOutScript[idx]), P.U32LE.encode(inp.sequence));
791
+ out.push(TxHashIdx.encode(inp), P.U64LE.encode(amount[idx]), script_ts_1.VarBytes.encode(prevOutScript[idx]), P.U32LE.encode(inp.sequence));
645
792
  }
646
793
  else
647
794
  out.push(P.U32LE.encode(idx));
648
795
  if (spendType & 1)
649
- out.push(u.sha256(script_js_1.VarBytes.encode(annex || P.EMPTY)));
796
+ out.push(u.sha256(script_ts_1.VarBytes.encode(annex || P.EMPTY)));
650
797
  if (outType === SignatureHash.SINGLE)
651
- out.push(idx < outputs.length ? u.sha256(script_js_1.RawOutput.encode(outputs[idx])) : EMPTY32);
798
+ out.push(idx < outputs.length ? u.sha256(script_ts_1.RawOutput.encode(outputs[idx])) : EMPTY32);
652
799
  if (leafScript)
653
- out.push((0, payment_js_1.tapLeafHash)(leafScript, leafVer), P.U8.encode(0), P.I32LE.encode(codeSeparator));
800
+ out.push((0, payment_ts_1.tapLeafHash)(leafScript, leafVer), P.U8.encode(0), P.I32LE.encode(codeSeparator));
654
801
  return u.tagSchnorr('TapSighash', ...out);
655
802
  }
656
803
  // Signer can be privateKey OR instance of bip32 HD stuff
657
804
  signIdx(privateKey, idx, allowedSighash, _auxRand) {
658
805
  this.checkInputIdx(idx);
659
806
  const input = this.inputs[idx];
660
- const inputType = (0, utxo_js_1.getInputType)(input, this.opts.allowLegacyWitnessUtxo);
807
+ const inputType = getInputType(input, this.opts.allowLegacyWitnessUtxo);
661
808
  // Handle BIP32 HDKey
662
- if (!(0, utils_js_1.isBytes)(privateKey)) {
809
+ if (!(0, utils_ts_1.isBytes)(privateKey)) {
663
810
  if (!input.bip32Derivation || !input.bip32Derivation.length)
664
811
  throw new Error('bip32Derivation: empty');
665
812
  const signers = input.bip32Derivation
@@ -668,7 +815,7 @@ class Transaction {
668
815
  let s = privateKey;
669
816
  for (const i of path)
670
817
  s = s.deriveChild(i);
671
- if (!(0, utils_js_1.equalBytes)(s.publicKey, pubKey))
818
+ if (!(0, utils_ts_1.equalBytes)(s.publicKey, pubKey))
672
819
  throw new Error('bip32Derivation: wrong pubKey');
673
820
  if (!s.privateKey)
674
821
  throw new Error('bip32Derivation: no privateKey');
@@ -702,9 +849,9 @@ class Transaction {
702
849
  }
703
850
  // Actual signing
704
851
  // Taproot
705
- const prevOut = (0, utxo_js_1.getPrevOut)(input);
852
+ const prevOut = getPrevOut(input);
706
853
  if (inputType.txType === 'taproot') {
707
- const prevOuts = this.inputs.map(utxo_js_1.getPrevOut);
854
+ const prevOuts = this.inputs.map(getPrevOut);
708
855
  const prevOutScript = prevOuts.map((i) => i.script);
709
856
  const amount = prevOuts.map((i) => i.amount);
710
857
  let signed = false;
@@ -717,9 +864,9 @@ class Transaction {
717
864
  // priv key to be provided
718
865
  const { pubKey, privKey } = getTaprootKeys(privateKey, schnorrPub, input.tapInternalKey, merkleRoot);
719
866
  const [taprootPubKey, _] = u.taprootTweakPubkey(input.tapInternalKey, merkleRoot);
720
- if ((0, utils_js_1.equalBytes)(taprootPubKey, pubKey)) {
867
+ if ((0, utils_ts_1.equalBytes)(taprootPubKey, pubKey)) {
721
868
  const hash = this.preimageWitnessV1(idx, prevOutScript, sighash, amount);
722
- const sig = (0, utils_js_1.concatBytes)(u.signSchnorr(hash, privKey, _auxRand), sighash !== SignatureHash.DEFAULT ? new Uint8Array([sighash]) : P.EMPTY);
869
+ const sig = (0, utils_ts_1.concatBytes)(u.signSchnorr(hash, privKey, _auxRand), sighash !== SignatureHash.DEFAULT ? new Uint8Array([sighash]) : P.EMPTY);
723
870
  this.updateInput(idx, { tapKeySig: sig }, true);
724
871
  signed = true;
725
872
  }
@@ -728,16 +875,16 @@ class Transaction {
728
875
  input.tapScriptSig = input.tapScriptSig || [];
729
876
  for (const [_, _script] of input.tapLeafScript) {
730
877
  const script = _script.subarray(0, -1);
731
- const scriptDecoded = script_js_1.Script.decode(script);
878
+ const scriptDecoded = script_ts_1.Script.decode(script);
732
879
  const ver = _script[_script.length - 1];
733
- const hash = (0, payment_js_1.tapLeafHash)(script, ver);
880
+ const hash = (0, payment_ts_1.tapLeafHash)(script, ver);
734
881
  // NOTE: no need to tweak internal key here, since we don't support nested p2tr
735
- const pos = scriptDecoded.findIndex((i) => (0, utils_js_1.isBytes)(i) && (0, utils_js_1.equalBytes)(i, schnorrPub));
882
+ const pos = scriptDecoded.findIndex((i) => (0, utils_ts_1.isBytes)(i) && (0, utils_ts_1.equalBytes)(i, schnorrPub));
736
883
  // Skip if there is no public key in tapLeafScript
737
884
  if (pos === -1)
738
885
  continue;
739
886
  const msg = this.preimageWitnessV1(idx, prevOutScript, sighash, amount, undefined, script, ver);
740
- const sig = (0, utils_js_1.concatBytes)(u.signSchnorr(msg, privateKey, _auxRand), sighash !== SignatureHash.DEFAULT ? new Uint8Array([sighash]) : P.EMPTY);
887
+ const sig = (0, utils_ts_1.concatBytes)(u.signSchnorr(msg, privateKey, _auxRand), sighash !== SignatureHash.DEFAULT ? new Uint8Array([sighash]) : P.EMPTY);
741
888
  this.updateInput(idx, { tapScriptSig: [[{ pubKey: schnorrPub, leafHash: hash }, sig]] }, true);
742
889
  signed = true;
743
890
  }
@@ -753,8 +900,8 @@ class Transaction {
753
900
  // Check if script has public key or its has inside
754
901
  let hasPubkey = false;
755
902
  const pubKeyHash = u.hash160(pubKey);
756
- for (const i of script_js_1.Script.decode(inputType.lastScript)) {
757
- if ((0, utils_js_1.isBytes)(i) && ((0, utils_js_1.equalBytes)(i, pubKey) || (0, utils_js_1.equalBytes)(i, pubKeyHash)))
903
+ for (const i of script_ts_1.Script.decode(inputType.lastScript)) {
904
+ if ((0, utils_ts_1.isBytes)(i) && ((0, utils_ts_1.equalBytes)(i, pubKey) || (0, utils_ts_1.equalBytes)(i, pubKeyHash)))
758
905
  hasPubkey = true;
759
906
  }
760
907
  if (!hasPubkey)
@@ -767,14 +914,14 @@ class Transaction {
767
914
  let script = inputType.lastScript;
768
915
  // If wpkh OR sh-wpkh, wsh-wpkh is impossible, so looks ok
769
916
  if (inputType.last.type === 'wpkh')
770
- script = payment_js_1.OutScript.encode({ type: 'pkh', hash: inputType.last.hash });
917
+ script = payment_ts_1.OutScript.encode({ type: 'pkh', hash: inputType.last.hash });
771
918
  hash = this.preimageWitnessV0(idx, script, sighash, prevOut.amount);
772
919
  }
773
920
  else
774
921
  throw new Error(`Transaction/sign: unknown tx type: ${inputType.txType}`);
775
922
  const sig = u.signECDSA(hash, privateKey, this.opts.lowR);
776
923
  this.updateInput(idx, {
777
- partialSig: [[pubKey, (0, utils_js_1.concatBytes)(sig, new Uint8Array([sighash]))]],
924
+ partialSig: [[pubKey, (0, utils_ts_1.concatBytes)(sig, new Uint8Array([sighash]))]],
778
925
  }, true);
779
926
  }
780
927
  return true;
@@ -804,7 +951,7 @@ class Transaction {
804
951
  if (this.fee < 0n)
805
952
  throw new Error('Outputs spends more than inputs amount');
806
953
  const input = this.inputs[idx];
807
- const inputType = (0, utxo_js_1.getInputType)(input, this.opts.allowLegacyWitnessUtxo);
954
+ const inputType = getInputType(input, this.opts.allowLegacyWitnessUtxo);
808
955
  // Taproot finalize
809
956
  if (inputType.txType === 'taproot') {
810
957
  if (input.tapKeySig)
@@ -817,16 +964,16 @@ class Transaction {
817
964
  // Last byte is version
818
965
  const script = _script.slice(0, -1);
819
966
  const ver = _script[_script.length - 1];
820
- const outScript = payment_js_1.OutScript.decode(script);
821
- const hash = (0, payment_js_1.tapLeafHash)(script, ver);
822
- const scriptSig = input.tapScriptSig.filter((i) => (0, utils_js_1.equalBytes)(i[0].leafHash, hash));
967
+ const outScript = payment_ts_1.OutScript.decode(script);
968
+ const hash = (0, payment_ts_1.tapLeafHash)(script, ver);
969
+ const scriptSig = input.tapScriptSig.filter((i) => (0, utils_ts_1.equalBytes)(i[0].leafHash, hash));
823
970
  let signatures = [];
824
971
  if (outScript.type === 'tr_ms') {
825
972
  const m = outScript.m;
826
973
  const pubkeys = outScript.pubkeys;
827
974
  let added = 0;
828
975
  for (const pub of pubkeys) {
829
- const sigIdx = scriptSig.findIndex((i) => (0, utils_js_1.equalBytes)(i[0].pubKey, pub));
976
+ const sigIdx = scriptSig.findIndex((i) => (0, utils_ts_1.equalBytes)(i[0].pubKey, pub));
830
977
  // Should have exact amount of signatures (more -- will fail)
831
978
  if (added === m || sigIdx === -1) {
832
979
  signatures.push(P.EMPTY);
@@ -841,7 +988,7 @@ class Transaction {
841
988
  }
842
989
  else if (outScript.type === 'tr_ns') {
843
990
  for (const pub of outScript.pubkeys) {
844
- const sigIdx = scriptSig.findIndex((i) => (0, utils_js_1.equalBytes)(i[0].pubKey, pub));
991
+ const sigIdx = scriptSig.findIndex((i) => (0, utils_ts_1.equalBytes)(i[0].pubKey, pub));
845
992
  if (sigIdx === -1)
846
993
  continue;
847
994
  signatures.push(scriptSig[sigIdx][1]);
@@ -851,10 +998,10 @@ class Transaction {
851
998
  }
852
999
  else if (outScript.type === 'unknown' && this.opts.allowUnknownInputs) {
853
1000
  // Trying our best to sign what we can
854
- const scriptDecoded = script_js_1.Script.decode(script);
1001
+ const scriptDecoded = script_ts_1.Script.decode(script);
855
1002
  signatures = scriptSig
856
1003
  .map(([{ pubKey }, signature]) => {
857
- const pos = scriptDecoded.findIndex((i) => (0, utils_js_1.isBytes)(i) && (0, utils_js_1.equalBytes)(i, pubKey));
1004
+ const pos = scriptDecoded.findIndex((i) => (0, utils_ts_1.isBytes)(i) && (0, utils_ts_1.equalBytes)(i, pubKey));
858
1005
  if (pos === -1)
859
1006
  throw new Error('finalize/taproot: cannot find position of pubkey in script');
860
1007
  return { signature, pos };
@@ -871,7 +1018,7 @@ class Transaction {
871
1018
  for (const c of custom) {
872
1019
  if (!c.finalizeTaproot)
873
1020
  continue;
874
- const scriptDecoded = script_js_1.Script.decode(script);
1021
+ const scriptDecoded = script_ts_1.Script.decode(script);
875
1022
  const csEncoded = c.encode(scriptDecoded);
876
1023
  if (csEncoded === undefined)
877
1024
  continue;
@@ -913,7 +1060,7 @@ class Transaction {
913
1060
  let signatures = [];
914
1061
  // partial: [pubkey, sign]
915
1062
  for (const pub of pubkeys) {
916
- const sign = input.partialSig.find((s) => (0, utils_js_1.equalBytes)(pub, s[0]));
1063
+ const sign = input.partialSig.find((s) => (0, utils_ts_1.equalBytes)(pub, s[0]));
917
1064
  if (!sign)
918
1065
  continue;
919
1066
  signatures.push(sign[1]);
@@ -922,13 +1069,13 @@ class Transaction {
922
1069
  if (signatures.length !== m) {
923
1070
  throw new Error(`Multisig: wrong signatures count, m=${m} n=${pubkeys.length} signatures=${signatures.length}`);
924
1071
  }
925
- inputScript = script_js_1.Script.encode([0, ...signatures]);
1072
+ inputScript = script_ts_1.Script.encode([0, ...signatures]);
926
1073
  }
927
1074
  else if (inputType.last.type === 'pk') {
928
- inputScript = script_js_1.Script.encode([input.partialSig[0][1]]);
1075
+ inputScript = script_ts_1.Script.encode([input.partialSig[0][1]]);
929
1076
  }
930
1077
  else if (inputType.last.type === 'pkh') {
931
- inputScript = script_js_1.Script.encode([input.partialSig[0][1], input.partialSig[0][0]]);
1078
+ inputScript = script_ts_1.Script.encode([input.partialSig[0][1], input.partialSig[0][0]]);
932
1079
  }
933
1080
  else if (inputType.last.type === 'wpkh') {
934
1081
  inputScript = P.EMPTY;
@@ -941,10 +1088,10 @@ class Transaction {
941
1088
  if (inputType.type.includes('wsh-')) {
942
1089
  // P2WSH
943
1090
  if (inputScript.length && inputType.lastScript.length) {
944
- witness = script_js_1.Script.decode(inputScript).map((i) => {
1091
+ witness = script_ts_1.Script.decode(inputScript).map((i) => {
945
1092
  if (i === 0)
946
1093
  return P.EMPTY;
947
- if ((0, utils_js_1.isBytes)(i))
1094
+ if ((0, utils_ts_1.isBytes)(i))
948
1095
  return i;
949
1096
  throw new Error(`Wrong witness op=${i}`);
950
1097
  });
@@ -954,10 +1101,10 @@ class Transaction {
954
1101
  if (inputType.txType === 'segwit')
955
1102
  finalScriptWitness = witness;
956
1103
  if (inputType.type.startsWith('sh-wsh-')) {
957
- finalScriptSig = script_js_1.Script.encode([script_js_1.Script.encode([0, u.sha256(inputType.lastScript)])]);
1104
+ finalScriptSig = script_ts_1.Script.encode([script_ts_1.Script.encode([0, u.sha256(inputType.lastScript)])]);
958
1105
  }
959
1106
  else if (inputType.type.startsWith('sh-')) {
960
- finalScriptSig = script_js_1.Script.encode([...script_js_1.Script.decode(inputScript), inputType.lastScript]);
1107
+ finalScriptSig = script_ts_1.Script.encode([...script_ts_1.Script.decode(inputScript), inputType.lastScript]);
961
1108
  }
962
1109
  else if (inputType.type.startsWith('wsh-')) {
963
1110
  }
@@ -995,11 +1142,11 @@ class Transaction {
995
1142
  throw new Error(`Transaction/combine: different ${k} length this=${this[k].length} other=${other[k].length}`);
996
1143
  }
997
1144
  }
998
- const thisUnsigned = this.global.unsignedTx ? script_js_1.RawOldTx.encode(this.global.unsignedTx) : P.EMPTY;
1145
+ const thisUnsigned = this.global.unsignedTx ? script_ts_1.RawOldTx.encode(this.global.unsignedTx) : P.EMPTY;
999
1146
  const otherUnsigned = other.global.unsignedTx
1000
- ? script_js_1.RawOldTx.encode(other.global.unsignedTx)
1147
+ ? script_ts_1.RawOldTx.encode(other.global.unsignedTx)
1001
1148
  : P.EMPTY;
1002
- if (!(0, utils_js_1.equalBytes)(thisUnsigned, otherUnsigned))
1149
+ if (!(0, utils_ts_1.equalBytes)(thisUnsigned, otherUnsigned))
1003
1150
  throw new Error(`Transaction/combine: different unsigned tx`);
1004
1151
  this.global = psbt.mergeKeyMap(psbt.PSBTGlobal, this.global, other.global, undefined, this.opts.allowUnknown);
1005
1152
  for (let i = 0; i < this.inputs.length; i++)