@scure/btc-signer 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +194 -25
  2. package/esm/_type_test.js +1 -1
  3. package/esm/index.d.ts +12 -12
  4. package/esm/index.d.ts.map +1 -1
  5. package/esm/index.js +10 -10
  6. package/esm/index.js.map +1 -1
  7. package/esm/musig2.d.ts +148 -0
  8. package/esm/musig2.d.ts.map +1 -0
  9. package/esm/musig2.js +405 -0
  10. package/esm/musig2.js.map +1 -0
  11. package/esm/p2p.d.ts +38 -0
  12. package/esm/p2p.d.ts.map +1 -0
  13. package/esm/p2p.js +156 -0
  14. package/esm/p2p.js.map +1 -0
  15. package/esm/payment.d.ts +77 -21
  16. package/esm/payment.d.ts.map +1 -1
  17. package/esm/payment.js +63 -60
  18. package/esm/payment.js.map +1 -1
  19. package/esm/psbt.d.ts +463 -463
  20. package/esm/psbt.d.ts.map +1 -1
  21. package/esm/psbt.js +10 -39
  22. package/esm/psbt.js.map +1 -1
  23. package/esm/script.d.ts +16 -16
  24. package/esm/script.d.ts.map +1 -1
  25. package/esm/script.js +1 -1
  26. package/esm/transaction.d.ts +59 -6
  27. package/esm/transaction.d.ts.map +1 -1
  28. package/esm/transaction.js +154 -11
  29. package/esm/transaction.js.map +1 -1
  30. package/esm/utils.d.ts.map +1 -1
  31. package/esm/utxo.d.ts +73 -125
  32. package/esm/utxo.d.ts.map +1 -1
  33. package/esm/utxo.js +17 -122
  34. package/esm/utxo.js.map +1 -1
  35. package/index.d.ts +12 -12
  36. package/index.d.ts.map +1 -1
  37. package/index.js +58 -58
  38. package/index.js.map +1 -1
  39. package/musig2.d.ts +148 -0
  40. package/musig2.d.ts.map +1 -0
  41. package/musig2.js +417 -0
  42. package/musig2.js.map +1 -0
  43. package/p2p.d.ts +38 -0
  44. package/p2p.d.ts.map +1 -0
  45. package/p2p.js +158 -0
  46. package/p2p.js.map +1 -0
  47. package/package.json +15 -11
  48. package/payment.d.ts +77 -21
  49. package/payment.d.ts.map +1 -1
  50. package/payment.js +81 -78
  51. package/payment.js.map +1 -1
  52. package/psbt.d.ts +463 -463
  53. package/psbt.d.ts.map +1 -1
  54. package/psbt.js +30 -59
  55. package/psbt.js.map +1 -1
  56. package/script.d.ts +16 -16
  57. package/script.d.ts.map +1 -1
  58. package/script.js +3 -3
  59. package/src/_type_test.ts +1 -1
  60. package/src/index.ts +12 -12
  61. package/src/musig2.ts +517 -0
  62. package/src/p2p.ts +158 -0
  63. package/src/payment.ts +160 -75
  64. package/src/psbt.ts +11 -39
  65. package/src/script.ts +1 -1
  66. package/src/transaction.ts +170 -17
  67. package/src/utxo.ts +29 -122
  68. package/transaction.d.ts +59 -6
  69. package/transaction.d.ts.map +1 -1
  70. package/transaction.js +224 -77
  71. package/transaction.js.map +1 -1
  72. package/utils.d.ts.map +1 -1
  73. package/utxo.d.ts +73 -125
  74. package/utxo.d.ts.map +1 -1
  75. package/utxo.js +54 -163
  76. package/utxo.js.map +1 -1
@@ -1,7 +1,7 @@
1
1
  import { hex } from '@scure/base';
2
2
  import * as P from 'micro-packed';
