@scure/btc-signer 1.7.0 → 1.8.1

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