@scure/btc-signer 1.3.2 → 1.4.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 +33 -7
  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 +65 -27
  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 +38 -7
  54. package/src/utxo.ts +80 -23
  55. package/transaction.d.ts +229 -0
  56. package/transaction.d.ts.map +1 -0
  57. package/{lib/transaction.js → transaction.js} +45 -19
  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} +70 -32
  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,7 +268,10 @@ 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) {
@@ -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
@@ -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
  }
@@ -390,7 +412,7 @@ class Transaction {
390
412
  for (const i of this.inputs) {
391
413
  out += 160 + 4 * script_js_1.VarBytes.encode(i.finalScriptSig || P.EMPTY).length;
392
414
  if (this.hasWitnesses && i.finalScriptWitness)
393
- out += script_js_1.RawWitness.encode(i.finalScriptWitness).length;
415
+ out += script_js_2.RawWitness.encode(i.finalScriptWitness).length;
394
416
  }
395
417
  return out;
396
418
  }
@@ -398,7 +420,7 @@ class Transaction {
398
420
  return (0, utxo_js_1.toVsize)(this.weight);
399
421
  }
400
422
  toBytes(withScriptSig = false, withWitness = false) {
401
- return script_js_1.RawTx.encode({
423
+ return script_js_2.RawTx.encode({
402
424
  version: this.version,
403
425
  lockTime: this.lockTime,
404
426
  inputs: this.inputs.map(inputBeforeSign).map((i) => ({
@@ -464,6 +486,12 @@ class Transaction {
464
486
  this.checkOutputIdx(idx);
465
487
  return cloneDeep(this.outputs[idx]);
466
488
  }
489
+ getOutputAddress(idx, network = utils_js_1.NETWORK) {
490
+ const out = this.getOutput(idx);
491
+ if (!out.script)
492
+ return;
493
+ return (0, payment_js_1.Address)(network).encode(payment_js_1.OutScript.decode(out.script));
494
+ }
467
495
  get outputsLength() {
468
496
  return this.outputs.length;
469
497
  }
@@ -472,7 +500,7 @@ class Transaction {
472
500
  if (amount === undefined)
473
501
  amount = cur?.amount;
474
502
  if (typeof amount !== 'bigint')
475
- throw new Error('amount must be bigint sats');
503
+ throw new Error(`Wrong amount type, should be of type bigint in sats, but got ${amount} of type ${typeof amount}`);
476
504
  if (typeof script === 'string')
477
505
  script = base_1.hex.decode(script);
478
506
  if (script === undefined)
@@ -555,7 +583,7 @@ class Transaction {
555
583
  else if (isSingle) {
556
584
  outputs = outputs.slice(0, idx).fill(EMPTY_OUTPUT).concat([outputs[idx]]);
557
585
  }
558
- const tmpTx = script_js_1.RawTx.encode({
586
+ const tmpTx = script_js_2.RawTx.encode({
559
587
  lockTime: this.lockTime,
560
588
  version: this.version,
561
589
  segwitFlag: false,
@@ -576,10 +604,10 @@ class Transaction {
576
604
  if (!isAny && !isSingle && !isNone)
577
605
  sequenceHash = u.sha256x2(...inputs.map((i) => P.U32LE.encode(i.sequence)));
578
606
  if (!isSingle && !isNone) {
579
- outputHash = u.sha256x2(...outputs.map(script_js_1.RawOutput.encode));
607
+ outputHash = u.sha256x2(...outputs.map(script_js_2.RawOutput.encode));
580
608
  }
581
609
  else if (isSingle && idx < outputs.length)
582
- outputHash = u.sha256x2(script_js_1.RawOutput.encode(outputs[idx]));
610
+ outputHash = u.sha256x2(script_js_2.RawOutput.encode(outputs[idx]));
583
611
  const input = inputs[idx];
584
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));
585
613
  }
@@ -607,7 +635,7 @@ class Transaction {
607
635
  ].map((i) => u.sha256((0, utils_js_1.concatBytes)(...i))));
608
636
  }
609
637
  if (outType === SignatureHash.ALL) {
610
- out.push(u.sha256((0, utils_js_1.concatBytes)(...outputs.map(script_js_1.RawOutput.encode))));
638
+ out.push(u.sha256((0, utils_js_1.concatBytes)(...outputs.map(script_js_2.RawOutput.encode))));
611
639
  }
612
640
  const spendType = (annex ? 1 : 0) | (leafScript ? 2 : 0);
613
641
  out.push(new Uint8Array([spendType]));
@@ -620,7 +648,7 @@ class Transaction {
620
648
  if (spendType & 1)
621
649
  out.push(u.sha256(script_js_1.VarBytes.encode(annex || P.EMPTY)));
622
650
  if (outType === SignatureHash.SINGLE)
623
- out.push(idx < outputs.length ? u.sha256(script_js_1.RawOutput.encode(outputs[idx])) : EMPTY32);
651
+ out.push(idx < outputs.length ? u.sha256(script_js_2.RawOutput.encode(outputs[idx])) : EMPTY32);
624
652
  if (leafScript)
625
653
  out.push((0, payment_js_1.tapLeafHash)(leafScript, leafVer), P.U8.encode(0), P.I32LE.encode(codeSeparator));
626
654
  return u.tagSchnorr('TapSighash', ...out);
@@ -676,8 +704,6 @@ class Transaction {
676
704
  // Taproot
677
705
  const prevOut = (0, utxo_js_1.getPrevOut)(input);
678
706
  if (inputType.txType === 'taproot') {
679
- if (input.tapBip32Derivation)
680
- throw new Error('tapBip32Derivation unsupported');
681
707
  const prevOuts = this.inputs.map(utxo_js_1.getPrevOut);
682
708
  const prevOutScript = prevOuts.map((i) => i.script);
683
709
  const amount = prevOuts.map((i) => i.amount);
@@ -969,8 +995,10 @@ class Transaction {
969
995
  throw new Error(`Transaction/combine: different ${k} length this=${this[k].length} other=${other[k].length}`);
970
996
  }
971
997
  }
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;
998
+ const thisUnsigned = this.global.unsignedTx ? script_js_2.RawOldTx.encode(this.global.unsignedTx) : P.EMPTY;
999
+ const otherUnsigned = other.global.unsignedTx
1000
+ ? script_js_2.RawOldTx.encode(other.global.unsignedTx)
1001
+ : P.EMPTY;
974
1002
  if (!(0, utils_js_1.equalBytes)(thisUnsigned, otherUnsigned))
975
1003
  throw new Error(`Transaction/combine: different unsigned tx`);
976
1004
  this.global = psbt.mergeKeyMap(psbt.PSBTGlobal, this.global, other.global);
@@ -994,7 +1022,6 @@ function PSBTCombine(psbts) {
994
1022
  tx.combine(Transaction.fromPSBT(psbts[i]));
995
1023
  return tx.toPSBT();
996
1024
  }
997
- exports.PSBTCombine = PSBTCombine;
998
1025
  // Copy-pasted from bip32 derive, maybe do something like 'bip32.parsePath'?
999
1026
  const HARDENED_OFFSET = 0x80000000;
1000
1027
  function bip32Path(path) {
@@ -1018,5 +1045,4 @@ function bip32Path(path) {
1018
1045
  }
1019
1046
  return out;
1020
1047
  }
1021
- exports.bip32Path = bip32Path;
1022
1048
  //# sourceMappingURL=transaction.js.map