@scure/btc-signer 1.3.2 → 1.5.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 (94) hide show
  1. package/README.md +2 -5
  2. package/_type_test.d.ts.map +1 -0
  3. package/_type_test.js.map +1 -0
  4. package/esm/_type_test.d.ts +2 -0
  5. package/esm/_type_test.js.map +1 -0
  6. package/{lib → esm}/index.d.ts +2 -2
  7. package/esm/index.d.ts.map +1 -0
  8. package/{lib/esm → esm}/index.js +1 -1
  9. package/esm/index.js.map +1 -0
  10. package/{lib → esm}/payment.d.ts.map +1 -1
  11. package/{lib/esm → esm}/payment.js +1 -1
  12. package/esm/payment.js.map +1 -0
  13. package/{lib → esm}/psbt.d.ts +0 -14
  14. package/esm/psbt.d.ts.map +1 -0
  15. package/{lib/esm → esm}/psbt.js +4 -5
  16. package/esm/psbt.js.map +1 -0
  17. package/{lib → esm}/script.d.ts +14 -0
  18. package/{lib → esm}/script.d.ts.map +1 -1
  19. package/{lib/esm → esm}/script.js +7 -0
  20. package/esm/script.js.map +1 -0
  21. package/{lib → esm}/transaction.d.ts +15 -9
  22. package/esm/transaction.d.ts.map +1 -0
  23. package/{lib/esm → esm}/transaction.js +36 -9
  24. package/esm/transaction.js.map +1 -0
  25. package/{lib → esm}/utils.d.ts +3 -3
  26. package/esm/utils.d.ts.map +1 -0
  27. package/esm/utils.js.map +1 -0
  28. package/{lib → esm}/utxo.d.ts +16 -19
  29. package/esm/utxo.d.ts.map +1 -0
  30. package/{lib/esm → esm}/utxo.js +66 -28
  31. package/esm/utxo.js.map +1 -0
  32. package/index.d.ts +20 -0
  33. package/index.d.ts.map +1 -0
  34. package/{lib/index.js → index.js} +2 -1
  35. package/index.js.map +1 -0
  36. package/package.json +43 -43
  37. package/payment.d.ts +177 -0
  38. package/payment.d.ts.map +1 -0
  39. package/{lib/payment.js → payment.js} +12 -12
  40. package/payment.js.map +1 -0
  41. package/psbt.d.ts +820 -0
  42. package/psbt.d.ts.map +1 -0
  43. package/{lib/psbt.js → psbt.js} +10 -11
  44. package/psbt.js.map +1 -0
  45. package/script.d.ts +168 -0
  46. package/script.d.ts.map +1 -0
  47. package/{lib/script.js → script.js} +10 -3
  48. package/script.js.map +1 -0
  49. package/src/index.ts +1 -1
  50. package/src/payment.ts +3 -3
  51. package/src/psbt.ts +4 -5
  52. package/src/script.ts +7 -0
  53. package/src/transaction.ts +41 -9
  54. package/src/utxo.ts +81 -24
  55. package/transaction.d.ts +229 -0
  56. package/transaction.d.ts.map +1 -0
  57. package/{lib/transaction.js → transaction.js} +48 -21
  58. package/transaction.js.map +1 -0
  59. package/utils.d.ts +30 -0
  60. package/utils.d.ts.map +1 -0
  61. package/{lib/utils.js → utils.js} +7 -7
  62. package/utils.js.map +1 -0
  63. package/utxo.d.ts +248 -0
  64. package/utxo.d.ts.map +1 -0
  65. package/{lib/utxo.js → utxo.js} +71 -33
  66. package/utxo.js.map +1 -0
  67. package/lib/_type_test.js.map +0 -1
  68. package/lib/esm/_type_test.js.map +0 -1
  69. package/lib/esm/index.js.map +0 -1
  70. package/lib/esm/payment.js.map +0 -1
  71. package/lib/esm/psbt.js.map +0 -1
  72. package/lib/esm/script.js.map +0 -1
  73. package/lib/esm/transaction.js.map +0 -1
  74. package/lib/esm/utils.js.map +0 -1
  75. package/lib/esm/utxo.js.map +0 -1
  76. package/lib/index.d.ts.map +0 -1
  77. package/lib/index.js.map +0 -1
  78. package/lib/payment.js.map +0 -1
  79. package/lib/psbt.d.ts.map +0 -1
  80. package/lib/psbt.js.map +0 -1
  81. package/lib/script.js.map +0 -1
  82. package/lib/transaction.d.ts.map +0 -1
  83. package/lib/transaction.js.map +0 -1
  84. package/lib/utils.d.ts.map +0 -1
  85. package/lib/utils.js.map +0 -1
  86. package/lib/utxo.d.ts.map +0 -1
  87. package/lib/utxo.js.map +0 -1
  88. /package/{lib/_type_test.d.ts → _type_test.d.ts} +0 -0
  89. /package/{lib/_type_test.js → _type_test.js} +0 -0
  90. /package/{lib → esm}/_type_test.d.ts.map +0 -0
  91. /package/{lib/esm → esm}/_type_test.js +0 -0
  92. /package/{lib/esm → esm}/package.json +0 -0
  93. /package/{lib → esm}/payment.d.ts +0 -0
  94. /package/{lib/esm → esm}/utils.js +0 -0