3
- import { Address, type CustomScript, OutScript, checkScript, tapLeafHash } from './payment.js';
4
- import * as psbt from './psbt.js'; // circular
3
+ import { Address, type CustomScript, OutScript, checkScript, tapLeafHash } from './payment.ts';
4
+ import * as psbt from './psbt.ts';
5
5
  import {
6
6
  CompactSizeLen,
7
7
  RawOldTx,
@@ -10,16 +10,16 @@ import {
10
10
  RawWitness,
11
11
  Script,
12
12
  VarBytes,
13
- } from './script.js';
14
- import * as u from './utils.js';
15
- import { type Bytes, NETWORK, concatBytes, equalBytes, isBytes } from './utils.js';
16
- import { getInputType, getPrevOut, normalizeInput, toVsize } from './utxo.js'; // circular
13
+ } from './script.ts';
14
+ import * as u from './utils.ts';
15
+ import { type Bytes, NETWORK, concatBytes, equalBytes, isBytes } from './utils.ts';
17
16
 
18
17
  const EMPTY32 = new Uint8Array(32);
19
18
  const EMPTY_OUTPUT: P.UnwrapCoder<typeof RawOutput> = {
20
19
  amount: 0xffffffffffffffffn,
21
20
  script: P.EMPTY,
22
21
  };
22
+ export const toVsize = (weight: number): number => Math.ceil(weight / 4);
23
23
 
24
24
  // @scure/bip32 interface
