@scure/btc-signer 0.5.0 → 1.0.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.
package/index.ts CHANGED
@@ -26,6 +26,23 @@ const concat = P.concatBytes;
26
26
  // Make base58check work
27
27
  export const base58check = _b58(sha256);
28
28
 
29
+ export function cloneDeep<T>(obj: T): T {
30
+ if (Array.isArray(obj)) return obj.map((i) => cloneDeep(i)) as unknown as T;
31
+ // slice of nodejs Buffer doesn't copy
32
+ else if (obj instanceof Uint8Array) return Uint8Array.from(obj) as unknown as T;
33
+ // immutable
34
+ else if (['number', 'bigint', 'boolean', 'string', 'undefined'].includes(typeof obj)) return obj;
35
+ // null is object
36
+ else if (obj === null) return obj;
37
+ // should be last, so it won't catch other types
38
+ else if (typeof obj === 'object') {
39
+ return Object.fromEntries(
40
+ Object.entries(obj).map(([k, v]) => [k, cloneDeep(v)])
41
+ ) as unknown as T;
42
+ }
43
+ throw new Error(`cloneDeep: unknown type=${obj} (${typeof obj})`);
44
+ }
45
+
29
46
  enum PubT {
30
47
  ecdsa,
31
48
  schnorr,
@@ -463,7 +480,7 @@ const PSBTGlobal = {
463
480
  outputCount: [0x05, false, CompactSizeLen, [2], [2], false],
464
481
  txModifiable: [0x06, false, P.U8, [], [2], false], // TODO: bitfield
465
482
  version: [0xfb, false, P.U32LE, [], [0, 2], false],
466
- propietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
483
+ proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
467
484
  } as const;
468
485
  // prettier-ignore
469
486
  const PSBTInput = {
@@ -492,7 +509,7 @@ const PSBTInput = {
492
509
  tapBip32Derivation: [0x16, Bytes32, TaprootBIP32Der, [], [0, 2], false],
493
510
  tapInternalKey: [0x17, false, PubKeySchnorr, [], [0, 2], false],
494
511
  tapMerkleRoot: [0x18, false, Bytes32, [], [0, 2], false],
495
- propietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
512
+ proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
496
513
  } as const;
497
514
  // All other keys removed when finalizing
498
515
  const PSBTInputFinalKeys: (keyof TransactionInput)[] = [
@@ -525,7 +542,7 @@ const PSBTOutput = {
525
542
  tapInternalKey: [0x05, false, PubKeySchnorr, [], [0, 2], false],
526
543
  tapTree: [0x06, false, tapTree, [], [0, 2], false],
527
544
  tapBip32Derivation: [0x07, PubKeySchnorr, TaprootBIP32Der, [], [0, 2], false],
528
- propietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
545
+ proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
529
546
  } as const;
530
547
 
531
548
  // Can be modified even on signed input
@@ -564,10 +581,11 @@ function PSBTKeyMap<T extends PSBTKeyMap>(psbtEnum: T): P.CoderType<PSBTKeyMapKe
564
581
  const val = value[name];
565
582
  if (val === undefined) continue;
566
583
  const [type, kc, vc] = psbtEnum[name];
567
- if (!kc) out.push({ key: { type, key: P.EMPTY }, value: vc.encode(val) });
568
- else {
584
+ if (!kc) {
585
+ out.push({ key: { type, key: P.EMPTY }, value: vc.encode(val) });
586
+ } else {
569
587
  // Low level interface, returns keys as is (with duplicates). Useful for debug
570
- const kv: [Bytes, Bytes][] = val.map(
588
+ const kv: [Bytes, Bytes][] = val!.map(
571
589
  ([k, v]: [P.UnwrapCoder<typeof kc>, P.UnwrapCoder<typeof vc>]) => [
572
590
  kc.encode(k),
573
591
  vc.encode(v),
@@ -1538,10 +1556,7 @@ function cleanFinalInput(i: TransactionInput) {
1538
1556
  }
1539
1557
 
1540
1558
  export type TransactionOutput = P.UnwrapCoder<typeof PSBTOutputCoder>;
1541
- export type TransactionOutputUpdate = ExtendType<
1542
- TransactionOutput,
1543
- { amount?: string | number; script?: string }
1544
- >;
1559
+ export type TransactionOutputUpdate = ExtendType<TransactionOutput, { script?: string }>;
1545
1560
  export type TransactionOutputRequired = {
1546
1561
  script: Bytes;
1547
1562
  amount: bigint;
@@ -1642,6 +1657,17 @@ function validateOpts(opts: TxOpts) {
1642
1657
  }
1643
1658
 
1644
1659
  export class Transaction {
1660
+ private global: PSBTKeyMapKeys<typeof PSBTGlobal> = {};
1661
+ private inputs: TransactionInput[] = []; // use getInput()
1662
+ private outputs: TransactionOutput[] = []; // use getOutput()
1663
+ readonly opts: ReturnType<typeof validateOpts>;
1664
+ constructor(opts: TxOpts = {}) {
1665
+ const _opts = (this.opts = validateOpts(opts));
1666
+ // Merge with global structure of PSBTv2
1667
+ if (_opts.lockTime !== DEFAULT_LOCKTIME) this.global.fallbackLocktime = _opts.lockTime;
1668
+ this.global.txVersion = _opts.version;
1669
+ }
1670
+
1645
1671
  // Import
1646
1672
  static fromRaw(raw: Bytes, opts: TxOpts = {}) {
1647
1673
  const parsed = RawTx.decode(raw);
@@ -1687,7 +1713,7 @@ export class Transaction {
1687
1713
  ...i,
1688
1714
  ...parsed.global.unsignedTx?.outputs[j],
1689
1715
  }));
1690
- tx.global = { ...parsed.global, txVersion: version }; // just in case propietary/unknown fields
1716
+ tx.global = { ...parsed.global, txVersion: version }; // just in case proprietary/unknown fields
1691
1717
  if (lockTime !== DEFAULT_LOCKTIME) tx.global.fallbackLocktime = lockTime;
1692
1718
  return tx;
1693
1719
  }
@@ -1725,16 +1751,6 @@ export class Transaction {
1725
1751
  outputs,
1726
1752
  });
1727
1753
  }
1728
- private global: PSBTKeyMapKeys<typeof PSBTGlobal> = {};
1729
- private inputs: TransactionInput[] = [];
1730
- private outputs: TransactionOutput[] = [];
1731
- readonly opts: ReturnType<typeof validateOpts>;
1732
- constructor(opts: TxOpts = {}) {
1733
- const _opts = (this.opts = validateOpts(opts));
1734
- // Merge with global structure of PSBTv2
1735
- if (_opts.lockTime !== DEFAULT_LOCKTIME) this.global.fallbackLocktime = _opts.lockTime;
1736
- this.global.txVersion = _opts.version;
1737
- }
1738
1754
 
1739
1755
  // BIP370 lockTime (https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#determining-lock-time)
1740
1756
  get lockTime() {
@@ -1884,6 +1900,13 @@ export class Transaction {
1884
1900
  if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.inputs.length)
1885
1901
  throw new Error(`Wrong input index=${idx}`);
1886
1902
  }
1903
+ getInput(idx: number) {
1904
+ this.checkInputIdx(idx);
1905
+ return cloneDeep(this.inputs[idx]);
1906
+ }
1907
+ get inputsLength() {
1908
+ return this.inputs.length;
1909
+ }
1887
1910
  // Modification
1888
1911
  private normalizeInput(
1889
1912
  i: TransactionInputUpdate,
@@ -1934,6 +1957,13 @@ export class Transaction {
1934
1957
  if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.outputs.length)
1935
1958
  throw new Error(`Wrong output index=${idx}`);
1936
1959
  }
1960
+ getOutput(idx: number) {
1961
+ this.checkOutputIdx(idx);
1962
+ return cloneDeep(this.outputs[idx]);
1963
+ }
1964
+ get outputsLength() {
1965
+ return this.outputs.length;
1966
+ }
1937
1967
  private normalizeOutput(
1938
1968
  o: TransactionOutputUpdate,
1939
1969
  cur?: TransactionOutput,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@scure/btc-signer",
3
- "version": "0.5.0",
4
- "description": "Audited minimal library for creating, signing & decoding Bitcoin transactions: with Schnorr, Taproot, UTXO & PSBT",
3
+ "version": "1.0.0",
4
+ "description": "Audited & minimal library for creating, signing & decoding Bitcoin transactions: with Schnorr, Taproot, UTXO & PSBT",
5
5
  "files": [
6
6
  "index.js",
7
7
  "index.js.map",
@@ -14,17 +14,17 @@
14
14
  "module": "index.js",
15
15
  "types": "index.d.ts",
16
16
  "dependencies": {
17
- "@noble/curves": "~0.8.0",
18
- "@noble/hashes": "~1.2.0",
19
- "@scure/base": "~1.1.0",
17
+ "@noble/curves": "~1.0.0",
18
+ "@noble/hashes": "~1.3.0",
19
+ "@scure/base": "~1.1.1",
20
20
  "micro-packed": "~0.3.2"
21
21
  },
22
22
  "devDependencies": {
23
- "@scure/bip32": "~1.1.0",
23
+ "@scure/bip32": "~1.3.0",
24
24
  "micro-packed-debugger": "0.3.1",
25
25
  "micro-should": "0.4.0",
26
- "prettier": "2.6.2",
27
- "typescript": "4.7.3"
26
+ "prettier": "2.8.4",
27
+ "typescript": "5.0.2"
28
28
  },
29
29
  "author": "Paul Miller (https://paulmillr.com)",
30
30
  "license": "MIT",