package/src/utxo.ts CHANGED
@@ -268,12 +268,15 @@ export type EstimatorOpts = TxOpts & {
268
268
  bip69?: boolean; // https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki
269
269
  network?: typeof NETWORK;
270
270
  dust?: number; // how much vbytes considered dust?
271
+ dustRelayFeeRate?: bigint; // fee per dust byte (DUST_RELAY_TX_FEE)
271
272
  createTx?: boolean; // Create tx inside selection
273
+ requiredInputs?: psbt.TransactionInputUpdate[]; // these inputs always will be used
274
+ allowSameUtxo?: boolean; // allow using UTXO multiple times (for test purposes)
272
275
  };
273
276
 
274
277
  function getScript(o: Output, opts: TxOpts = {}, network = NETWORK) {
275
278
  let script;
276
- if ('script' in o && o.script instanceof Uint8Array) {
279
+ if ('script' in o && isBytes(o.script)) {
277
280
  script = o.script;
278
281
  }
279
282
  if ('address' in o) {
@@ -282,7 +285,12 @@ function getScript(o: Output, opts: TxOpts = {}, network = NETWORK) {
282
285
  script = OutScript.encode(Address(network).decode(o.address));
283
286
  }
284
287
  if (!script) throw new Error('Estimator: wrong output script');
285
- if (typeof o.amount !== 'bigint') throw new Error(`Estimator: wrong output amount=${o.amount}`);
288
+ if (typeof o.amount !== 'bigint')
289
+ throw new Error(
290
+ `Estimator: wrong output amount=${
291
+ o.amount
292
+ }, should be of type bigint but got ${typeof o.amount}.`
293
+ );
286
294
  if (script && !opts.allowUnknownOutputs && OutScript.decode(script).type === 'unknown') {
287
295
  throw new Error(
288
296
  'Estimator: unknown output script type, there is a chance that input is unspendable. Pass allowUnknownOutputs=true, if you sure'
@@ -310,6 +318,7 @@ export class _Estimator {
310
318
  private baseWeight: number;
311
319
  private changeWeight: number;
312
320
  private amount: bigint;
321
+ private requiredIndices: number[] = [];
313
322
  private normalizedInputs: {
314
323
  inputType: ReturnType<typeof getInputType>;
315
324
  normalized: ReturnType<typeof normalizeInput>;
@@ -317,24 +326,51 @@ export class _Estimator {
317
326
  value: bigint;
318
327
  estimate: { weight: number; hasWitnesses: boolean };
319
328
  }[];
320
- // https://github.com/bitcoin/bitcoin/blob/f90603ac6d24f5263649675d51233f1fce8b2ecd/src/policy/policy.cpp#L44
321
- // 32 + 4 + 1 + 107 + 4
322
329
  // Dust used in accumExact + change address algo
323
330
  // - change address: can be smaller for segwit
324
331
  // - accumExact: ???
325
- private dust = 148n; // compat with coinselect
326
-
332
+ private dust: bigint; // total dust limit (3||opts.dustRelayFeeRate * 182||opts.dust). Default: 546
327
333
  constructor(
328
- private inputs: psbt.TransactionInputUpdate[],
334
+ inputs: psbt.TransactionInputUpdate[],
329
335
  private outputs: Output[],
330
336
  private opts: EstimatorOpts
331
337
  ) {
332
338
  if (typeof opts.feePerByte !== 'bigint')
333
- throw new Error(`Estimator: wrong feePerByte=${opts.feePerByte}`);
334
- if (opts.dust) {
335
- if (typeof opts.dust !== 'bigint') throw new Error(`Estimator: wrong dust=${opts.dust}`);
336
- this.dust = opts.dust;
339
+ throw new Error(
340
+ `Estimator: wrong feePerByte=${
341
+ opts.feePerByte
342
+ }, should be of type bigint but got ${typeof opts.feePerByte}.`
343
+ );
344
+ // Dust stuff
345
+ // TODO: think about this more:
346
+ // - current dust filters tx which cannot be relayed by core
347
+ // - but actual dust meaning is 'can be this amount spent?'
348
+ // - dust contains full tx size. but we can use other inputs to pay for outputDust (and parially inputsDust)?
349
+ // - not sure if we can spent anything with feePerByte: 3. It will be relayed, but will it be mined?
350
+ // - for now it works exactly as bitcoin-core. But will create change/outputs which cannot be spent (reasonable).
351
+ // Number of bytes needed to create and spend a UTXO.
352
+ // https://github.com/bitcoin/bitcoin/blob/27a770b34b8f1dbb84760f442edb3e23a0c2420b/src/policy/policy.cpp#L28-L41
353
+ const inputsDust = 32 + 4 + 1 + 107 + 4; // NOTE: can be smaller for segwit tx?
354
+ const outputDust = 34; // NOTE: 'nSize = GetSerializeSize(txout)'
355
+ const dustBytes = opts.dust === undefined ? BigInt(inputsDust + outputDust) : opts.dust;
356
+ if (typeof dustBytes !== 'bigint') {
357
+ throw new Error(
358
+ `Estimator: wrong dust=${opts.dust}, should be of type bigint but got ${typeof opts.dust}.`
359
+ );
337
360
  }
361
+ // 3 sat/vb is the default minimum fee rate used to calculate dust thresholds by bitcoin core.
362
+ // 3000 sat/kvb -> 3 sat/vb.
363
+ // https://github.com/bitcoin/bitcoin/blob/27a770b34b8f1dbb84760f442edb3e23a0c2420b/src/policy/policy.h#L55
364
+ const dustFee = opts.dustRelayFeeRate === undefined ? 3n : opts.dustRelayFeeRate;
365
+ if (typeof dustFee !== 'bigint') {
366
+ throw new Error(
367
+ `Estimator: wrong dustRelayFeeRate=${opts.dustRelayFeeRate}, should be of type bigint but got ${typeof opts.dustRelayFeeRate}.`
368
+ );
369
+ }
370
+ // Dust uses feePerbyte by default, but we allow separate dust fee if needed
371
+ this.dust = dustBytes * dustFee;
372
+ if (opts.requiredInputs !== undefined && !Array.isArray(opts.requiredInputs))
373
+ throw new Error(`Estimator: wrong required inputs=${opts.requiredInputs}`);
338
374
  const network = opts.network || NETWORK;
339
375
  let amount = 0n;
340
376
  // Base weight: tx with outputs, no inputs
@@ -356,9 +392,19 @@ export class _Estimator {
356
392
  this.baseWeight = baseWeight;
357
393
  this.changeWeight = changeWeight;
358
394
  this.amount = amount;
359
- this.normalizedInputs = this.inputs.map((i) => {
395
+ const allInputs = Array.from(inputs);
396
+ if (opts.requiredInputs) {
397
+ for (let i = 0; i < opts.requiredInputs.length; i++)
398
+ this.requiredIndices.push(allInputs.push(opts.requiredInputs[i]) - 1);
399
+ }
400
+ const inputKeys = new Set();
401
+ this.normalizedInputs = allInputs.map((i) => {
360
402
  const normalized = normalizeInput(i, undefined, undefined, opts.disableScriptCheck);
361
403
  inputBeforeSign(normalized); // check fields
404
+ const key = `${hex.encode(normalized.txid!)}:${normalized.index}`;
405
+ if (!opts.allowSameUtxo && inputKeys.has(key))
406
+ throw new Error(`Estimator: same input passed multiple times: ${key}`);
407
+ inputKeys.add(key);
362
408
  const inputType = getInputType(normalized, opts.allowLegacyWitnessUtxo);
363
409
  const prev = getPrevOut(normalized);
364
410
  const estimate = estimateInput(inputType, normalized, this.opts);
@@ -367,7 +413,7 @@ export class _Estimator {
367
413
  });
368
414
  }
369
415
  private checkInputIdx(idx: number) {
370
- if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.inputs.length)
416
+ if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.normalizedInputs.length)
371
417
  throw new Error(`Wrong input index=${idx}`);
372
418
  return idx;
373
419
  }
@@ -397,7 +443,7 @@ export class _Estimator {
397
443
 
398
444
  // Sort by value instead of amount
399
445
  get biggest() {
400
- return this.inputs
446
+ return this.normalizedInputs
401
447
  .map((_i, j) => j)
402
448
  .sort((a, b) => _cmpBig(this.normalizedInputs[b].value, this.normalizedInputs[a].value));
403
449
  }
@@ -408,7 +454,7 @@ export class _Estimator {
408
454
  // Otherwise, we have no way to know which tx is oldest
409
455
  // Explorers usually give UTXO in this order.
410
456
  get oldest() {
411
- return this.inputs.map((_i, j) => j);
457
+ return this.normalizedInputs.map((_i, j) => j);
412
458
  }
413
459
  get newest() {
414
460
  return this.oldest.reverse();
@@ -417,7 +463,6 @@ export class _Estimator {
417
463
  // exact(biggest) will select one big utxo which is closer to targetValue+dust, if possible.
418
464
  // If not, it will accumulate largest utxo until value is close to targetValue+dust.
419
465
  accumulate(indices: number[], exact = false, skipNegative = true, all = false) {
420
- const { feePerByte } = this.opts;
421
466
  // TODO: how to handle change addresses?
422
467
  // - cost of input
423
468
  // - cost of change output (if input requires change)
@@ -433,6 +478,22 @@ export class _Estimator {
433
478
  const targetAmount = this.amount;
434
479
  const res = [];
435
480
  let fee;
481
+ for (const idx of this.requiredIndices) {
482
+ this.checkInputIdx(idx);
483
+ const { estimate, amount } = this.normalizedInputs[idx];
484
+ let newWeight = weight + estimate.weight;
485
+ if (!hasWitnesses && estimate.hasWitnesses) newWeight += 2; // enable witness if needed
486
+ const totalWeight = newWeight + 4 * CompactSizeLen.encode(num).length; // number of outputs can change weight
487
+ fee = this.getSatoshi(totalWeight);
488
+ weight = newWeight;
489
+ if (estimate.hasWitnesses) hasWitnesses = true;
490
+ num++;
491
+ inputsAmount += amount;
492
+ res.push(idx);
493
+ // inputsAmount is enough to cover cost of tx
494
+ if (!all && targetAmount + fee <= inputsAmount)
495
+ return { indices: res, fee, weight: totalWeight, total: inputsAmount };
496
+ }
436
497
  for (const idx of indices) {
437
498
  this.checkInputIdx(idx);
438
499
  const { estimate, amount, value } = this.normalizedInputs[idx];
@@ -441,11 +502,7 @@ export class _Estimator {
441
502
  const totalWeight = newWeight + 4 * CompactSizeLen.encode(num).length; // number of outputs can change weight
442
503
  fee = this.getSatoshi(totalWeight);
443
504
  // Best case scenario exact(biggest) -> we find biggest output, less than target+threshold
444
- if (exact) {
445
- const dust = this.dust * feePerByte;
446
- // skip if added value is bigger than dust
447
- if (amount + inputsAmount > targetAmount + fee + dust) continue;
448
- }
505
+ if (exact && amount + inputsAmount > targetAmount + fee + this.dust) continue; // skip if added value is bigger than dust
449
506
  // Negative: cost of using input is more than value provided (negative)
450
507
  // By default 'blackjack' mode in coinselect doesn't use that, which means
451
508
  // it will use negative output if sorted by 'smallest'
@@ -456,7 +513,7 @@ export class _Estimator {
456
513
  inputsAmount += amount;
457
514
  res.push(idx);
458
515
  // inputsAmount is enough to cover cost of tx
459
- if (!all && targetAmount + fee < inputsAmount)
516
+ if (!all && targetAmount + fee <= inputsAmount)
460
517
  return { indices: res, fee, weight: totalWeight, total: inputsAmount };
461
518
  }
462
519
  if (all) {
@@ -477,7 +534,7 @@ export class _Estimator {
477
534
  private select(strategy: SelectionStrategy) {
478
535
  if (strategy === 'all') {
479
536
  return this.accumulate(
480
- this.inputs.map((_, j) => j),
537
+ this.normalizedInputs.map((_, j) => j),
481
538
  false,
482
539
  true,
483
540
  true
@@ -531,7 +588,7 @@ export class _Estimator {
531
588
  outputs = this.sortOutputs(outputs).map((i) => outputs[i]);
532
589
  }
533
590
  const res = {
534
- inputs: inputs.map((i) => this.inputs[i]),
591
+ inputs: inputs.map((i) => this.normalizedInputs[i].normalized),
535
592
  outputs,
536
593
  fee,
537
594
  weight: this.opts.alwaysChange ? s.weight : changeWeight,
@@ -0,0 +1,229 @@
1
+ import * as P from 'micro-packed';
2
+ import { CustomScript } from './payment.js';
3
+ import * as psbt from './psbt.js';
4
+ import { Bytes } from './utils.js';
5
+ interface HDKey {
6
+ publicKey: Bytes;
7
+ privateKey: Bytes;
8
+ fingerprint: number;
9
+ derive(path: string): HDKey;
10
+ deriveChild(index: number): HDKey;
11
+ sign(hash: Bytes): Bytes;
12
+ }
13
+ export type Signer = Bytes | HDKey;
14
+ export declare const PRECISION = 8;
15
+ export declare const DEFAULT_VERSION = 2;
16
+ export declare const DEFAULT_LOCKTIME = 0;
17
+ export declare const DEFAULT_SEQUENCE = 4294967295;
18
+ export declare const Decimal: {
19
+ encode: (from: bigint) => string;
20
+ decode: (to: string) => bigint;
21
+ };
22
+ export declare const def: <T>(value: T | undefined, def: T) => T;
23
+ export declare function cloneDeep<T>(obj: T): T;
24
+ export type TxOpts = {
25
+ version?: number;
26
+ lockTime?: number;
27
+ PSBTVersion?: number;
28
+ /** @deprecated Use `allowUnknownOutputs` */
29
+ allowUnknowOutput?: boolean;
30
+ allowUnknownOutputs?: boolean;
31
+ /** @deprecated Use `allowUnknownInputs` */
32
+ allowUnknowInput?: boolean;
33
+ allowUnknownInputs?: boolean;
34
+ disableScriptCheck?: boolean;
35
+ bip174jsCompat?: boolean;
36
+ allowLegacyWitnessUtxo?: boolean;
37
+ lowR?: boolean;
38
+ customScripts?: CustomScript[];
39
+ };
40
+ /**
41
+ * Internal, exported only for backwards-compat. Use `SigHash` instead.
42
+ * @deprecated
43
+ */
44
+ export declare enum SignatureHash {
45
+ DEFAULT = 0,
46
+ ALL = 1,
47
+ NONE = 2,
48
+ SINGLE = 3,
49
+ ANYONECANPAY = 128
50
+ }
51
+ export declare enum SigHash {
52
+ DEFAULT = 0,
53
+ ALL = 1,
54
+ NONE = 2,
55
+ SINGLE = 3,
56
+ DEFAULT_ANYONECANPAY = 128,
57
+ ALL_ANYONECANPAY = 129,
58
+ NONE_ANYONECANPAY = 130,
59
+ SINGLE_ANYONECANPAY = 131
60
+ }
61
+ export type TransactionInputRequired = {
62
+ txid: Bytes;
63
+ index: number;
64
+ sequence: number;
65
+ finalScriptSig: Bytes;
66
+ };
67
+ export declare function inputBeforeSign(i: psbt.TransactionInput): TransactionInputRequired;
68
+ declare function validateOpts(opts: TxOpts): Readonly<{
69
+ version: number;
70
+ lockTime: number;
71
+ PSBTVersion: number;
72
+ /** @deprecated Use `allowUnknownOutputs` */
73
+ allowUnknowOutput?: boolean;
74
+ allowUnknownOutputs?: boolean;
75
+ /** @deprecated Use `allowUnknownInputs` */
76
+ allowUnknowInput?: boolean;
77
+ allowUnknownInputs?: boolean;
78
+ disableScriptCheck?: boolean;
79
+ bip174jsCompat?: boolean;
80
+ allowLegacyWitnessUtxo?: boolean;
81
+ lowR?: boolean;
82
+ customScripts?: CustomScript[];
83
+ }>;
84
+ export declare class Transaction {
85
+ private global;
86
+ private inputs;
87
+ private outputs;
88
+ readonly opts: ReturnType<typeof validateOpts>;
89
+ constructor(opts?: TxOpts);
90
+ static fromRaw(raw: Bytes, opts?: TxOpts): Transaction;
91
+ static fromPSBT(psbt_: Bytes, opts?: TxOpts): Transaction;
92
+ toPSBT(PSBTVersion?: number): Uint8Array;
93
+ get lockTime(): number;
94
+ get version(): number;
95
+ private inputStatus;
96
+ private inputSighash;
97
+ private signStatus;
98
+ get isFinal(): boolean;
99
+ get hasWitnesses(): boolean;
100
+ get weight(): number;
101
+ get vsize(): number;
102
+ toBytes(withScriptSig?: boolean, withWitness?: boolean): Uint8Array;
103
+ get unsignedTx(): Bytes;
104
+ get hex(): string;
105
+ get hash(): string;
106
+ get id(): string;
107
+ private checkInputIdx;
108
+ getInput(idx: number): psbt.PSBTKeyMapKeys<{
109
+ readonly nonWitnessUtxo: readonly [0, false, P.CoderType<P.StructInput<{
110
+ version: number;
111
+ segwitFlag: boolean | undefined;
112
+ inputs: P.StructInput<{
113
+ txid: any;
114
+ index: any;
115
+ finalScriptSig: any;
116
+ sequence: any;
117
+ }>[];
118
+ outputs: P.StructInput<{
119
+ amount: any;
120
+ script: any;
121
+ }>[];
122
+ witnesses: P.Option<Uint8Array[][]>;
123
+ lockTime: number;
124
+ }>>, readonly [], readonly [0, 2], false];
125
+ readonly witnessUtxo: readonly [1, false, P.CoderType<P.StructInput<{
126
+ amount: bigint;
127
+ script: Uint8Array;
128
+ }>>, readonly [], readonly [0, 2], false];
129
+ readonly partialSig: readonly [2, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
130
+ readonly sighashType: readonly [3, false, P.CoderType<number>, readonly [], readonly [0, 2], false];
131
+ readonly redeemScript: readonly [4, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
132
+ readonly witnessScript: readonly [5, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
133
+ readonly bip32Derivation: readonly [6, P.CoderType<Uint8Array>, P.CoderType<P.StructInput<{
134
+ fingerprint: number;
135
+ path: number[];
136
+ }>>, readonly [], readonly [0, 2], false];
137
+ readonly finalScriptSig: readonly [7, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
138
+ readonly finalScriptWitness: readonly [8, false, P.CoderType<Uint8Array[]>, readonly [], readonly [0, 2], false];
139
+ readonly porCommitment: readonly [9, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
140
+ readonly ripemd160: readonly [10, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
141
+ readonly sha256: readonly [11, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
142
+ readonly hash160: readonly [12, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
143
+ readonly hash256: readonly [13, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
144
+ readonly txid: readonly [14, false, P.CoderType<Uint8Array>, readonly [2], readonly [2], true];
145
+ readonly index: readonly [15, false, P.CoderType<number>, readonly [2], readonly [2], true];
146
+ readonly sequence: readonly [16, false, P.CoderType<number>, readonly [], readonly [2], true];
147
+ readonly requiredTimeLocktime: readonly [17, false, P.CoderType<number>, readonly [], readonly [2], false];
148
+ readonly requiredHeightLocktime: readonly [18, false, P.CoderType<number>, readonly [], readonly [2], false];
149
+ readonly tapKeySig: readonly [19, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
150
+ readonly tapScriptSig: readonly [20, P.CoderType<P.StructInput<{
151
+ pubKey: Uint8Array;
152
+ leafHash: Uint8Array;
153
+ }>>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
154
+ readonly tapLeafScript: readonly [21, P.CoderType<P.StructInput<{
155
+ version: number;
156
+ internalKey: Uint8Array;
157
+ merklePath: Uint8Array[];
158
+ }>>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
159
+ readonly tapBip32Derivation: readonly [22, P.CoderType<Uint8Array>, P.CoderType<P.StructInput<{
160
+ hashes: Uint8Array[];
161
+ der: P.StructInput<{
162
+ fingerprint: any;
163
+ path: any;
164
+ }>;
165
+ }>>, readonly [], readonly [0, 2], false];
166
+ readonly tapInternalKey: readonly [23, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
167
+ readonly tapMerkleRoot: readonly [24, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
168
+ readonly proprietary: readonly [252, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
169
+ }>;
170
+ get inputsLength(): number;
171
+ addInput(input: psbt.TransactionInputUpdate, _ignoreSignStatus?: boolean): number;
172
+ updateInput(idx: number, input: psbt.TransactionInputUpdate, _ignoreSignStatus?: boolean): void;
173
+ private checkOutputIdx;
174
+ getOutput(idx: number): psbt.PSBTKeyMapKeys<{
175
+ readonly redeemScript: readonly [0, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
176
+ readonly witnessScript: readonly [1, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
177
+ readonly bip32Derivation: readonly [2, P.CoderType<Uint8Array>, P.CoderType<P.StructInput<{
178
+ fingerprint: number;
179
+ path: number[];
180
+ }>>, readonly [], readonly [0, 2], false];
181
+ readonly amount: readonly [3, false, P.CoderType<bigint>, readonly [2], readonly [2], true];
182
+ readonly script: readonly [4, false, P.CoderType<Uint8Array>, readonly [2], readonly [2], true];
183
+ readonly tapInternalKey: readonly [5, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
184
+ readonly tapTree: readonly [6, false, P.CoderType<P.StructInput<{
185
+ depth: number;
186
+ version: number;
187
+ script: Uint8Array;
188
+ }>[]>, readonly [], readonly [0, 2], false];
189
+ readonly tapBip32Derivation: readonly [7, P.CoderType<Uint8Array>, P.CoderType<P.StructInput<{
190
+ hashes: Uint8Array[];
191
+ der: P.StructInput<{
192
+ fingerprint: any;
193
+ path: any;
194
+ }>;
195
+ }>>, readonly [], readonly [0, 2], false];
196
+ readonly proprietary: readonly [252, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
197
+ }>;
198
+ getOutputAddress(idx: number, network?: {
199
+ bech32: string;
200
+ pubKeyHash: number;
201
+ scriptHash: number;
202
+ wif: number;
203
+ }): string | undefined;
204
+ get outputsLength(): number;
205
+ private normalizeOutput;
206
+ addOutput(o: psbt.TransactionOutputUpdate, _ignoreSignStatus?: boolean): number;
207
+ updateOutput(idx: number, output: psbt.TransactionOutputUpdate, _ignoreSignStatus?: boolean): void;
208
+ addOutputAddress(address: string, amount: bigint, network?: {
209
+ bech32: string;
210
+ pubKeyHash: number;
211
+ scriptHash: number;
212
+ wif: number;
213
+ }): number;
214
+ get fee(): bigint;
215
+ private preimageLegacy;
216
+ preimageWitnessV0(idx: number, prevOutScript: Bytes, hashType: number, amount: bigint): Uint8Array;
217
+ preimageWitnessV1(idx: number, prevOutScript: Bytes[], hashType: number, amount: bigint[], codeSeparator?: number, leafScript?: Bytes, leafVer?: number, annex?: Bytes): Uint8Array;
218
+ signIdx(privateKey: Signer, idx: number, allowedSighash?: SigHash[], _auxRand?: Bytes): boolean;
219
+ sign(privateKey: Signer, allowedSighash?: number[], _auxRand?: Bytes): number;
220
+ finalizeIdx(idx: number): void;
221
+ finalize(): void;
222
+ extract(): Uint8Array;
223
+ combine(other: Transaction): this;
224
+ clone(): Transaction;
225
+ }
226
+ export declare function PSBTCombine(psbts: Bytes[]): Bytes;
227
+ export declare function bip32Path(path: string): number[];
228
+ export {};
229
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["src/transaction.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.bip32Path = exports.PSBTCombine = exports.Transaction = exports.inputBeforeSign = exports.SigHash = exports.SignatureHash = exports.cloneDeep = 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 = void 0;
4
+ exports.cloneDeep = cloneDeep;
5
+ exports.inputBeforeSign = inputBeforeSign;
6
+ exports.PSBTCombine = PSBTCombine;
7
+ exports.bip32Path = bip32Path;
4
8
  const P = require("micro-packed");
5
9
  const base_1 = require("@scure/base");
6
10
  const payment_js_1 = require("./payment.js");
7
11
  const psbt = require("./psbt.js"); // circular
8
12
  const script_js_1 = require("./script.js");
13
+ const script_js_2 = require("./script.js");
9
14
  const utils_js_1 = require("./utils.js");
10
15
  const u = require("./utils.js");
11
16
  const utxo_js_1 = require("./utxo.js"); // circular
@@ -26,7 +31,7 @@ function cloneDeep(obj) {
26
31
  if (Array.isArray(obj))
27
32
  return obj.map((i) => cloneDeep(i));
28
33
  // slice of nodejs Buffer doesn't copy
29
- else if (obj instanceof Uint8Array)
34
+ else if ((0, utils_js_1.isBytes)(obj))
30
35
  return Uint8Array.from(obj);
31
36
  // immutable
32
37
  else if (['number', 'bigint', 'boolean', 'string', 'undefined'].includes(typeof obj))
@@ -40,7 +45,6 @@ function cloneDeep(obj) {
40
45
  }
41
46
  throw new Error(`cloneDeep: unknown type=${obj} (${typeof obj})`);
42
47
  }
43
- exports.cloneDeep = cloneDeep;
44
48
  /**
45
49
  * Internal, exported only for backwards-compat. Use `SigHash` instead.
46
50
  * @deprecated
@@ -88,7 +92,6 @@ function inputBeforeSign(i) {
88
92
  finalScriptSig: (0, exports.def)(i.finalScriptSig, P.EMPTY),
89
93
  };
90
94
  }
91
- exports.inputBeforeSign = inputBeforeSign;
92
95
  function cleanFinalInput(i) {
93
96
  for (const _k in i) {
94
97
  const k = _k;
@@ -177,7 +180,7 @@ class Transaction {
177
180
  }
178
181
  // Import
179
182
  static fromRaw(raw, opts = {}) {
180
- const parsed = script_js_1.RawTx.decode(raw);
183
+ const parsed = script_js_2.RawTx.decode(raw);
181
184
  const tx = new Transaction({ ...opts, version: parsed.version, lockTime: parsed.lockTime });
182
185
  for (const o of parsed.outputs)
183
186
  tx.addOutput(o);
@@ -231,6 +234,11 @@ class Transaction {
231
234
  toPSBT(PSBTVersion = this.opts.PSBTVersion) {
232
235
  if (PSBTVersion !== 0 && PSBTVersion !== 2)
233
236
  throw new Error(`Wrong PSBT version=${PSBTVersion}`);
237
+ // if (PSBTVersion === 0 && this.inputs.length === 0) {
238
+ // throw new Error(
239
+ // 'PSBT version=0 export for transaction without inputs disabled, please use version=2. Please check `toPSBT` method for explanation.'
240
+ // );
241
+ // }
234
242
  const inputs = this.inputs.map((i) => psbt.cleanPSBTFields(PSBTVersion, psbt.PSBTInput, i));
235
243
  for (const inp of inputs) {
236
244
  // Don't serialize empty fields
@@ -244,7 +252,21 @@ class Transaction {
244
252
  const outputs = this.outputs.map((i) => psbt.cleanPSBTFields(PSBTVersion, psbt.PSBTOutput, i));
245
253
  const global = { ...this.global };
246
254
  if (PSBTVersion === 0) {
247
- global.unsignedTx = script_js_1.RawTx.decode(this.unsignedTx);
255
+ /*
256
+ - Bitcoin raw transaction expects to have at least 1 input because it uses case with zero inputs as marker for SegWit
257
+ - this means we cannot serialize raw tx with zero inputs since it will be parsed as SegWit tx
258
+ - Parsing of PSBTv0 depends on unsignedTx (it looks for input count here)
259
+ - BIP-174 requires old serialization format (without witnesses) inside global, which solves this
260
+ */
261
+ global.unsignedTx = script_js_2.RawOldTx.decode(script_js_2.RawOldTx.encode({
262
+ version: this.version,
263
+ lockTime: this.lockTime,
264
+ inputs: this.inputs.map(inputBeforeSign).map((i) => ({
265
+ ...i,
266
+ finalScriptSig: P.EMPTY,
267
+ })),
268
+ outputs: this.outputs.map(outputBeforeSign),
269
+ }));
248
270
  delete global.fallbackLocktime;
249
271
  delete global.txVersion;
250
272
  }
@@ -318,7 +340,8 @@ class Transaction {
318
340
  // We will lose some vectors -> smaller test coverage of preimages (very important!)
319
341
  inputSighash(idx) {
320
342
  this.checkInputIdx(idx);
321
- const sighash = (0, utxo_js_1.getInputType)(this.inputs[idx], this.opts.allowLegacyWitnessUtxo).sighash;
343
+ const inputSighash = this.inputs[idx].sighashType;
344
+ const sighash = inputSighash === undefined ? SignatureHash.DEFAULT : inputSighash;
322
345
  // ALL or DEFAULT -- everything signed
323
346
  // NONE -- all inputs + no outputs
324
347
  // SINGLE -- all inputs + output with same index
@@ -390,7 +413,7 @@ class Transaction {
390
413
  for (const i of this.inputs) {
391
414
  out += 160 + 4 * script_js_1.VarBytes.encode(i.finalScriptSig || P.EMPTY).length;
392
415
  if (this.hasWitnesses && i.finalScriptWitness)
393
- out += script_js_1.RawWitness.encode(i.finalScriptWitness).length;
416
+ out += script_js_2.RawWitness.encode(i.finalScriptWitness).length;
394
417
  }
395
418
  return out;
396
419
  }
@@ -398,7 +421,7 @@ class Transaction {
398
421
  return (0, utxo_js_1.toVsize)(this.weight);
399
422
  }
400
423
  toBytes(withScriptSig = false, withWitness = false) {
401
- return script_js_1.RawTx.encode({
424
+ return script_js_2.RawTx.encode({
402
425
  version: this.version,
403
426
  lockTime: this.lockTime,
404
427
  inputs: this.inputs.map(inputBeforeSign).map((i) => ({
@@ -464,6 +487,12 @@ class Transaction {
464
487
  this.checkOutputIdx(idx);
465
488
  return cloneDeep(this.outputs[idx]);
466
489
  }
490
+ getOutputAddress(idx, network = utils_js_1.NETWORK) {
491
+ const out = this.getOutput(idx);
492
+ if (!out.script)
493
+ return;
494
+ return (0, payment_js_1.Address)(network).encode(payment_js_1.OutScript.decode(out.script));
495
+ }
467
496
  get outputsLength() {
468
497
  return this.outputs.length;
469
498
  }
@@ -472,7 +501,7 @@ class Transaction {
472
501
  if (amount === undefined)
473
502
  amount = cur?.amount;
474
503
  if (typeof amount !== 'bigint')
475
- throw new Error('amount must be bigint sats');
504
+ throw new Error(`Wrong amount type, should be of type bigint in sats, but got ${amount} of type ${typeof amount}`);
476
505
  if (typeof script === 'string')
477
506
  script = base_1.hex.decode(script);
478
507
  if (script === undefined)
@@ -555,7 +584,7 @@ class Transaction {
555
584
  else if (isSingle) {
556
585
  outputs = outputs.slice(0, idx).fill(EMPTY_OUTPUT).concat([outputs[idx]]);
557
586
  }
558
- const tmpTx = script_js_1.RawTx.encode({
587
+ const tmpTx = script_js_2.RawTx.encode({
559
588
  lockTime: this.lockTime,
560
589
  version: this.version,
561
590
  segwitFlag: false,
@@ -576,10 +605,10 @@ class Transaction {
576
605
  if (!isAny && !isSingle && !isNone)
577
606
  sequenceHash = u.sha256x2(...inputs.map((i) => P.U32LE.encode(i.sequence)));
578
607
  if (!isSingle && !isNone) {
579
- outputHash = u.sha256x2(...outputs.map(script_js_1.RawOutput.encode));
608
+ outputHash = u.sha256x2(...outputs.map(script_js_2.RawOutput.encode));
580
609
  }
581
610
  else if (isSingle && idx < outputs.length)
582
- outputHash = u.sha256x2(script_js_1.RawOutput.encode(outputs[idx]));
611
+ outputHash = u.sha256x2(script_js_2.RawOutput.encode(outputs[idx]));
583
612
  const input = inputs[idx];
584
613
  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));
585
614
  }
@@ -607,7 +636,7 @@ class Transaction {
607
636
  ].map((i) => u.sha256((0, utils_js_1.concatBytes)(...i))));
608
637
  }
609
638
  if (outType === SignatureHash.ALL) {
610
- out.push(u.sha256((0, utils_js_1.concatBytes)(...outputs.map(script_js_1.RawOutput.encode))));
639
+ out.push(u.sha256((0, utils_js_1.concatBytes)(...outputs.map(script_js_2.RawOutput.encode))));
611
640
  }
612
641
  const spendType = (annex ? 1 : 0) | (leafScript ? 2 : 0);
613
642
  out.push(new Uint8Array([spendType]));
@@ -620,7 +649,7 @@ class Transaction {
620
649
  if (spendType & 1)
621
650
  out.push(u.sha256(script_js_1.VarBytes.encode(annex || P.EMPTY)));
622
651
  if (outType === SignatureHash.SINGLE)
623
- out.push(idx < outputs.length ? u.sha256(script_js_1.RawOutput.encode(outputs[idx])) : EMPTY32);
652
+ out.push(idx < outputs.length ? u.sha256(script_js_2.RawOutput.encode(outputs[idx])) : EMPTY32);
624
653
  if (leafScript)
625
654
  out.push((0, payment_js_1.tapLeafHash)(leafScript, leafVer), P.U8.encode(0), P.I32LE.encode(codeSeparator));
626
655
  return u.tagSchnorr('TapSighash', ...out);
@@ -676,8 +705,6 @@ class Transaction {
676
705
  // Taproot
677
706
  const prevOut = (0, utxo_js_1.getPrevOut)(input);
678
707
  if (inputType.txType === 'taproot') {
679
- if (input.tapBip32Derivation)
680
- throw new Error('tapBip32Derivation unsupported');
681
708
  const prevOuts = this.inputs.map(utxo_js_1.getPrevOut);
682
709
  const prevOutScript = prevOuts.map((i) => i.script);
683
710
  const amount = prevOuts.map((i) => i.amount);
@@ -969,8 +996,10 @@ class Transaction {
969
996
  throw new Error(`Transaction/combine: different ${k} length this=${this[k].length} other=${other[k].length}`);
970
997
  }
971
998
  }
972
- const thisUnsigned = this.global.unsignedTx ? script_js_1.RawTx.encode(this.global.unsignedTx) : P.EMPTY;
973
- const otherUnsigned = other.global.unsignedTx ? script_js_1.RawTx.encode(other.global.unsignedTx) : P.EMPTY;
999
+ const thisUnsigned = this.global.unsignedTx ? script_js_2.RawOldTx.encode(this.global.unsignedTx) : P.EMPTY;
1000
+ const otherUnsigned = other.global.unsignedTx
1001
+ ? script_js_2.RawOldTx.encode(other.global.unsignedTx)
1002
+ : P.EMPTY;
974
1003
  if (!(0, utils_js_1.equalBytes)(thisUnsigned, otherUnsigned))
975
1004
  throw new Error(`Transaction/combine: different unsigned tx`);
976
1005
  this.global = psbt.mergeKeyMap(psbt.PSBTGlobal, this.global, other.global);
@@ -994,7 +1023,6 @@ function PSBTCombine(psbts) {
994
1023
  tx.combine(Transaction.fromPSBT(psbts[i]));
995
1024
  return tx.toPSBT();
996
1025
  }
997
- exports.PSBTCombine = PSBTCombine;
998
1026
  // Copy-pasted from bip32 derive, maybe do something like 'bip32.parsePath'?
999
1027
  const HARDENED_OFFSET = 0x80000000;
1000
1028
  function bip32Path(path) {
@@ -1018,5 +1046,4 @@ function bip32Path(path) {
1018
1046
  }
1019
1047
  return out;
1020
1048
  }
1021
- exports.bip32Path = bip32Path;
1022
1049
  //# sourceMappingURL=transaction.js.map