25
25
  interface HDKey {
@@ -61,7 +61,7 @@ export function cloneDeep<T>(obj: T): T {
61
61
 
62
62
  // Mostly security features, hardened defaults;
63
63
  // but you still can parse other people tx with unspendable outputs and stuff if you want
64
- export type TxOpts = {
64
+ export interface TxOpts {
65
65
  version?: number;
66
66
  lockTime?: number;
67
67
  PSBTVersion?: number;
@@ -84,7 +84,9 @@ export type TxOpts = {
84
84
  allowLegacyWitnessUtxo?: boolean;
85
85
  lowR?: boolean; // Use lowR signatures
86
86
  customScripts?: CustomScript[]; // UNSAFE: Custom payment scripts
87
- };
87
+ // Allow to add additional unknown keys/values to the "unknown" array member
88
+ allowUnknown?: boolean;
89
+ }
88
90
 
89
91
  /**
90
92
  * Internal, exported only for backwards-compat. Use `SigHash` instead.
@@ -228,6 +230,146 @@ function validateOpts(opts: TxOpts): Readonly<TxOpts> {
228
230
  return Object.freeze(_opts);
229
231
  }
230
232
 
233
+ // NOTE: we cannot do this inside PSBTInput coder, because there is no index/txid at this point!
234
+ function validateInput(i: psbt.TransactionInput): psbt.TransactionInput {
235
+ if (i.nonWitnessUtxo && i.index !== undefined) {
236
+ const last = i.nonWitnessUtxo.outputs.length - 1;
237
+ if (i.index > last) throw new Error(`validateInput: index(${i.index}) not in nonWitnessUtxo`);
238
+ const prevOut = i.nonWitnessUtxo.outputs[i.index];
239
+ if (
240
+ i.witnessUtxo &&
241
+ (!equalBytes(i.witnessUtxo.script, prevOut.script) || i.witnessUtxo.amount !== prevOut.amount)
242
+ )
243
+ throw new Error('validateInput: witnessUtxo different from nonWitnessUtxo');
244
+ if (i.txid) {
245
+ const outputs = i.nonWitnessUtxo.outputs;
246
+ if (outputs.length - 1 < i.index) throw new Error('nonWitnessUtxo: incorect output index');
247
+ // At this point, we are using previous tx output to create new input.
248
+ // Script safety checks are unnecessary:
249
+ // - User has no control over previous tx. If somebody send money in same tx
250
+ // as unspendable output, we still want user able to spend money
251
+ // - We still want some checks to notify user about possible errors early
252
+ // in case user wants to use wrong input by mistake
253
+ // - Worst case: tx will be rejected by nodes. Still better than disallowing user
254
+ // to spend real input, no matter how broken it looks
255
+ const tx = Transaction.fromRaw(RawTx.encode(i.nonWitnessUtxo), {
256
+ allowUnknownOutputs: true,
257
+ disableScriptCheck: true,
258
+ allowUnknownInputs: true,
259
+ });
260
+ const txid = hex.encode(i.txid);
261
+ // PSBTv2 vectors have non-final tx in inputs
262
+ if (tx.isFinal && tx.id !== txid)
263
+ throw new Error(`nonWitnessUtxo: wrong txid, exp=${txid} got=${tx.id}`);
264
+ }
265
+ }
266
+ return i;
267
+ }
268
+
269
+ export type PSBTInputs = psbt.PSBTKeyMapKeys<typeof psbt.PSBTInput>;
270
+
271
+ // Normalizes input
272
+ export function getPrevOut(input: psbt.TransactionInput): P.UnwrapCoder<typeof RawOutput> {
273
+ if (input.nonWitnessUtxo) {
274
+ if (input.index === undefined) throw new Error('Unknown input index');
275
+ return input.nonWitnessUtxo.outputs[input.index];
276
+ } else if (input.witnessUtxo) return input.witnessUtxo;
277
+ else throw new Error('Cannot find previous output info');
278
+ }
279
+
280
+ export function normalizeInput(
281
+ i: psbt.TransactionInputUpdate,
282
+ cur?: psbt.TransactionInput,
283
+ allowedFields?: (keyof psbt.TransactionInput)[],
284
+ disableScriptCheck = false,
285
+ allowUnknown = false
286
+ ): psbt.TransactionInput {
287
+ let { nonWitnessUtxo, txid } = i;
288
+ // String support for common fields. We usually prefer Uint8Array to avoid errors
289
+ // like hex looking string accidentally passed, however, in case of nonWitnessUtxo
290
+ // it is better to expect string, since constructing this complex object will be
291
+ // difficult for user
292
+ if (typeof nonWitnessUtxo === 'string') nonWitnessUtxo = hex.decode(nonWitnessUtxo);
293
+ if (isBytes(nonWitnessUtxo)) nonWitnessUtxo = RawTx.decode(nonWitnessUtxo);
294
+ if (!('nonWitnessUtxo' in i) && nonWitnessUtxo === undefined)
295
+ nonWitnessUtxo = cur?.nonWitnessUtxo;
296
+ if (typeof txid === 'string') txid = hex.decode(txid);
297
+ // TODO: if we have nonWitnessUtxo, we can extract txId from here
298
+ if (txid === undefined) txid = cur?.txid;
299
+ let res: PSBTInputs = { ...cur, ...i, nonWitnessUtxo, txid };
300
+ if (!('nonWitnessUtxo' in i) && res.nonWitnessUtxo === undefined) delete res.nonWitnessUtxo;
301
+ if (res.sequence === undefined) res.sequence = DEFAULT_SEQUENCE;
302
+ if (res.tapMerkleRoot === null) delete res.tapMerkleRoot;
303
+ res = psbt.mergeKeyMap(psbt.PSBTInput, res, cur, allowedFields, allowUnknown);
304
+ psbt.PSBTInputCoder.encode(res); // Validates that everything is correct at this point
305
+
306
+ let prevOut;
307
+ if (res.nonWitnessUtxo && res.index !== undefined)
308
+ prevOut = res.nonWitnessUtxo.outputs[res.index];
309
+ else if (res.witnessUtxo) prevOut = res.witnessUtxo;
310
+ if (prevOut && !disableScriptCheck)
311
+ checkScript(prevOut && prevOut.script, res.redeemScript, res.witnessScript);
312
+ return res;
313
+ }
314
+
315
+ export function getInputType(input: psbt.TransactionInput, allowLegacyWitnessUtxo = false) {
316
+ let txType = 'legacy';
317
+ let defaultSighash = SignatureHash.ALL;
318
+ const prevOut = getPrevOut(input);
319
+ const first = OutScript.decode(prevOut.script);
320
+ let type = first.type;
321
+ let cur = first;
322
+ const stack = [first];
323
+ if (first.type === 'tr') {
324
+ defaultSighash = SignatureHash.DEFAULT;
325
+ return {
326
+ txType: 'taproot',
327
+ type: 'tr',
328
+ last: first,
329
+ lastScript: prevOut.script,
330
+ defaultSighash,
331
+ sighash: input.sighashType || defaultSighash,
332
+ };
333
+ } else {
334
+ if (first.type === 'wpkh' || first.type === 'wsh') txType = 'segwit';
335
+ if (first.type === 'sh') {
336
+ if (!input.redeemScript) throw new Error('inputType: sh without redeemScript');
337
+ let child = OutScript.decode(input.redeemScript);
338
+ if (child.type === 'wpkh' || child.type === 'wsh') txType = 'segwit';
339
+ stack.push(child);
340
+ cur = child;
341
+ type += `-${child.type}`;
342
+ }
343
+ // wsh can be inside sh
344
+ if (cur.type === 'wsh') {
345
+ if (!input.witnessScript) throw new Error('inputType: wsh without witnessScript');
346
+ let child = OutScript.decode(input.witnessScript);
347
+ if (child.type === 'wsh') txType = 'segwit';
348
+ stack.push(child);
349
+ cur = child;
350
+ type += `-${child.type}`;
351
+ }
352
+ const last = stack[stack.length - 1];
353
+ if (last.type === 'sh' || last.type === 'wsh')
354
+ throw new Error('inputType: sh/wsh cannot be terminal type');
355
+ const lastScript = OutScript.encode(last);
356
+ const res = {
357
+ type,
358
+ txType,
359
+ last,
360
+ lastScript,
361
+ defaultSighash,
362
+ sighash: input.sighashType || defaultSighash,
363
+ };
364
+ if (txType === 'legacy' && !allowLegacyWitnessUtxo && !input.nonWitnessUtxo) {
365
+ throw new Error(
366
+ `Transaction/sign: legacy input without nonWitnessUtxo, can result in attack that forces paying higher fees. Pass allowLegacyWitnessUtxo=true, if you sure`
367
+ );
368
+ }
369
+ return res;
370
+ }
371
+ }
372
+
231
373
  export class Transaction {
232
374
  private global: psbt.PSBTKeyMapKeys<typeof psbt.PSBTGlobal> = {};
233
375
  private inputs: psbt.TransactionInput[] = []; // use getInput()
@@ -275,11 +417,13 @@ export class Transaction {
275
417
  const tx = new Transaction({ ...opts, version, lockTime, PSBTVersion });
276
418
  // We need slice here, because otherwise
277
419
  const inputCount = PSBTVersion === 0 ? unsigned?.inputs.length : parsed.global.inputCount;
278
- tx.inputs = parsed.inputs.slice(0, inputCount).map((i, j) => ({
279
- finalScriptSig: P.EMPTY,
280
- ...parsed.global.unsignedTx?.inputs[j],
281
- ...i,
282
- }));
420
+ tx.inputs = parsed.inputs.slice(0, inputCount).map((i, j) =>
421
+ validateInput({
422
+ finalScriptSig: P.EMPTY,
423
+ ...parsed.global.unsignedTx?.inputs[j],
424
+ ...i,
425
+ })
426
+ );
283
427
  const outputCount = PSBTVersion === 0 ? unsigned?.outputs.length : parsed.global.outputCount;
284
428
  tx.outputs = parsed.outputs.slice(0, outputCount).map((i, j) => ({
285
429
  ...i,
@@ -297,7 +441,9 @@ export class Transaction {
297
441
  // 'PSBT version=0 export for transaction without inputs disabled, please use version=2. Please check `toPSBT` method for explanation.'
298
442
  // );
299
443
  // }
300
- const inputs = this.inputs.map((i) => psbt.cleanPSBTFields(PSBTVersion, psbt.PSBTInput, i));
444
+ const inputs = this.inputs.map((i) =>
445
+ validateInput(psbt.cleanPSBTFields(PSBTVersion, psbt.PSBTInput, i))
446
+ );
301
447
  for (const inp of inputs) {
302
448
  // Don't serialize empty fields
303
449
  if (inp.partialSig && !inp.partialSig.length) delete inp.partialSig;
@@ -520,7 +666,8 @@ export class Transaction {
520
666
  input,
521
667
  this.inputs[idx],
522
668
  allowedFields,
523
- this.opts.disableScriptCheck
669
+ this.opts.disableScriptCheck,
670
+ this.opts.allowUnknown
524
671
  );
525
672
  }
526
673
  // Output stuff
@@ -556,7 +703,7 @@ export class Transaction {
556
703
  if (script === undefined) script = cur?.script;
557
704
  let res: psbt.PSBTKeyMapKeys<typeof psbt.PSBTOutput> = { ...cur, ...o, amount, script };
558
705
  if (res.amount === undefined) delete res.amount;
559
- res = psbt.mergeKeyMap(psbt.PSBTOutput, res, cur, allowedFields);
706
+ res = psbt.mergeKeyMap(psbt.PSBTOutput, res, cur, allowedFields, this.opts.allowUnknown);
560
707
  psbt.PSBTOutputCoder.encode(res);
561
708
  if (
562
709
  res.script &&
@@ -1070,7 +1217,13 @@ export class Transaction {
1070
1217
  : P.EMPTY;
1071
1218
  if (!equalBytes(thisUnsigned, otherUnsigned))
1072
1219
  throw new Error(`Transaction/combine: different unsigned tx`);
1073
- this.global = psbt.mergeKeyMap(psbt.PSBTGlobal, this.global, other.global);
1220
+ this.global = psbt.mergeKeyMap(
1221
+ psbt.PSBTGlobal,
1222
+ this.global,
1223
+ other.global,
1224
+ undefined,
1225
+ this.opts.allowUnknown
1226
+ );
1074
1227
  for (let i = 0; i < this.inputs.length; i++) this.updateInput(i, other.inputs[i], true);
1075
1228
  for (let i = 0; i < this.outputs.length; i++) this.updateOutput(i, other.outputs[i], true);
1076
1229
  return this;
package/src/utxo.ts CHANGED
@@ -1,15 +1,18 @@
1
1
  import { hex } from '@scure/base';
2
2
  import * as P from 'micro-packed';
3
- import { Address, type CustomScript, OutScript, checkScript, tapLeafHash } from './payment.js';
4
- import * as psbt from './psbt.js';
5
- import { CompactSizeLen, RawOutput, RawTx, RawWitness, Script, VarBytes } from './script.js';
3
+ import { Address, type CustomScript, OutScript, checkScript, tapLeafHash } from './payment.ts';
4
+ import * as psbt from './psbt.ts';
5
+ import { CompactSizeLen, RawWitness, Script, VarBytes } from './script.ts';
6
6
  import {
7
- DEFAULT_SEQUENCE,
8
7
  SignatureHash,
9
8
  Transaction,
10
9
  type TxOpts,
10
+ getInputType,
11
+ getPrevOut,
11
12
  inputBeforeSign,
12
- } from './transaction.js'; // circular
13
+ normalizeInput,
14
+ toVsize,
15
+ } from './transaction.ts';
13
16
  import {
14
17
  type Bytes,
15
18
  NETWORK,
@@ -20,112 +23,8 @@ import {
20
23
  isBytes,
21
24
  sha256,
22
25
  validatePubkey,
23
- } from './utils.js';
26
+ } from './utils.ts';
24
27
 
25
- export type PSBTInputs = psbt.PSBTKeyMapKeys<typeof psbt.PSBTInput>;
26
-
27
- // Normalizes input
28
- export function getPrevOut(input: psbt.TransactionInput): P.UnwrapCoder<typeof RawOutput> {
29
- if (input.nonWitnessUtxo) {
30
- if (input.index === undefined) throw new Error('Unknown input index');
31
- return input.nonWitnessUtxo.outputs[input.index];
32
- } else if (input.witnessUtxo) return input.witnessUtxo;
33
- else throw new Error('Cannot find previous output info');
34
- }
35
-
36
- export function normalizeInput(
37
- i: psbt.TransactionInputUpdate,
38
- cur?: psbt.TransactionInput,
39
- allowedFields?: (keyof psbt.TransactionInput)[],
40
- disableScriptCheck = false
41
- ): psbt.TransactionInput {
42
- let { nonWitnessUtxo, txid } = i;
43
- // String support for common fields. We usually prefer Uint8Array to avoid errors
44
- // like hex looking string accidentally passed, however, in case of nonWitnessUtxo
45
- // it is better to expect string, since constructing this complex object will be
46
- // difficult for user
47
- if (typeof nonWitnessUtxo === 'string') nonWitnessUtxo = hex.decode(nonWitnessUtxo);
48
- if (isBytes(nonWitnessUtxo)) nonWitnessUtxo = RawTx.decode(nonWitnessUtxo);
49
- if (!('nonWitnessUtxo' in i) && nonWitnessUtxo === undefined)
50
- nonWitnessUtxo = cur?.nonWitnessUtxo;
51
- if (typeof txid === 'string') txid = hex.decode(txid);
52
- // TODO: if we have nonWitnessUtxo, we can extract txId from here
53
- if (txid === undefined) txid = cur?.txid;
54
- let res: PSBTInputs = { ...cur, ...i, nonWitnessUtxo, txid };
55
- if (!('nonWitnessUtxo' in i) && res.nonWitnessUtxo === undefined) delete res.nonWitnessUtxo;
56
- if (res.sequence === undefined) res.sequence = DEFAULT_SEQUENCE;
57
- if (res.tapMerkleRoot === null) delete res.tapMerkleRoot;
58
- res = psbt.mergeKeyMap(psbt.PSBTInput, res, cur, allowedFields);
59
- psbt.PSBTInputCoder.encode(res); // Validates that everything is correct at this point
60
-
61
- let prevOut;
62
- if (res.nonWitnessUtxo && res.index !== undefined)
63
- prevOut = res.nonWitnessUtxo.outputs[res.index];
64
- else if (res.witnessUtxo) prevOut = res.witnessUtxo;
65
- if (prevOut && !disableScriptCheck)
66
- checkScript(prevOut && prevOut.script, res.redeemScript, res.witnessScript);
67
- return res;
68
- }
69
-
70
- export function getInputType(input: psbt.TransactionInput, allowLegacyWitnessUtxo = false) {
71
- let txType = 'legacy';
72
- let defaultSighash = SignatureHash.ALL;
73
- const prevOut = getPrevOut(input);
74
- const first = OutScript.decode(prevOut.script);
75
- let type = first.type;
76
- let cur = first;
77
- const stack = [first];
78
- if (first.type === 'tr') {
79
- defaultSighash = SignatureHash.DEFAULT;
80
- return {
81
- txType: 'taproot',
82
- type: 'tr',
83
- last: first,
84
- lastScript: prevOut.script,
85
- defaultSighash,
86
- sighash: input.sighashType || defaultSighash,
87
- };
88
- } else {
89
- if (first.type === 'wpkh' || first.type === 'wsh') txType = 'segwit';
90
- if (first.type === 'sh') {
91
- if (!input.redeemScript) throw new Error('inputType: sh without redeemScript');
92
- let child = OutScript.decode(input.redeemScript);
93
- if (child.type === 'wpkh' || child.type === 'wsh') txType = 'segwit';
94
- stack.push(child);
95
- cur = child;
96
- type += `-${child.type}`;
97
- }
98
- // wsh can be inside sh
99
- if (cur.type === 'wsh') {
100
- if (!input.witnessScript) throw new Error('inputType: wsh without witnessScript');
101
- let child = OutScript.decode(input.witnessScript);
102
- if (child.type === 'wsh') txType = 'segwit';
103
- stack.push(child);
104
- cur = child;
105
- type += `-${child.type}`;
106
- }
107
- const last = stack[stack.length - 1];
108
- if (last.type === 'sh' || last.type === 'wsh')
109
- throw new Error('inputType: sh/wsh cannot be terminal type');
110
- const lastScript = OutScript.encode(last);
111
- const res = {
112
- type,
113
- txType,
114
- last,
115
- lastScript,
116
- defaultSighash,
117
- sighash: input.sighashType || defaultSighash,
118
- };
119
- if (txType === 'legacy' && !allowLegacyWitnessUtxo && !input.nonWitnessUtxo) {
120
- throw new Error(
121
- `Transaction/sign: legacy input without nonWitnessUtxo, can result in attack that forces paying higher fees. Pass allowLegacyWitnessUtxo=true, if you sure`
122
- );
123
- }
124
- return res;
125
- }
126
- }
127
-
128
- export const toVsize = (weight: number): number => Math.ceil(weight / 4);
129
28
  // UTXO Select
130
29
  export type Output = { address: string; amount: bigint } | { script: Uint8Array; amount: bigint };
131
30
  export type Accumulated =
@@ -341,11 +240,11 @@ export class _Estimator {
341
240
  // - change address: can be smaller for segwit
342
241
  // - accumExact: ???
343
242
  private dust: bigint; // total dust limit (3||opts.dustRelayFeeRate * 182||opts.dust). Default: 546
344
- constructor(
345
- inputs: psbt.TransactionInputUpdate[],
346
- private outputs: Output[],
347
- private opts: EstimatorOpts
348
- ) {
243
+ private outputs: Output[];
244
+ private opts: EstimatorOpts;
245
+ constructor(inputs: psbt.TransactionInputUpdate[], outputs: Output[], opts: EstimatorOpts) {
246
+ this.outputs = outputs;
247
+ this.opts = opts;
349
248
  if (typeof opts.feePerByte !== 'bigint')
350
249
  throw new Error(
351
250
  `Estimator: wrong feePerByte=${
@@ -410,7 +309,13 @@ export class _Estimator {
410
309
  }
411
310
  const inputKeys = new Set();
412
311
  this.normalizedInputs = allInputs.map((i) => {
413
- const normalized = normalizeInput(i, undefined, undefined, opts.disableScriptCheck);
312
+ const normalized = normalizeInput(
313
+ i,
314
+ undefined,
315
+ undefined,
316
+ opts.disableScriptCheck,
317
+ opts.allowUnknown
318
+ );
414
319
  inputBeforeSign(normalized); // check fields
415
320
  const key = `${hex.encode(normalized.txid!)}:${normalized.index}`;
416
321
  if (!opts.allowSameUtxo && inputKeys.has(key))
@@ -487,10 +392,11 @@ export class _Estimator {
487
392
  let num = 0;
488
393
  let inputsAmount = 0n;
489
394
  const targetAmount = this.amount;
490
- const res = [];
395
+ const res: Set<number> = new Set();
491
396
  let fee;
492
397
  for (const idx of this.requiredIndices) {
493
398
  this.checkInputIdx(idx);
399
+ if (res.has(idx)) throw new Error('required input encountered multiple times'); // should not happen
494
400
  const { estimate, amount } = this.normalizedInputs[idx];
495
401
  let newWeight = weight + estimate.weight;
496
402
  if (!hasWitnesses && estimate.hasWitnesses) newWeight += 2; // enable witness if needed
@@ -500,13 +406,14 @@ export class _Estimator {
500
406
  if (estimate.hasWitnesses) hasWitnesses = true;
501
407
  num++;
502
408
  inputsAmount += amount;
503
- res.push(idx);
409
+ res.add(idx);
504
410
  // inputsAmount is enough to cover cost of tx
505
411
  if (!all && targetAmount + fee <= inputsAmount)
506
- return { indices: res, fee, weight: totalWeight, total: inputsAmount };
412
+ return { indices: Array.from(res), fee, weight: totalWeight, total: inputsAmount };
507
413
  }
508
414
  for (const idx of indices) {
509
415
  this.checkInputIdx(idx);
416
+ if (res.has(idx)) continue; // skip required inputs
510
417
  const { estimate, amount, value } = this.normalizedInputs[idx];
511
418
  let newWeight = weight + estimate.weight;
512
419
  if (!hasWitnesses && estimate.hasWitnesses) newWeight += 2; // enable witness if needed
@@ -522,14 +429,14 @@ export class _Estimator {
522
429
  if (estimate.hasWitnesses) hasWitnesses = true;
523
430
  num++;
524
431
  inputsAmount += amount;
525
- res.push(idx);
432
+ res.add(idx);
526
433
  // inputsAmount is enough to cover cost of tx
527
434
  if (!all && targetAmount + fee <= inputsAmount)
528
- return { indices: res, fee, weight: totalWeight, total: inputsAmount };
435
+ return { indices: Array.from(res), fee, weight: totalWeight, total: inputsAmount };
529
436
  }
530
437
  if (all) {
531
438
  const newWeight = weight + 4 * CompactSizeLen.encode(num).length;
532
- return { indices: res, fee, weight: newWeight, total: inputsAmount };
439
+ return { indices: Array.from(res), fee, weight: newWeight, total: inputsAmount };
533
440
  }
534
441
  return undefined;
535
442
  }
package/transaction.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import * as P from 'micro-packed';
2
- import { type CustomScript } from './payment.js';
3
- import * as psbt from './psbt.js';
4
- import * as u from './utils.js';
5
- import { type Bytes } from './utils.js';
2
+ import { type CustomScript } from './payment.ts';
3
+ import * as psbt from './psbt.ts';
4
+ import { RawOutput } from './script.ts';
5
+ import * as u from './utils.ts';
6
+ import { type Bytes } from './utils.ts';
7
+ export declare const toVsize: (weight: number) => number;
6
8
  interface HDKey {
7
9
  publicKey: Bytes;
8
10
  privateKey: Bytes;
@@ -19,7 +21,7 @@ export declare const DEFAULT_SEQUENCE = 4294967295;
19
21
  export declare const Decimal: P.Coder<bigint, string>;
20
22
  export declare const def: <T>(value: T | undefined, def: T) => T;
21
23
  export declare function cloneDeep<T>(obj: T): T;
22
- export type TxOpts = {
24
+ export interface TxOpts {
23
25
  version?: number;
24
26
  lockTime?: number;
25
27
  PSBTVersion?: number;
@@ -34,7 +36,8 @@ export type TxOpts = {
34
36
  allowLegacyWitnessUtxo?: boolean;
35
37
  lowR?: boolean;
36
38
  customScripts?: CustomScript[];
37
- };
39
+ allowUnknown?: boolean;
40
+ }
38
41
  /**
39
42
  * Internal, exported only for backwards-compat. Use `SigHash` instead.
40
43
  * @deprecated
@@ -64,6 +67,56 @@ export type TransactionInputRequired = {
64
67
  };
65
68
  export declare function inputBeforeSign(i: psbt.TransactionInput): TransactionInputRequired;
66
69
  declare function validateOpts(opts: TxOpts): Readonly<TxOpts>;
70
+ export type PSBTInputs = psbt.PSBTKeyMapKeys<typeof psbt.PSBTInput>;
71
+ export declare function getPrevOut(input: psbt.TransactionInput): P.UnwrapCoder<typeof RawOutput>;
72
+ export declare function normalizeInput(i: psbt.TransactionInputUpdate, cur?: psbt.TransactionInput, allowedFields?: (keyof psbt.TransactionInput)[], disableScriptCheck?: boolean, allowUnknown?: boolean): psbt.TransactionInput;
73
+ export declare function getInputType(input: psbt.TransactionInput, allowLegacyWitnessUtxo?: boolean): {
74
+ type: string;
75
+ txType: string;
76
+ last: {
77
+ type: "p2a";
78
+ script: Bytes;
79
+ } | {
80
+ type: "pk";
81
+ pubkey: Bytes;
82
+ } | {
83
+ type: "pkh";
84
+ hash: Bytes;
85
+ } | {
86
+ type: "wpkh";
87
+ hash: Bytes;
88
+ } | {
89
+ type: "ms";
90
+ pubkeys: Bytes[];
91
+ m: number;
92
+ } | {
93
+ type: "tr";
94
+ pubkey: Bytes;
95
+ } | {
96
+ type: "tr_ns";
97
+ pubkeys: Bytes[];
98
+ } | {
99
+ type: "tr_ms";
100
+ pubkeys: Bytes[];
101
+ m: number;
102
+ } | {
103
+ type: "unknown";
104
+ script: Bytes;
105
+ };
106
+ lastScript: P.Bytes;
107
+ defaultSighash: SignatureHash.ALL;
108
+ sighash: number;
109
+ } | {
110
+ txType: string;
111
+ type: string;
112
+ last: {
113
+ type: "tr";
114
+ pubkey: Bytes;
115
+ };
116
+ lastScript: Uint8Array<ArrayBufferLike>;
117
+ defaultSighash: SignatureHash.DEFAULT;
118
+ sighash: number;
119
+ };
67
120
  export declare class Transaction {
68
121
  private global;
69
122
  private inputs;
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["src/transaction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["src/transaction.ts"],"names":[],"mappings":"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"}