@vbyte/btc-dev 1.0.14 → 1.1.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/dist/module.mjs CHANGED
@@ -785,7 +785,7 @@ const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? glob
785
785
  // Makes the utils un-importable in browsers without a bundler.
786
786
  // Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
787
787
  /** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
788
- function isBytes$3(a) {
788
+ function isBytes$1(a) {
789
789
  return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
790
790
  }
791
791
  /** Asserts something is positive integer. */
@@ -795,7 +795,7 @@ function anumber$1(n) {
795
795
  }
796
796
  /** Asserts something is Uint8Array. */
797
797
  function abytes$1(b, ...lengths) {
798
- if (!isBytes$3(b))
798
+ if (!isBytes$1(b))
799
799
  throw new Error('Uint8Array expected');
800
800
  if (lengths.length > 0 && !lengths.includes(b.length))
801
801
  throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
@@ -829,7 +829,7 @@ function clean(...arrays) {
829
829
  }
830
830
  }
831
831
  /** Create DataView of an array for easy byte-level manipulation. */
832
- function createView$1(arr) {
832
+ function createView(arr) {
833
833
  return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
834
834
  }
835
835
  /** The rotate right (circular right shift) operation for uint32 */
@@ -841,7 +841,7 @@ function rotl(word, shift) {
841
841
  return (word << shift) | ((word >>> (32 - shift)) >>> 0);
842
842
  }
843
843
  // Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
844
- const hasHexBuiltin$1 = /* @__PURE__ */ (() =>
844
+ const hasHexBuiltin = /* @__PURE__ */ (() =>
845
845
  // @ts-ignore
846
846
  typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();
847
847
  // Array where index 0xf0 (240) is mapped to string 'f0'
@@ -853,7 +853,7 @@ const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(1
853
853
  function bytesToHex(bytes) {
854
854
  abytes$1(bytes);
855
855
  // @ts-ignore
856
- if (hasHexBuiltin$1)
856
+ if (hasHexBuiltin)
857
857
  return bytes.toHex();
858
858
  // pre-caching improves the speed 6x
859
859
  let hex = '';
@@ -881,7 +881,7 @@ function hexToBytes(hex) {
881
881
  if (typeof hex !== 'string')
882
882
  throw new Error('hex string expected, got ' + typeof hex);
883
883
  // @ts-ignore
884
- if (hasHexBuiltin$1)
884
+ if (hasHexBuiltin)
885
885
  return Uint8Array.fromHex(hex);
886
886
  const hl = hex.length;
887
887
  const al = hl / 2;
@@ -920,7 +920,7 @@ function toBytes(data) {
920
920
  return data;
921
921
  }
922
922
  /** Copies several Uint8Arrays into one. */
923
- function concatBytes$2(...arrays) {
923
+ function concatBytes(...arrays) {
924
924
  let sum = 0;
925
925
  for (let i = 0; i < arrays.length; i++) {
926
926
  const a = arrays[i];
@@ -1000,7 +1000,7 @@ class HashMD extends Hash {
1000
1000
  this.padOffset = padOffset;
1001
1001
  this.isLE = isLE;
1002
1002
  this.buffer = new Uint8Array(blockLen);
1003
- this.view = createView$1(this.buffer);
1003
+ this.view = createView(this.buffer);
1004
1004
  }
1005
1005
  update(data) {
1006
1006
  aexists(this);
@@ -1012,7 +1012,7 @@ class HashMD extends Hash {
1012
1012
  const take = Math.min(blockLen - this.pos, len - pos);
1013
1013
  // Fast path: we have at least one block in input, cast it to view and process
1014
1014
  if (take === blockLen) {
1015
- const dataView = createView$1(data);
1015
+ const dataView = createView(data);
1016
1016
  for (; blockLen <= len - pos; pos += blockLen)
1017
1017
  this.process(dataView, pos);
1018
1018
  continue;
@@ -1055,7 +1055,7 @@ class HashMD extends Hash {
1055
1055
  // So we just write lowest 64 bits of that value.
1056
1056
  setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
1057
1057
  this.process(view, 0);
1058
- const oview = createView$1(out);
1058
+ const oview = createView(out);
1059
1059
  const len = this.outputLen;
1060
1060
  // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
1061
1061
  if (len % 4)
@@ -1346,7 +1346,7 @@ function ensureBytes(title, hex, expectedLength) {
1346
1346
  throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
1347
1347
  }
1348
1348
  }
1349
- else if (isBytes$3(hex)) {
1349
+ else if (isBytes$1(hex)) {
1350
1350
  // Uint8Array.from() instead of hash.slice() because node.js Buffer
1351
1351
  // is instance of Uint8Array, and its slice() creates **mutable** copy
1352
1352
  res = Uint8Array.from(hex);
@@ -1451,7 +1451,7 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
1451
1451
  out.push(sl);
1452
1452
  len += v.length;
1453
1453
  }
1454
- return concatBytes$2(...out);
1454
+ return concatBytes(...out);
1455
1455
  };
1456
1456
  const genUntil = (seed, pred) => {
1457
1457
  reset();
@@ -2521,10 +2521,10 @@ function weierstrassN(CURVE, curveOpts = {}) {
2521
2521
  if (isCompressed) {
2522
2522
  assertCompressionIsSupported();
2523
2523
  const hasEvenY = !Fp.isOdd(y);
2524
- return concatBytes$2(pprefix(hasEvenY), bx);
2524
+ return concatBytes(pprefix(hasEvenY), bx);
2525
2525
  }
2526
2526
  else {
2527
- return concatBytes$2(Uint8Array.of(0x04), bx, Fp.toBytes(y));
2527
+ return concatBytes(Uint8Array.of(0x04), bx, Fp.toBytes(y));
2528
2528
  }
2529
2529
  }
2530
2530
  function pointFromBytes(bytes) {
@@ -2971,7 +2971,7 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
2971
2971
  });
2972
2972
  const randomBytes_ = ecdsaOpts.randomBytes || randomBytes;
2973
2973
  const hmac_ = ecdsaOpts.hmac ||
2974
- ((key, ...msgs) => hmac(ecdsaOpts.hash, key, concatBytes$2(...msgs)));
2974
+ ((key, ...msgs) => hmac(ecdsaOpts.hash, key, concatBytes(...msgs)));
2975
2975
  const { Fp, Fn } = Point;
2976
2976
  const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;
2977
2977
  function isBiggerThanHalfOrder(number) {
@@ -3039,7 +3039,7 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
3039
3039
  if (!Fp.isValid(radj))
3040
3040
  throw new Error('recovery id 2 or 3 invalid');
3041
3041
  const x = Fp.toBytes(radj);
3042
- const R = Point.fromHex(concatBytes$2(pprefix((rec & 1) === 0), x));
3042
+ const R = Point.fromHex(concatBytes(pprefix((rec & 1) === 0), x));
3043
3043
  const ir = Fn.inv(radj); // r^-1
3044
3044
  const h = bits2int_modN(ensureBytes('msgHash', msgHash)); // Truncate hash
3045
3045
  const u1 = Fn.create(-h * ir); // -hr^-1
@@ -3060,7 +3060,7 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
3060
3060
  }
3061
3061
  toBytes(format) {
3062
3062
  if (format === 'compact')
3063
- return concatBytes$2(Fn.toBytes(this.r), Fn.toBytes(this.s));
3063
+ return concatBytes(Fn.toBytes(this.r), Fn.toBytes(this.s));
3064
3064
  if (format === 'der')
3065
3065
  return hexToBytes(DER.hexFromSig(this));
3066
3066
  throw new Error('invalid format');
@@ -3208,7 +3208,7 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
3208
3208
  const e = ent === true ? randomBytes_(Fp.BYTES) : ent; // generate random bytes OR pass as-is
3209
3209
  seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes
3210
3210
  }
3211
- const seed = concatBytes$2(...seedArgs); // Step D of RFC6979 3.2
3211
+ const seed = concatBytes(...seedArgs); // Step D of RFC6979 3.2
3212
3212
  const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!
3213
3213
  // Converts signature params into point w r/s, checks result for validity.
3214
3214
  // Can use scalar blinding b^-1(bm + bdr) where b ∈ [1,q−1] according to
@@ -3285,7 +3285,7 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
3285
3285
  throw new Error('options.strict was renamed to lowS');
3286
3286
  if (format !== undefined && !['compact', 'der', 'js'].includes(format))
3287
3287
  throw new Error('format must be "compact", "der" or "js"');
3288
- const isHex = typeof sg === 'string' || isBytes$3(sg);
3288
+ const isHex = typeof sg === 'string' || isBytes$1(sg);
3289
3289
  const isObj = !isHex &&
3290
3290
  !format &&
3291
3291
  typeof sg === 'object' &&
@@ -3534,22 +3534,22 @@ function taggedHash(tag, ...messages) {
3534
3534
  let tagP = TAGGED_HASH_PREFIXES[tag];
3535
3535
  if (tagP === undefined) {
3536
3536
  const tagH = sha256$1(Uint8Array.from(tag, (c) => c.charCodeAt(0)));
3537
- tagP = concatBytes$2(tagH, tagH);
3537
+ tagP = concatBytes(tagH, tagH);
3538
3538
  TAGGED_HASH_PREFIXES[tag] = tagP;
3539
3539
  }
3540
- return sha256$1(concatBytes$2(tagP, ...messages));
3540
+ return sha256$1(concatBytes(tagP, ...messages));
3541
3541
  }
3542
3542
  // ECDSA compact points are 33-byte. Schnorr is 32: we strip first byte 0x02 or 0x03
3543
3543
  const pointToBytes = (point) => point.toBytes(true).slice(1);
3544
3544
  const numTo32b = (n) => numberToBytesBE(n, 32);
3545
3545
  const modP = (x) => mod(x, secp256k1_CURVE.p);
3546
3546
  const modN = (x) => mod(x, secp256k1_CURVE.n);
3547
- const Point$1 = /* @__PURE__ */ (() => secp256k1.Point)();
3547
+ const Point = /* @__PURE__ */ (() => secp256k1.Point)();
3548
3548
  const hasEven = (y) => y % _2n === _0n$1;
3549
3549
  // Calculate point, scalar and bytes
3550
3550
  function schnorrGetExtPubKey(priv) {
3551
3551
  let d_ = secp256k1.utils.normPrivateKeyToScalar(priv); // same method executed in fromPrivateKey
3552
- let p = Point$1.fromPrivateKey(d_); // P = d'⋅G; 0 < d' < n check is done inside
3552
+ let p = Point.fromPrivateKey(d_); // P = d'⋅G; 0 < d' < n check is done inside
3553
3553
  const scalar = hasEven(p.y) ? d_ : modN(-d_);
3554
3554
  return { scalar: scalar, bytes: pointToBytes(p) };
3555
3555
  }
@@ -3564,7 +3564,7 @@ function lift_x(x) {
3564
3564
  let y = sqrtMod(c); // Let y = c^(p+1)/4 mod p.
3565
3565
  if (!hasEven(y))
3566
3566
  y = modP(-y); // Return the unique point P such that x(P) = x and
3567
- const p = Point$1.fromAffine({ x, y }); // y(P) = y if y mod 2 = 0 or y(P) = p-y otherwise.
3567
+ const p = Point.fromAffine({ x, y }); // y(P) = y if y mod 2 = 0 or y(P) = p-y otherwise.
3568
3568
  p.assertValidity();
3569
3569
  return p;
3570
3570
  }
@@ -3622,7 +3622,7 @@ function schnorrVerify(signature, message, publicKey) {
3622
3622
  return false;
3623
3623
  const e = challenge(numTo32b(r), pointToBytes(P), m); // int(challenge(bytes(r)||bytes(P)||m))%n
3624
3624
  // R = s⋅G - e⋅P, where -eP == (n-e)P
3625
- const R = Point$1.BASE.multiplyUnsafe(s).add(P.multiplyUnsafe(modN(-e)));
3625
+ const R = Point.BASE.multiplyUnsafe(s).add(P.multiplyUnsafe(modN(-e)));
3626
3626
  const { x, y } = R.toAffine();
3627
3627
  // Fail if is_infinite(R) / not has_even_y(R) / x(R) ≠ r.
3628
3628
  if (R.is0() || !hasEven(y) || x !== r)
@@ -3841,7 +3841,7 @@ class RIPEMD160 extends HashMD {
3841
3841
  */
3842
3842
  const ripemd160 = /* @__PURE__ */ createHasher(() => new RIPEMD160());
3843
3843
 
3844
- function hash160$1(...input) {
3844
+ function hash160(...input) {
3845
3845
  const buffer = Buff.join(input);
3846
3846
  const digest = ripemd160(sha256$1(buffer));
3847
3847
  return new Buff(digest);
@@ -7768,7 +7768,7 @@ float.refine((e) => {
7768
7768
  const parts = String(e).split('.').at(1);
7769
7769
  return parts !== undefined && parts.length <= 2;
7770
7770
  });
7771
- const hex$1 = stringType()
7771
+ const hex = stringType()
7772
7772
  .regex(/^[0-9a-fA-F]*$/)
7773
7773
  .refine(e => e.length % 2 === 0);
7774
7774
  const literal = unionType([
@@ -7779,11 +7779,11 @@ u8a.refine((e) => e.length === 20);
7779
7779
  const u8a32 = u8a.refine((e) => e.length === 32);
7780
7780
  const u8a33 = u8a.refine((e) => e.length === 33);
7781
7781
  const u8a64 = u8a.refine((e) => e.length === 64);
7782
- hex$1.refine((e) => e.length === 40);
7783
- const hex32 = hex$1.refine((e) => e.length === 64);
7784
- const hex33 = hex$1.refine((e) => e.length === 66);
7785
- const hex64 = hex$1.refine((e) => e.length === 128);
7786
- unionType([hex$1, u8a]);
7782
+ hex.refine((e) => e.length === 40);
7783
+ const hex32 = hex.refine((e) => e.length === 64);
7784
+ const hex33 = hex.refine((e) => e.length === 66);
7785
+ const hex64 = hex.refine((e) => e.length === 128);
7786
+ unionType([hex, u8a]);
7787
7787
  const byte32 = unionType([hex32, u8a32]);
7788
7788
  unionType([hex33, u8a33]);
7789
7789
  unionType([hex64, u8a64]);
@@ -7793,12 +7793,12 @@ stringType().regex(/^[a-zA-Z0-9\-_]+={0,2}$/);
7793
7793
  stringType().regex(/^[a-z]+1[023456789acdefghjklmnpqrstuvwxyz]+$/);
7794
7794
 
7795
7795
  /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
7796
- function isBytes$2(a) {
7796
+ function isBytes(a) {
7797
7797
  return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
7798
7798
  }
7799
7799
  /** Asserts something is Uint8Array. */
7800
7800
  function abytes(b, ...lengths) {
7801
- if (!isBytes$2(b))
7801
+ if (!isBytes(b))
7802
7802
  throw new Error('Uint8Array expected');
7803
7803
  if (lengths.length > 0 && !lengths.includes(b.length))
7804
7804
  throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
@@ -7933,13 +7933,6 @@ function padding(bits, chr = '=') {
7933
7933
  },
7934
7934
  };
7935
7935
  }
7936
- /**
7937
- * @__NO_SIDE_EFFECTS__
7938
- */
7939
- function normalize(fn) {
7940
- afn(fn);
7941
- return { encode: (from) => from, decode: (to) => fn(to) };
7942
- }
7943
7936
  /**
7944
7937
  * Slow: O(n^2) time complexity
7945
7938
  */
@@ -8051,7 +8044,7 @@ function radix(num) {
8051
8044
  const _256 = 2 ** 8;
8052
8045
  return {
8053
8046
  encode: (bytes) => {
8054
- if (!isBytes$2(bytes))
8047
+ if (!isBytes(bytes))
8055
8048
  throw new Error('radix.encode input should be Uint8Array');
8056
8049
  return convertRadix(Array.from(bytes), _256, num);
8057
8050
  },
@@ -8074,7 +8067,7 @@ function radix2(bits, revPadding = false) {
8074
8067
  throw new Error('radix2: carry overflow');
8075
8068
  return {
8076
8069
  encode: (bytes) => {
8077
- if (!isBytes$2(bytes))
8070
+ if (!isBytes(bytes))
8078
8071
  throw new Error('radix2.encode input should be Uint8Array');
8079
8072
  return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
8080
8073
  },
@@ -8098,7 +8091,7 @@ function checksum(len, fn) {
8098
8091
  afn(fn);
8099
8092
  return {
8100
8093
  encode(data) {
8101
- if (!isBytes$2(data))
8094
+ if (!isBytes(data))
8102
8095
  throw new Error('checksum.encode: input should be Uint8Array');
8103
8096
  const sum = fn(data).slice(0, len);
8104
8097
  const res = new Uint8Array(data.length + len);
@@ -8107,7 +8100,7 @@ function checksum(len, fn) {
8107
8100
  return res;
8108
8101
  },
8109
8102
  decode(data) {
8110
- if (!isBytes$2(data))
8103
+ if (!isBytes(data))
8111
8104
  throw new Error('checksum.decode: input should be Uint8Array');
8112
8105
  const payload = data.slice(0, -len);
8113
8106
  const oldChecksum = data.slice(-len);
@@ -8220,7 +8213,7 @@ function genBech32(encoding) {
8220
8213
  const fromWordsUnsafe = unsafeWrapper(fromWords);
8221
8214
  function encode(prefix, words, limit = 90) {
8222
8215
  astr('bech32.encode prefix', prefix);
8223
- if (isBytes$2(words))
8216
+ if (isBytes(words))
8224
8217
  words = Array.from(words);
8225
8218
  anumArr('bech32.encode', words);
8226
8219
  const plen = prefix.length;
@@ -8287,42 +8280,6 @@ const bech32 = genBech32('bech32');
8287
8280
  * https://github.com/paulmillr/scure-btc-signer.
8288
8281
  */
8289
8282
  const bech32m = genBech32('bech32m');
8290
- /**
8291
- * UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
8292
- * @example
8293
- * ```js
8294
- * const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
8295
- * const str = utf8.encode(b); // "hey"
8296
- * ```
8297
- */
8298
- const utf8 = {
8299
- encode: (data) => new TextDecoder().decode(data),
8300
- decode: (str) => new TextEncoder().encode(str),
8301
- };
8302
- // Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
8303
- // prettier-ignore
8304
- const hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === 'function' &&
8305
- typeof Uint8Array.fromHex === 'function')();
8306
- // prettier-ignore
8307
- const hexBuiltin = {
8308
- encode(data) { abytes(data); return data.toHex(); },
8309
- decode(s) { astr('hex', s); return Uint8Array.fromHex(s); },
8310
- };
8311
- /**
8312
- * hex string decoder. Uses built-in function, when available.
8313
- * @example
8314
- * ```js
8315
- * const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
8316
- * const str = hex.encode(b); // "0102ff"
8317
- * ```
8318
- */
8319
- const hex = hasHexBuiltin
8320
- ? hexBuiltin
8321
- : chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
8322
- if (typeof s !== 'string' || s.length % 2 !== 0)
8323
- throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
8324
- return s.toLowerCase();
8325
- }));
8326
8283
 
8327
8284
  var B58chk;
8328
8285
  (function (B58chk) {
@@ -8586,7 +8543,7 @@ var P2PKH;
8586
8543
  })(P2PKH || (P2PKH = {}));
8587
8544
  function create_p2pkh_address(script, network = 'main') {
8588
8545
  const bytes = Buff.bytes(script);
8589
- const hash = hash160$1(bytes);
8546
+ const hash = hash160(bytes);
8590
8547
  return encode_p2pkh_address(hash, network);
8591
8548
  }
8592
8549
  function encode_p2pkh_address(pk_hash, network = 'main') {
@@ -8615,7 +8572,7 @@ var P2SH;
8615
8572
  })(P2SH || (P2SH = {}));
8616
8573
  function create_p2sh_address(script, network = 'main') {
8617
8574
  const bytes = Buff.bytes(script);
8618
- const hash = hash160$1(bytes);
8575
+ const hash = hash160(bytes);
8619
8576
  return encode_p2sh_address(hash, network);
8620
8577
  }
8621
8578
  function encode_p2sh_address(script_hash, network = 'main') {
@@ -8645,7 +8602,7 @@ var P2WPKH;
8645
8602
  function create_p2wpkh_address(pubkey, network = 'main') {
8646
8603
  const bytes = Buff.bytes(pubkey);
8647
8604
  Assert.size(bytes, 33, `invalid payload size: ${bytes.length} !== 33`);
8648
- const hash = hash160$1(bytes);
8605
+ const hash = hash160(bytes);
8649
8606
  return encode_p2wpkh_address(hash, network);
8650
8607
  }
8651
8608
  function encode_p2wpkh_address(pk_hash, network = 'main') {
@@ -8727,7 +8684,7 @@ var AddressTool;
8727
8684
  AddressTool.parse = parse_address;
8728
8685
  })(AddressTool || (AddressTool = {}));
8729
8686
 
8730
- var index$9 = /*#__PURE__*/Object.freeze({
8687
+ var index$8 = /*#__PURE__*/Object.freeze({
8731
8688
  __proto__: null,
8732
8689
  get AddressTool () { return AddressTool; },
8733
8690
  get P2PKH () { return P2PKH; },
@@ -9398,7 +9355,7 @@ function parse_height(height) {
9398
9355
  return height;
9399
9356
  }
9400
9357
 
9401
- var index$8 = /*#__PURE__*/Object.freeze({
9358
+ var index$7 = /*#__PURE__*/Object.freeze({
9402
9359
  __proto__: null,
9403
9360
  get LocktimeUtil () { return LocktimeUtil; },
9404
9361
  get RefEncoder () { return RefEncoder; },
@@ -9412,3977 +9369,81 @@ var index$8 = /*#__PURE__*/Object.freeze({
9412
9369
  encode_sequence: encode_sequence
9413
9370
  });
9414
9371
 
9415
- /**
9416
- * Define complex binary structures using composable primitives.
9417
- * Main ideas:
9418
- * - Encode / decode can be chained, same as in `scure-base`
9419
- * - A complex structure can be created from an array and struct of primitive types
9420
- * - Strings / bytes are arrays with specific optimizations: we can just read bytes directly
9421
- * without creating plain array first and reading each byte separately.
9422
- * - Types are inferred from definition
9423
- * @module
9424
- * @example
9425
- * import * as P from 'micro-packed';
9426
- * const s = P.struct({
9427
- * field1: P.U32BE, // 32-bit unsigned big-endian integer
9428
- * field2: P.string(P.U8), // String with U8 length prefix
9429
- * field3: P.bytes(32), // 32 bytes
9430
- * field4: P.array(P.U16BE, P.struct({ // Array of structs with U16BE length
9431
- * subField1: P.U64BE, // 64-bit unsigned big-endian integer
9432
- * subField2: P.string(10) // 10-byte string
9433
- * }))
9434
- * });
9435
- */
9436
- // TODO: remove dependency on scure-base & inline?
9437
- /*
9438
- Exports can be groupped like this:
9439
-
9440
- - Primitive types: P.bytes, P.string, P.hex, P.constant, P.pointer
9441
- - Complex types: P.array, P.struct, P.tuple, P.map, P.tag, P.mappedTag
9442
- - Padding, prefix, magic: P.padLeft, P.padRight, P.prefix, P.magic, P.magicBytes
9443
- - Flags: P.flag, P.flagged, P.optional
9444
- - Wrappers: P.apply, P.wrap, P.lazy
9445
- - Bit fiddling: P.bits, P.bitset
9446
- - utils: P.validate, coders.decimal
9447
- - Debugger
9448
- */
9449
- /** Shortcut to zero-length (empty) byte array */
9450
- const EMPTY = /* @__PURE__ */ new Uint8Array();
9451
- /** Shortcut to one-element (element is 0) byte array */
9452
- const NULL = /* @__PURE__ */ new Uint8Array([0]);
9453
- /** Checks if two Uint8Arrays are equal. Not constant-time. */
9454
- function equalBytes$1(a, b) {
9455
- if (a.length !== b.length)
9456
- return false;
9457
- for (let i = 0; i < a.length; i++)
9458
- if (a[i] !== b[i])
9459
- return false;
9460
- return true;
9372
+ function prefix_script_size(script) {
9373
+ return Buff.bytes(script).prefix_varint('le').hex;
9461
9374
  }
9462
- /** Checks if the given value is a Uint8Array. */
9463
- function isBytes$1(a) {
9464
- return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
9375
+ function parse_script_pubkeys(script) {
9376
+ const scriptHex = typeof script === 'string' ? script : Buff.bytes(script).hex;
9377
+ const pubkeyPattern = /20([0-9a-f]{64})(ac|ad|ba)/gi;
9378
+ const matches = [...scriptHex.matchAll(pubkeyPattern)];
9379
+ return matches.map(match => match[1]);
9465
9380
  }
9466
- /**
9467
- * Concatenates multiple Uint8Arrays.
9468
- * Engines limit functions to 65K+ arguments.
9469
- * @param arrays Array of Uint8Array elements
9470
- * @returns Concatenated Uint8Array
9471
- */
9472
- function concatBytes$1(...arrays) {
9473
- let sum = 0;
9474
- for (let i = 0; i < arrays.length; i++) {
9475
- const a = arrays[i];
9476
- if (!isBytes$1(a))
9477
- throw new Error('Uint8Array expected');
9478
- sum += a.length;
9479
- }
9480
- const res = new Uint8Array(sum);
9481
- for (let i = 0, pad = 0; i < arrays.length; i++) {
9482
- const a = arrays[i];
9483
- res.set(a, pad);
9484
- pad += a.length;
9485
- }
9486
- return res;
9381
+
9382
+ var ScriptUtil;
9383
+ (function (ScriptUtil) {
9384
+ ScriptUtil.prefix_size = prefix_script_size;
9385
+ ScriptUtil.decode = decode_script;
9386
+ ScriptUtil.encode = encode_script;
9387
+ ScriptUtil.is_valid = is_valid_script;
9388
+ ScriptUtil.get_pubkeys = parse_script_pubkeys;
9389
+ ScriptUtil.OPCODES = OPCODE_MAP;
9390
+ })(ScriptUtil || (ScriptUtil = {}));
9391
+
9392
+ var index$6 = /*#__PURE__*/Object.freeze({
9393
+ __proto__: null,
9394
+ OPCODE_MAP: OPCODE_MAP,
9395
+ get ScriptUtil () { return ScriptUtil; },
9396
+ decode_script: decode_script,
9397
+ encode_script: encode_script,
9398
+ encode_script_word: encode_script_word,
9399
+ get_asm_code: get_asm_code,
9400
+ get_op_code: get_op_code,
9401
+ get_op_type: get_op_type,
9402
+ get_size_varint: get_size_varint,
9403
+ is_valid_op: is_valid_op,
9404
+ is_valid_script: is_valid_script,
9405
+ parse_script_pubkeys: parse_script_pubkeys,
9406
+ prefix_script_size: prefix_script_size,
9407
+ prefix_word_size: prefix_word_size,
9408
+ split_script_word: split_script_word
9409
+ });
9410
+
9411
+ function get_prevout(vin) {
9412
+ Assert.exists(vin.prevout, 'Prevout data missing for input: ' + String(vin.txid));
9413
+ return vin.prevout;
9487
9414
  }
9488
- /**
9489
- * Creates DataView from Uint8Array
9490
- * @param arr - bytes
9491
- * @returns DataView
9492
- */
9493
- const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
9494
- /**
9495
- * Checks if the provided value is a plain object, not created from any class or special constructor.
9496
- * Array, Uint8Array and others are not plain objects.
9497
- * @param obj - The value to be checked.
9498
- */
9499
- function isPlainObject(obj) {
9500
- return Object.prototype.toString.call(obj) === '[object Object]';
9501
- }
9502
- function isNum(num) {
9503
- return Number.isSafeInteger(num);
9504
- }
9505
- const utils = {
9506
- equalBytes: equalBytes$1,
9507
- isBytes: isBytes$1,
9508
- concatBytes: concatBytes$1};
9509
- // NOTE: we can't have terminator separate function, since it won't know about boundaries
9510
- // E.g. array of U16LE ([1,2,3]) would be [1, 0, 2, 0, 3, 0]
9511
- // But terminator will find array at index '1', which happens to be inside of an element itself
9512
- /**
9513
- * Can be:
9514
- * - Dynamic (CoderType)
9515
- * - Fixed (number)
9516
- * - Terminated (usually zero): Uint8Array with terminator
9517
- * - Field path to field with length (string)
9518
- * - Infinity (null) - decodes until end of buffer
9519
- * Used in:
9520
- * - bytes (string, prefix is implementation of bytes)
9521
- * - array
9522
- */
9523
- const lengthCoder = (len) => {
9524
- if (len !== null && typeof len !== 'string' && !isCoder(len) && !isBytes$1(len) && !isNum(len)) {
9525
- throw new Error(`lengthCoder: expected null | number | Uint8Array | CoderType, got ${len} (${typeof len})`);
9526
- }
9527
- return {
9528
- encodeStream(w, value) {
9529
- if (len === null)
9530
- return;
9531
- if (isCoder(len))
9532
- return len.encodeStream(w, value);
9533
- let byteLen;
9534
- if (typeof len === 'number')
9535
- byteLen = len;
9536
- else if (typeof len === 'string')
9537
- byteLen = Path.resolve(w.stack, len);
9538
- if (typeof byteLen === 'bigint')
9539
- byteLen = Number(byteLen);
9540
- if (byteLen === undefined || byteLen !== value)
9541
- throw w.err(`Wrong length: ${byteLen} len=${len} exp=${value} (${typeof value})`);
9542
- },
9543
- decodeStream(r) {
9544
- let byteLen;
9545
- if (isCoder(len))
9546
- byteLen = Number(len.decodeStream(r));
9547
- else if (typeof len === 'number')
9548
- byteLen = len;
9549
- else if (typeof len === 'string')
9550
- byteLen = Path.resolve(r.stack, len);
9551
- if (typeof byteLen === 'bigint')
9552
- byteLen = Number(byteLen);
9553
- if (typeof byteLen !== 'number')
9554
- throw r.err(`Wrong length: ${byteLen}`);
9555
- return byteLen;
9556
- },
9557
- };
9558
- };
9559
- /**
9560
- * Small bitset structure to store position of ranges that have been read.
9561
- * Can be more efficient when internal trees are utilized at the cost of complexity.
9562
- * Needs `O(N/8)` memory for parsing.
9563
- * Purpose: if there are pointers in parsed structure,
9564
- * they can cause read of two distinct ranges:
9565
- * [0-32, 64-128], which means 'pos' is not enough to handle them
9566
- */
9567
- const Bitset = {
9568
- BITS: 32,
9569
- FULL_MASK: -1 >>> 0, // 1<<32 will overflow
9570
- len: (len) => Math.ceil(len / 32),
9571
- create: (len) => new Uint32Array(Bitset.len(len)),
9572
- clean: (bs) => bs.fill(0),
9573
- debug: (bs) => Array.from(bs).map((i) => (i >>> 0).toString(2).padStart(32, '0')),
9574
- checkLen: (bs, len) => {
9575
- if (Bitset.len(len) === bs.length)
9576
- return;
9577
- throw new Error(`wrong length=${bs.length}. Expected: ${Bitset.len(len)}`);
9578
- },
9579
- chunkLen: (bsLen, pos, len) => {
9580
- if (pos < 0)
9581
- throw new Error(`wrong pos=${pos}`);
9582
- if (pos + len > bsLen)
9583
- throw new Error(`wrong range=${pos}/${len} of ${bsLen}`);
9584
- },
9585
- set: (bs, chunk, value, allowRewrite = true) => {
9586
- if (!allowRewrite && (bs[chunk] & value) !== 0)
9587
- return false;
9588
- bs[chunk] |= value;
9589
- return true;
9590
- },
9591
- pos: (pos, i) => ({
9592
- chunk: Math.floor((pos + i) / 32),
9593
- mask: 1 << (32 - ((pos + i) % 32) - 1),
9594
- }),
9595
- indices: (bs, len, invert = false) => {
9596
- Bitset.checkLen(bs, len);
9597
- const { FULL_MASK, BITS } = Bitset;
9598
- const left = BITS - (len % BITS);
9599
- const lastMask = left ? (FULL_MASK >>> left) << left : FULL_MASK;
9600
- const res = [];
9601
- for (let i = 0; i < bs.length; i++) {
9602
- let c = bs[i];
9603
- if (invert)
9604
- c = ~c; // allows to gen unset elements
9605
- // apply mask to last element, so we won't iterate non-existent items
9606
- if (i === bs.length - 1)
9607
- c &= lastMask;
9608
- if (c === 0)
9609
- continue; // fast-path
9610
- for (let j = 0; j < BITS; j++) {
9611
- const m = 1 << (BITS - j - 1);
9612
- if (c & m)
9613
- res.push(i * BITS + j);
9614
- }
9615
- }
9616
- return res;
9617
- },
9618
- range: (arr) => {
9619
- const res = [];
9620
- let cur;
9621
- for (const i of arr) {
9622
- if (cur === undefined || i !== cur.pos + cur.length)
9623
- res.push((cur = { pos: i, length: 1 }));
9624
- else
9625
- cur.length += 1;
9626
- }
9627
- return res;
9628
- },
9629
- rangeDebug: (bs, len, invert = false) => `[${Bitset.range(Bitset.indices(bs, len, invert))
9630
- .map((i) => `(${i.pos}/${i.length})`)
9631
- .join(', ')}]`,
9632
- setRange: (bs, bsLen, pos, len, allowRewrite = true) => {
9633
- Bitset.chunkLen(bsLen, pos, len);
9634
- const { FULL_MASK, BITS } = Bitset;
9635
- // Try to set range with maximum efficiency:
9636
- // - first chunk is always '0000[1111]' (only right ones)
9637
- // - middle chunks are set to '[1111 1111]' (all ones)
9638
- // - last chunk is always '[1111]0000' (only left ones)
9639
- // - max operations: (N/32) + 2 (first and last)
9640
- const first = pos % BITS ? Math.floor(pos / BITS) : undefined;
9641
- const lastPos = pos + len;
9642
- const last = lastPos % BITS ? Math.floor(lastPos / BITS) : undefined;
9643
- // special case, whole range inside single chunk
9644
- if (first !== undefined && first === last)
9645
- return Bitset.set(bs, first, (FULL_MASK >>> (BITS - len)) << (BITS - len - pos), allowRewrite);
9646
- if (first !== undefined) {
9647
- if (!Bitset.set(bs, first, FULL_MASK >>> pos % BITS, allowRewrite))
9648
- return false; // first chunk
9649
- }
9650
- // middle chunks
9651
- const start = first !== undefined ? first + 1 : pos / BITS;
9652
- const end = last !== undefined ? last : lastPos / BITS;
9653
- for (let i = start; i < end; i++)
9654
- if (!Bitset.set(bs, i, FULL_MASK, allowRewrite))
9655
- return false;
9656
- if (last !== undefined && first !== last)
9657
- if (!Bitset.set(bs, last, FULL_MASK << (BITS - (lastPos % BITS)), allowRewrite))
9658
- return false; // last chunk
9659
- return true;
9660
- },
9661
- };
9662
- const Path = {
9663
- /**
9664
- * Internal method for handling stack of paths (debug, errors, dynamic fields via path)
9665
- * This is looks ugly (callback), but allows us to force stack cleaning by construction (.pop always after function).
9666
- * Also, this makes impossible:
9667
- * - pushing field when stack is empty
9668
- * - pushing field inside of field (real bug)
9669
- * NOTE: we don't want to do '.pop' on error!
9670
- */
9671
- pushObj: (stack, obj, objFn) => {
9672
- const last = { obj };
9673
- stack.push(last);
9674
- objFn((field, fieldFn) => {
9675
- last.field = field;
9676
- fieldFn();
9677
- last.field = undefined;
9678
- });
9679
- stack.pop();
9680
- },
9681
- path: (stack) => {
9682
- const res = [];
9683
- for (const i of stack)
9684
- if (i.field !== undefined)
9685
- res.push(i.field);
9686
- return res.join('/');
9687
- },
9688
- err: (name, stack, msg) => {
9689
- const err = new Error(`${name}(${Path.path(stack)}): ${typeof msg === 'string' ? msg : msg.message}`);
9690
- if (msg instanceof Error && msg.stack)
9691
- err.stack = msg.stack;
9692
- return err;
9693
- },
9694
- resolve: (stack, path) => {
9695
- const parts = path.split('/');
9696
- const objPath = stack.map((i) => i.obj);
9697
- let i = 0;
9698
- for (; i < parts.length; i++) {
9699
- if (parts[i] === '..')
9700
- objPath.pop();
9701
- else
9702
- break;
9703
- }
9704
- let cur = objPath.pop();
9705
- for (; i < parts.length; i++) {
9706
- if (!cur || cur[parts[i]] === undefined)
9707
- return undefined;
9708
- cur = cur[parts[i]];
9709
- }
9710
- return cur;
9711
- },
9712
- };
9713
- /**
9714
- * Internal structure. Reader class for reading from a byte array.
9715
- * `stack` is internal: for debugger and logging
9716
- * @class Reader
9717
- */
9718
- class _Reader {
9719
- constructor(data, opts = {}, stack = [], parent = undefined, parentOffset = 0) {
9720
- this.pos = 0;
9721
- this.bitBuf = 0;
9722
- this.bitPos = 0;
9723
- this.data = data;
9724
- this.opts = opts;
9725
- this.stack = stack;
9726
- this.parent = parent;
9727
- this.parentOffset = parentOffset;
9728
- this.view = createView(data);
9729
- }
9730
- /** Internal method for pointers. */
9731
- _enablePointers() {
9732
- if (this.parent)
9733
- return this.parent._enablePointers();
9734
- if (this.bs)
9735
- return;
9736
- this.bs = Bitset.create(this.data.length);
9737
- Bitset.setRange(this.bs, this.data.length, 0, this.pos, this.opts.allowMultipleReads);
9738
- }
9739
- markBytesBS(pos, len) {
9740
- if (this.parent)
9741
- return this.parent.markBytesBS(this.parentOffset + pos, len);
9742
- if (!len)
9743
- return true;
9744
- if (!this.bs)
9745
- return true;
9746
- return Bitset.setRange(this.bs, this.data.length, pos, len, false);
9747
- }
9748
- markBytes(len) {
9749
- const pos = this.pos;
9750
- this.pos += len;
9751
- const res = this.markBytesBS(pos, len);
9752
- if (!this.opts.allowMultipleReads && !res)
9753
- throw this.err(`multiple read pos=${this.pos} len=${len}`);
9754
- return res;
9755
- }
9756
- pushObj(obj, objFn) {
9757
- return Path.pushObj(this.stack, obj, objFn);
9758
- }
9759
- readView(n, fn) {
9760
- if (!Number.isFinite(n))
9761
- throw this.err(`readView: wrong length=${n}`);
9762
- if (this.pos + n > this.data.length)
9763
- throw this.err('readView: Unexpected end of buffer');
9764
- const res = fn(this.view, this.pos);
9765
- this.markBytes(n);
9766
- return res;
9767
- }
9768
- // read bytes by absolute offset
9769
- absBytes(n) {
9770
- if (n > this.data.length)
9771
- throw new Error('Unexpected end of buffer');
9772
- return this.data.subarray(n);
9773
- }
9774
- finish() {
9775
- if (this.opts.allowUnreadBytes)
9776
- return;
9777
- if (this.bitPos) {
9778
- throw this.err(`${this.bitPos} bits left after unpack: ${hex.encode(this.data.slice(this.pos))}`);
9779
- }
9780
- if (this.bs && !this.parent) {
9781
- const notRead = Bitset.indices(this.bs, this.data.length, true);
9782
- if (notRead.length) {
9783
- const formatted = Bitset.range(notRead)
9784
- .map(({ pos, length }) => `(${pos}/${length})[${hex.encode(this.data.subarray(pos, pos + length))}]`)
9785
- .join(', ');
9786
- throw this.err(`unread byte ranges: ${formatted} (total=${this.data.length})`);
9787
- }
9788
- else
9789
- return; // all bytes read, everything is ok
9790
- }
9791
- // Default: no pointers enabled
9792
- if (!this.isEnd()) {
9793
- throw this.err(`${this.leftBytes} bytes ${this.bitPos} bits left after unpack: ${hex.encode(this.data.slice(this.pos))}`);
9794
- }
9795
- }
9796
- // User methods
9797
- err(msg) {
9798
- return Path.err('Reader', this.stack, msg);
9799
- }
9800
- offsetReader(n) {
9801
- if (n > this.data.length)
9802
- throw this.err('offsetReader: Unexpected end of buffer');
9803
- return new _Reader(this.absBytes(n), this.opts, this.stack, this, n);
9804
- }
9805
- bytes(n, peek = false) {
9806
- if (this.bitPos)
9807
- throw this.err('readBytes: bitPos not empty');
9808
- if (!Number.isFinite(n))
9809
- throw this.err(`readBytes: wrong length=${n}`);
9810
- if (this.pos + n > this.data.length)
9811
- throw this.err('readBytes: Unexpected end of buffer');
9812
- const slice = this.data.subarray(this.pos, this.pos + n);
9813
- if (!peek)
9814
- this.markBytes(n);
9815
- return slice;
9816
- }
9817
- byte(peek = false) {
9818
- if (this.bitPos)
9819
- throw this.err('readByte: bitPos not empty');
9820
- if (this.pos + 1 > this.data.length)
9821
- throw this.err('readBytes: Unexpected end of buffer');
9822
- const data = this.data[this.pos];
9823
- if (!peek)
9824
- this.markBytes(1);
9825
- return data;
9826
- }
9827
- get leftBytes() {
9828
- return this.data.length - this.pos;
9829
- }
9830
- get totalBytes() {
9831
- return this.data.length;
9832
- }
9833
- isEnd() {
9834
- return this.pos >= this.data.length && !this.bitPos;
9835
- }
9836
- // bits are read in BE mode (left to right): (0b1000_0000).readBits(1) == 1
9837
- bits(bits) {
9838
- if (bits > 32)
9839
- throw this.err('BitReader: cannot read more than 32 bits in single call');
9840
- let out = 0;
9841
- while (bits) {
9842
- if (!this.bitPos) {
9843
- this.bitBuf = this.byte();
9844
- this.bitPos = 8;
9845
- }
9846
- const take = Math.min(bits, this.bitPos);
9847
- this.bitPos -= take;
9848
- out = (out << take) | ((this.bitBuf >> this.bitPos) & (2 ** take - 1));
9849
- this.bitBuf &= 2 ** this.bitPos - 1;
9850
- bits -= take;
9851
- }
9852
- // Fix signed integers
9853
- return out >>> 0;
9854
- }
9855
- find(needle, pos = this.pos) {
9856
- if (!isBytes$1(needle))
9857
- throw this.err(`find: needle is not bytes! ${needle}`);
9858
- if (this.bitPos)
9859
- throw this.err('findByte: bitPos not empty');
9860
- if (!needle.length)
9861
- throw this.err(`find: needle is empty`);
9862
- // indexOf should be faster than full equalBytes check
9863
- for (let idx = pos; (idx = this.data.indexOf(needle[0], idx)) !== -1; idx++) {
9864
- if (idx === -1)
9865
- return;
9866
- const leftBytes = this.data.length - idx;
9867
- if (leftBytes < needle.length)
9868
- return;
9869
- if (equalBytes$1(needle, this.data.subarray(idx, idx + needle.length)))
9870
- return idx;
9415
+ function parse_txinput(txdata, config) {
9416
+ let { txindex, txinput } = config ?? {};
9417
+ if (txindex !== undefined) {
9418
+ if (txindex >= txdata.vin.length) {
9419
+ throw new Error('Input index out of bounds: ' + String(txindex));
9871
9420
  }
9872
- return;
9421
+ txinput = txdata.vin.at(txindex);
9873
9422
  }
9423
+ Assert.ok(txinput !== undefined);
9424
+ return txinput;
9874
9425
  }
9875
- /**
9876
- * Internal structure. Writer class for writing to a byte array.
9877
- * The `stack` argument of constructor is internal, for debugging and logs.
9878
- * @class Writer
9879
- */
9880
- class _Writer {
9881
- constructor(stack = []) {
9882
- this.pos = 0;
9883
- // We could have a single buffer here and re-alloc it with
9884
- // x1.5-2 size each time it full, but it will be slower:
9885
- // basic/encode bench: 395ns -> 560ns
9886
- this.buffers = [];
9887
- this.ptrs = [];
9888
- this.bitBuf = 0;
9889
- this.bitPos = 0;
9890
- this.viewBuf = new Uint8Array(8);
9891
- this.finished = false;
9892
- this.stack = stack;
9893
- this.view = createView(this.viewBuf);
9894
- }
9895
- pushObj(obj, objFn) {
9896
- return Path.pushObj(this.stack, obj, objFn);
9897
- }
9898
- writeView(len, fn) {
9899
- if (this.finished)
9900
- throw this.err('buffer: finished');
9901
- if (!isNum(len) || len > 8)
9902
- throw new Error(`wrong writeView length=${len}`);
9903
- fn(this.view);
9904
- this.bytes(this.viewBuf.slice(0, len));
9905
- this.viewBuf.fill(0);
9906
- }
9907
- // User methods
9908
- err(msg) {
9909
- if (this.finished)
9910
- throw this.err('buffer: finished');
9911
- return Path.err('Reader', this.stack, msg);
9912
- }
9913
- bytes(b) {
9914
- if (this.finished)
9915
- throw this.err('buffer: finished');
9916
- if (this.bitPos)
9917
- throw this.err('writeBytes: ends with non-empty bit buffer');
9918
- this.buffers.push(b);
9919
- this.pos += b.length;
9920
- }
9921
- byte(b) {
9922
- if (this.finished)
9923
- throw this.err('buffer: finished');
9924
- if (this.bitPos)
9925
- throw this.err('writeByte: ends with non-empty bit buffer');
9926
- this.buffers.push(new Uint8Array([b]));
9927
- this.pos++;
9928
- }
9929
- finish(clean = true) {
9930
- if (this.finished)
9931
- throw this.err('buffer: finished');
9932
- if (this.bitPos)
9933
- throw this.err('buffer: ends with non-empty bit buffer');
9934
- // Can't use concatBytes, because it limits amount of arguments (65K).
9935
- const buffers = this.buffers.concat(this.ptrs.map((i) => i.buffer));
9936
- const sum = buffers.map((b) => b.length).reduce((a, b) => a + b, 0);
9937
- const buf = new Uint8Array(sum);
9938
- for (let i = 0, pad = 0; i < buffers.length; i++) {
9939
- const a = buffers[i];
9940
- buf.set(a, pad);
9941
- pad += a.length;
9942
- }
9943
- for (let pos = this.pos, i = 0; i < this.ptrs.length; i++) {
9944
- const ptr = this.ptrs[i];
9945
- buf.set(ptr.ptr.encode(pos), ptr.pos);
9946
- pos += ptr.buffer.length;
9947
- }
9948
- // Cleanup
9949
- if (clean) {
9950
- // We cannot cleanup buffers here, since it can be static user provided buffer.
9951
- // Only '.byte' and '.bits' create buffer which we can safely clean.
9952
- // for (const b of this.buffers) b.fill(0);
9953
- this.buffers = [];
9954
- for (const p of this.ptrs)
9955
- p.buffer.fill(0);
9956
- this.ptrs = [];
9957
- this.finished = true;
9958
- this.bitBuf = 0;
9959
- }
9960
- return buf;
9961
- }
9962
- bits(value, bits) {
9963
- if (bits > 32)
9964
- throw this.err('writeBits: cannot write more than 32 bits in single call');
9965
- if (value >= 2 ** bits)
9966
- throw this.err(`writeBits: value (${value}) >= 2**bits (${bits})`);
9967
- while (bits) {
9968
- const take = Math.min(bits, 8 - this.bitPos);
9969
- this.bitBuf = (this.bitBuf << take) | (value >> (bits - take));
9970
- this.bitPos += take;
9971
- bits -= take;
9972
- value &= 2 ** bits - 1;
9973
- if (this.bitPos === 8) {
9974
- this.bitPos = 0;
9975
- this.buffers.push(new Uint8Array([this.bitBuf]));
9976
- this.pos++;
9977
- }
9978
- }
9979
- }
9980
- }
9981
- // Immutable LE<->BE
9982
- const swapEndianness = (b) => Uint8Array.from(b).reverse();
9983
- /** Internal function for checking bit bounds of bigint in signed/unsinged form */
9984
- function checkBounds(value, bits, signed) {
9985
- if (signed) {
9986
- // [-(2**(32-1)), 2**(32-1)-1]
9987
- const signBit = 2n ** (bits - 1n);
9988
- if (value < -signBit || value >= signBit)
9989
- throw new Error(`value out of signed bounds. Expected ${-signBit} <= ${value} < ${signBit}`);
9990
- }
9991
- else {
9992
- // [0, 2**32-1]
9993
- if (0n > value || value >= 2n ** bits)
9994
- throw new Error(`value out of unsigned bounds. Expected 0 <= ${value} < ${2n ** bits}`);
9426
+ function get_annex_data(witness) {
9427
+ if (witness === undefined)
9428
+ return;
9429
+ if (witness.length < 2)
9430
+ return;
9431
+ const annex = witness.at(-1);
9432
+ if (typeof annex === 'string' && annex.startsWith('50')) {
9433
+ const bytes = Buff.hex(annex).prefix_varint('be');
9434
+ return sha256(bytes);
9995
9435
  }
9436
+ return undefined;
9996
9437
  }
9997
- function _wrap(inner) {
9998
- return {
9999
- // NOTE: we cannot export validate here, since it is likely mistake.
10000
- encodeStream: inner.encodeStream,
10001
- decodeStream: inner.decodeStream,
10002
- size: inner.size,
10003
- encode: (value) => {
10004
- const w = new _Writer();
10005
- inner.encodeStream(w, value);
10006
- return w.finish();
10007
- },
10008
- decode: (data, opts = {}) => {
10009
- const r = new _Reader(data, opts);
10010
- const res = inner.decodeStream(r);
10011
- r.finish();
10012
- return res;
10013
- },
10014
- };
10015
- }
10016
- /**
10017
- * Validates a value before encoding and after decoding using a provided function.
10018
- * @param inner - The inner CoderType.
10019
- * @param fn - The validation function.
10020
- * @returns CoderType which check value with validation function.
10021
- * @example
10022
- * const val = (n: number) => {
10023
- * if (n > 10) throw new Error(`${n} > 10`);
10024
- * return n;
10025
- * };
10026
- *
10027
- * const RangedInt = P.validate(P.U32LE, val); // Will check if value is <= 10 during encoding and decoding
10028
- */
10029
- function validate(inner, fn) {
10030
- if (!isCoder(inner))
10031
- throw new Error(`validate: invalid inner value ${inner}`);
10032
- if (typeof fn !== 'function')
10033
- throw new Error('validate: fn should be function');
10034
- return _wrap({
10035
- size: inner.size,
10036
- encodeStream: (w, value) => {
10037
- let res;
10038
- try {
10039
- res = fn(value);
10040
- }
10041
- catch (e) {
10042
- throw w.err(e);
10043
- }
10044
- inner.encodeStream(w, res);
10045
- },
10046
- decodeStream: (r) => {
10047
- const res = inner.decodeStream(r);
10048
- try {
10049
- return fn(res);
10050
- }
10051
- catch (e) {
10052
- throw r.err(e);
10053
- }
10054
- },
10055
- });
10056
- }
10057
- /**
10058
- * Wraps a stream encoder into a generic encoder and optionally validation function
10059
- * @param {inner} inner BytesCoderStream & { validate?: Validate<T> }.
10060
- * @returns The wrapped CoderType.
10061
- * @example
10062
- * const U8 = P.wrap({
10063
- * encodeStream: (w: Writer, value: number) => w.byte(value),
10064
- * decodeStream: (r: Reader): number => r.byte()
10065
- * });
10066
- * const checkedU8 = P.wrap({
10067
- * encodeStream: (w: Writer, value: number) => w.byte(value),
10068
- * decodeStream: (r: Reader): number => r.byte()
10069
- * validate: (n: number) => {
10070
- * if (n > 10) throw new Error(`${n} > 10`);
10071
- * return n;
10072
- * }
10073
- * });
10074
- */
10075
- const wrap = (inner) => {
10076
- const res = _wrap(inner);
10077
- return inner.validate ? validate(res, inner.validate) : res;
9438
+
9439
+ const COINBASE = {
9440
+ TXID: '00'.repeat(32),
9441
+ VOUT: 0xFFFFFFFF,
10078
9442
  };
10079
- const isBaseCoder = (elm) => isPlainObject(elm) && typeof elm.decode === 'function' && typeof elm.encode === 'function';
10080
- /**
10081
- * Checks if the given value is a CoderType.
10082
- * @param elm - The value to check.
10083
- * @returns True if the value is a CoderType, false otherwise.
10084
- */
10085
- function isCoder(elm) {
10086
- return (isPlainObject(elm) &&
10087
- isBaseCoder(elm) &&
10088
- typeof elm.encodeStream === 'function' &&
10089
- typeof elm.decodeStream === 'function' &&
10090
- (elm.size === undefined || isNum(elm.size)));
10091
- }
10092
- // Coders (like in @scure/base) for common operations
10093
- /**
10094
- * Base coder for working with dictionaries (records, objects, key-value map)
10095
- * Dictionary is dynamic type like: `[key: string, value: any][]`
10096
- * @returns base coder that encodes/decodes between arrays of key-value tuples and dictionaries.
10097
- * @example
10098
- * const dict: P.CoderType<Record<string, number>> = P.apply(
10099
- * P.array(P.U16BE, P.tuple([P.cstring, P.U32LE] as const)),
10100
- * P.coders.dict()
10101
- * );
10102
- */
10103
- function dict() {
10104
- return {
10105
- encode: (from) => {
10106
- if (!Array.isArray(from))
10107
- throw new Error('array expected');
10108
- const to = {};
10109
- for (const item of from) {
10110
- if (!Array.isArray(item) || item.length !== 2)
10111
- throw new Error(`array of two elements expected`);
10112
- const name = item[0];
10113
- const value = item[1];
10114
- if (to[name] !== undefined)
10115
- throw new Error(`key(${name}) appears twice in struct`);
10116
- to[name] = value;
10117
- }
10118
- return to;
10119
- },
10120
- decode: (to) => {
10121
- if (!isPlainObject(to))
10122
- throw new Error(`expected plain object, got ${to}`);
10123
- return Object.entries(to);
10124
- },
10125
- };
10126
- }
10127
- /**
10128
- * Safely converts bigint to number.
10129
- * Sometimes pointers / tags use u64 or other big numbers which cannot be represented by number,
10130
- * but we still can use them since real value will be smaller than u32
10131
- */
10132
- const numberBigint = {
10133
- encode: (from) => {
10134
- if (typeof from !== 'bigint')
10135
- throw new Error(`expected bigint, got ${typeof from}`);
10136
- if (from > BigInt(Number.MAX_SAFE_INTEGER))
10137
- throw new Error(`element bigger than MAX_SAFE_INTEGER=${from}`);
10138
- return Number(from);
10139
- },
10140
- decode: (to) => {
10141
- if (!isNum(to))
10142
- throw new Error('element is not a safe integer');
10143
- return BigInt(to);
10144
- },
10145
- };
10146
- /**
10147
- * Base coder for working with TypeScript enums.
10148
- * @param e - TypeScript enum.
10149
- * @returns base coder that encodes/decodes between numbers and enum keys.
10150
- * @example
10151
- * enum Color { Red, Green, Blue }
10152
- * const colorCoder = P.coders.tsEnum(Color);
10153
- * colorCoder.encode(Color.Red); // 'Red'
10154
- * colorCoder.decode('Green'); // 1
10155
- */
10156
- function tsEnum(e) {
10157
- if (!isPlainObject(e))
10158
- throw new Error('plain object expected');
10159
- return {
10160
- encode: (from) => {
10161
- if (!isNum(from) || !(from in e))
10162
- throw new Error(`wrong value ${from}`);
10163
- return e[from];
10164
- },
10165
- decode: (to) => {
10166
- if (typeof to !== 'string')
10167
- throw new Error(`wrong value ${typeof to}`);
10168
- return e[to];
10169
- },
10170
- };
10171
- }
10172
- /**
10173
- * Base coder for working with decimal numbers.
10174
- * @param precision - Number of decimal places.
10175
- * @param round - Round fraction part if bigger than precision (throws error by default)
10176
- * @returns base coder that encodes/decodes between bigints and decimal strings.
10177
- * @example
10178
- * const decimal8 = P.coders.decimal(8);
10179
- * decimal8.encode(630880845n); // '6.30880845'
10180
- * decimal8.decode('6.30880845'); // 630880845n
10181
- */
10182
- function decimal(precision, round = false) {
10183
- if (!isNum(precision))
10184
- throw new Error(`decimal/precision: wrong value ${precision}`);
10185
- if (typeof round !== 'boolean')
10186
- throw new Error(`decimal/round: expected boolean, got ${typeof round}`);
10187
- const decimalMask = 10n ** BigInt(precision);
10188
- return {
10189
- encode: (from) => {
10190
- if (typeof from !== 'bigint')
10191
- throw new Error(`expected bigint, got ${typeof from}`);
10192
- let s = (from < 0n ? -from : from).toString(10);
10193
- let sep = s.length - precision;
10194
- if (sep < 0) {
10195
- s = s.padStart(s.length - sep, '0');
10196
- sep = 0;
10197
- }
10198
- let i = s.length - 1;
10199
- for (; i >= sep && s[i] === '0'; i--)
10200
- ;
10201
- let int = s.slice(0, sep);
10202
- let frac = s.slice(sep, i + 1);
10203
- if (!int)
10204
- int = '0';
10205
- if (from < 0n)
10206
- int = '-' + int;
10207
- if (!frac)
10208
- return int;
10209
- return `${int}.${frac}`;
10210
- },
10211
- decode: (to) => {
10212
- if (typeof to !== 'string')
10213
- throw new Error(`expected string, got ${typeof to}`);
10214
- if (to === '-0')
10215
- throw new Error(`negative zero is not allowed`);
10216
- let neg = false;
10217
- if (to.startsWith('-')) {
10218
- neg = true;
10219
- to = to.slice(1);
10220
- }
10221
- if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(to))
10222
- throw new Error(`wrong string value=${to}`);
10223
- let sep = to.indexOf('.');
10224
- sep = sep === -1 ? to.length : sep;
10225
- // split by separator and strip trailing zeros from fraction. always returns [string, string] (.split doesn't).
10226
- const intS = to.slice(0, sep);
10227
- const fracS = to.slice(sep + 1).replace(/0+$/, '');
10228
- const int = BigInt(intS) * decimalMask;
10229
- if (!round && fracS.length > precision) {
10230
- throw new Error(`fractional part cannot be represented with this precision (num=${to}, prec=${precision})`);
10231
- }
10232
- const fracLen = Math.min(fracS.length, precision);
10233
- const frac = BigInt(fracS.slice(0, fracLen)) * 10n ** BigInt(precision - fracLen);
10234
- const value = int + frac;
10235
- return neg ? -value : value;
10236
- },
10237
- };
10238
- }
10239
- /**
10240
- * Combines multiple coders into a single coder, allowing conditional encoding/decoding based on input.
10241
- * Acts as a parser combinator, splitting complex conditional coders into smaller parts.
10242
- *
10243
- * `encode = [Ae, Be]; decode = [Ad, Bd]`
10244
- * ->
10245
- * `match([{encode: Ae, decode: Ad}, {encode: Be; decode: Bd}])`
10246
- *
10247
- * @param lst - Array of coders to match.
10248
- * @returns Combined coder for conditional encoding/decoding.
10249
- */
10250
- function match(lst) {
10251
- if (!Array.isArray(lst))
10252
- throw new Error(`expected array, got ${typeof lst}`);
10253
- for (const i of lst)
10254
- if (!isBaseCoder(i))
10255
- throw new Error(`wrong base coder ${i}`);
10256
- return {
10257
- encode: (from) => {
10258
- for (const c of lst) {
10259
- const elm = c.encode(from);
10260
- if (elm !== undefined)
10261
- return elm;
10262
- }
10263
- throw new Error(`match/encode: cannot find match in ${from}`);
10264
- },
10265
- decode: (to) => {
10266
- for (const c of lst) {
10267
- const elm = c.decode(to);
10268
- if (elm !== undefined)
10269
- return elm;
10270
- }
10271
- throw new Error(`match/decode: cannot find match in ${to}`);
10272
- },
10273
- };
10274
- }
10275
- /** Reverses direction of coder */
10276
- const reverse = (coder) => {
10277
- if (!isBaseCoder(coder))
10278
- throw new Error('BaseCoder expected');
10279
- return { encode: coder.decode, decode: coder.encode };
10280
- };
10281
- const coders = { dict, numberBigint, tsEnum, decimal, match, reverse };
10282
- /**
10283
- * CoderType for working with bigint values.
10284
- * Unsized bigint values should be wrapped in a container (e.g., bytes or string).
10285
- *
10286
- * `0n = new Uint8Array([])`
10287
- *
10288
- * `1n = new Uint8Array([1n])`
10289
- *
10290
- * Please open issue, if you need different behavior for zero.
10291
- *
10292
- * @param size - Size of the bigint in bytes.
10293
- * @param le - Whether to use little-endian byte order.
10294
- * @param signed - Whether the bigint is signed.
10295
- * @param sized - Whether the bigint should have a fixed size.
10296
- * @returns CoderType representing the bigint value.
10297
- * @example
10298
- * const U512BE = P.bigint(64, false, true, true); // Define a CoderType for a 512-bit unsigned big-endian integer
10299
- */
10300
- const bigint = (size, le = false, signed = false, sized = true) => {
10301
- if (!isNum(size))
10302
- throw new Error(`bigint/size: wrong value ${size}`);
10303
- if (typeof le !== 'boolean')
10304
- throw new Error(`bigint/le: expected boolean, got ${typeof le}`);
10305
- if (typeof signed !== 'boolean')
10306
- throw new Error(`bigint/signed: expected boolean, got ${typeof signed}`);
10307
- if (typeof sized !== 'boolean')
10308
- throw new Error(`bigint/sized: expected boolean, got ${typeof sized}`);
10309
- const bLen = BigInt(size);
10310
- const signBit = 2n ** (8n * bLen - 1n);
10311
- return wrap({
10312
- size: sized ? size : undefined,
10313
- encodeStream: (w, value) => {
10314
- if (signed && value < 0)
10315
- value = value | signBit;
10316
- const b = [];
10317
- for (let i = 0; i < size; i++) {
10318
- b.push(Number(value & 255n));
10319
- value >>= 8n;
10320
- }
10321
- let res = new Uint8Array(b).reverse();
10322
- if (!sized) {
10323
- let pos = 0;
10324
- for (pos = 0; pos < res.length; pos++)
10325
- if (res[pos] !== 0)
10326
- break;
10327
- res = res.subarray(pos); // remove leading zeros
10328
- }
10329
- w.bytes(le ? res.reverse() : res);
10330
- },
10331
- decodeStream: (r) => {
10332
- // TODO: for le we can read until first zero?
10333
- const value = r.bytes(sized ? size : Math.min(size, r.leftBytes));
10334
- const b = le ? value : swapEndianness(value);
10335
- let res = 0n;
10336
- for (let i = 0; i < b.length; i++)
10337
- res |= BigInt(b[i]) << (8n * BigInt(i));
10338
- if (signed && res & signBit)
10339
- res = (res ^ signBit) - signBit;
10340
- return res;
10341
- },
10342
- validate: (value) => {
10343
- if (typeof value !== 'bigint')
10344
- throw new Error(`bigint: invalid value: ${value}`);
10345
- checkBounds(value, 8n * bLen, !!signed);
10346
- return value;
10347
- },
10348
- });
10349
- };
10350
- /** Unsigned 256-bit big-endian integer CoderType. */
10351
- const U256BE = /* @__PURE__ */ bigint(32, false);
10352
- /** Unsigned 64-bit little-endian integer CoderType. */
10353
- const U64LE = /* @__PURE__ */ bigint(8, true);
10354
- /** Signed 64-bit little-endian integer CoderType. */
10355
- const I64LE = /* @__PURE__ */ bigint(8, true, true);
10356
- const view = (len, opts) => wrap({
10357
- size: len,
10358
- encodeStream: (w, value) => w.writeView(len, (view) => opts.write(view, value)),
10359
- decodeStream: (r) => r.readView(len, opts.read),
10360
- validate: (value) => {
10361
- if (typeof value !== 'number')
10362
- throw new Error(`viewCoder: expected number, got ${typeof value}`);
10363
- if (opts.validate)
10364
- opts.validate(value);
10365
- return value;
10366
- },
10367
- });
10368
- const intView = (len, signed, opts) => {
10369
- const bits = len * 8;
10370
- const signBit = 2 ** (bits - 1);
10371
- // Inlined checkBounds for integer
10372
- const validateSigned = (value) => {
10373
- if (!isNum(value))
10374
- throw new Error(`sintView: value is not safe integer: ${value}`);
10375
- if (value < -signBit || value >= signBit) {
10376
- throw new Error(`sintView: value out of bounds. Expected ${-signBit} <= ${value} < ${signBit}`);
10377
- }
10378
- };
10379
- const maxVal = 2 ** bits;
10380
- const validateUnsigned = (value) => {
10381
- if (!isNum(value))
10382
- throw new Error(`uintView: value is not safe integer: ${value}`);
10383
- if (0 > value || value >= maxVal) {
10384
- throw new Error(`uintView: value out of bounds. Expected 0 <= ${value} < ${maxVal}`);
10385
- }
10386
- };
10387
- return view(len, {
10388
- write: opts.write,
10389
- read: opts.read,
10390
- validate: signed ? validateSigned : validateUnsigned,
10391
- });
10392
- };
10393
- /** Unsigned 32-bit little-endian integer CoderType. */
10394
- const U32LE = /* @__PURE__ */ intView(4, false, {
10395
- read: (view, pos) => view.getUint32(pos, true),
10396
- write: (view, value) => view.setUint32(0, value, true),
10397
- });
10398
- /** Unsigned 32-bit big-endian integer CoderType. */
10399
- const U32BE = /* @__PURE__ */ intView(4, false, {
10400
- read: (view, pos) => view.getUint32(pos, false),
10401
- write: (view, value) => view.setUint32(0, value, false),
10402
- });
10403
- /** Signed 32-bit little-endian integer CoderType. */
10404
- const I32LE = /* @__PURE__ */ intView(4, true, {
10405
- read: (view, pos) => view.getInt32(pos, true),
10406
- write: (view, value) => view.setInt32(0, value, true),
10407
- });
10408
- /** Unsigned 16-bit little-endian integer CoderType. */
10409
- const U16LE = /* @__PURE__ */ intView(2, false, {
10410
- read: (view, pos) => view.getUint16(pos, true),
10411
- write: (view, value) => view.setUint16(0, value, true),
10412
- });
10413
- /** Unsigned 8-bit integer CoderType. */
10414
- const U8 = /* @__PURE__ */ intView(1, false, {
10415
- read: (view, pos) => view.getUint8(pos),
10416
- write: (view, value) => view.setUint8(0, value),
10417
- });
10418
- /**
10419
- * Bytes CoderType with a specified length and endianness.
10420
- * The bytes can have:
10421
- * - Dynamic size (prefixed with a length CoderType like U16BE)
10422
- * - Fixed size (specified by a number)
10423
- * - Unknown size (null, will parse until end of buffer)
10424
- * - Zero-terminated (terminator can be any Uint8Array)
10425
- * @param len - CoderType, number, Uint8Array (terminator) or null
10426
- * @param le - Whether to use little-endian byte order.
10427
- * @returns CoderType representing the bytes.
10428
- * @example
10429
- * // Dynamic size bytes (prefixed with P.U16BE number of bytes length)
10430
- * const dynamicBytes = P.bytes(P.U16BE, false);
10431
- * const fixedBytes = P.bytes(32, false); // Fixed size bytes
10432
- * const unknownBytes = P.bytes(null, false); // Unknown size bytes, will parse until end of buffer
10433
- * const zeroTerminatedBytes = P.bytes(new Uint8Array([0]), false); // Zero-terminated bytes
10434
- */
10435
- const createBytes = (len, le = false) => {
10436
- if (typeof le !== 'boolean')
10437
- throw new Error(`bytes/le: expected boolean, got ${typeof le}`);
10438
- const _length = lengthCoder(len);
10439
- const _isb = isBytes$1(len);
10440
- return wrap({
10441
- size: typeof len === 'number' ? len : undefined,
10442
- encodeStream: (w, value) => {
10443
- if (!_isb)
10444
- _length.encodeStream(w, value.length);
10445
- w.bytes(le ? swapEndianness(value) : value);
10446
- if (_isb)
10447
- w.bytes(len);
10448
- },
10449
- decodeStream: (r) => {
10450
- let bytes;
10451
- if (_isb) {
10452
- const tPos = r.find(len);
10453
- if (!tPos)
10454
- throw r.err(`bytes: cannot find terminator`);
10455
- bytes = r.bytes(tPos - r.pos);
10456
- r.bytes(len.length);
10457
- }
10458
- else {
10459
- bytes = r.bytes(len === null ? r.leftBytes : _length.decodeStream(r));
10460
- }
10461
- return le ? swapEndianness(bytes) : bytes;
10462
- },
10463
- validate: (value) => {
10464
- if (!isBytes$1(value))
10465
- throw new Error(`bytes: invalid value ${value}`);
10466
- return value;
10467
- },
10468
- });
10469
- };
10470
- /**
10471
- * Prefix-encoded value using a length prefix and an inner CoderType.
10472
- * The prefix can have:
10473
- * - Dynamic size (prefixed with a length CoderType like U16BE)
10474
- * - Fixed size (specified by a number)
10475
- * - Unknown size (null, will parse until end of buffer)
10476
- * - Zero-terminated (terminator can be any Uint8Array)
10477
- * @param len - Length CoderType (dynamic size), number (fixed size), Uint8Array (for terminator), or null (will parse until end of buffer)
10478
- * @param inner - CoderType for the actual value to be prefix-encoded.
10479
- * @returns CoderType representing the prefix-encoded value.
10480
- * @example
10481
- * const dynamicPrefix = P.prefix(P.U16BE, P.bytes(null)); // Dynamic size prefix (prefixed with P.U16BE number of bytes length)
10482
- * const fixedPrefix = P.prefix(10, P.bytes(null)); // Fixed size prefix (always 10 bytes)
10483
- */
10484
- function prefix(len, inner) {
10485
- if (!isCoder(inner))
10486
- throw new Error(`prefix: invalid inner value ${inner}`);
10487
- return apply(createBytes(len), reverse(inner));
10488
- }
10489
- /**
10490
- * String CoderType with a specified length and endianness.
10491
- * The string can be:
10492
- * - Dynamic size (prefixed with a length CoderType like U16BE)
10493
- * - Fixed size (specified by a number)
10494
- * - Unknown size (null, will parse until end of buffer)
10495
- * - Zero-terminated (terminator can be any Uint8Array)
10496
- * @param len - Length CoderType (dynamic size), number (fixed size), Uint8Array (for terminator), or null (will parse until end of buffer)
10497
- * @param le - Whether to use little-endian byte order.
10498
- * @returns CoderType representing the string.
10499
- * @example
10500
- * const dynamicString = P.string(P.U16BE, false); // Dynamic size string (prefixed with P.U16BE number of string length)
10501
- * const fixedString = P.string(10, false); // Fixed size string
10502
- * const unknownString = P.string(null, false); // Unknown size string, will parse until end of buffer
10503
- * const nullTerminatedString = P.cstring; // NUL-terminated string
10504
- * const _cstring = P.string(new Uint8Array([0])); // Same thing
10505
- */
10506
- const string = (len, le = false) => validate(apply(createBytes(len, le), utf8), (value) => {
10507
- // TextEncoder/TextDecoder will fail on non-string, but we create more readable errors earlier
10508
- if (typeof value !== 'string')
10509
- throw new Error(`expected string, got ${typeof value}`);
10510
- return value;
10511
- });
10512
- /**
10513
- * Hexadecimal string CoderType with a specified length, endianness, and optional 0x prefix.
10514
- * @param len - Length CoderType (dynamic size), number (fixed size), Uint8Array (for terminator), or null (will parse until end of buffer)
10515
- * @param le - Whether to use little-endian byte order.
10516
- * @param withZero - Whether to include the 0x prefix.
10517
- * @returns CoderType representing the hexadecimal string.
10518
- * @example
10519
- * const dynamicHex = P.hex(P.U16BE, {isLE: false, with0x: true}); // Hex string with 0x prefix and U16BE length
10520
- * const fixedHex = P.hex(32, {isLE: false, with0x: false}); // Fixed-length 32-byte hex string without 0x prefix
10521
- */
10522
- const createHex = (len, options = { isLE: false, with0x: false }) => {
10523
- let inner = apply(createBytes(len, options.isLE), hex);
10524
- const prefix = options.with0x;
10525
- if (typeof prefix !== 'boolean')
10526
- throw new Error(`hex/with0x: expected boolean, got ${typeof prefix}`);
10527
- if (prefix) {
10528
- inner = apply(inner, {
10529
- encode: (value) => `0x${value}`,
10530
- decode: (value) => {
10531
- if (!value.startsWith('0x'))
10532
- throw new Error('hex(with0x=true).encode input should start with 0x');
10533
- return value.slice(2);
10534
- },
10535
- });
10536
- }
10537
- return inner;
10538
- };
10539
- /**
10540
- * Applies a base coder to a CoderType.
10541
- * @param inner - The inner CoderType.
10542
- * @param b - The base coder to apply.
10543
- * @returns CoderType representing the transformed value.
10544
- * @example
10545
- * import { hex } from '@scure/base';
10546
- * const hex = P.apply(P.bytes(32), hex); // will decode bytes into a hex string
10547
- */
10548
- function apply(inner, base) {
10549
- if (!isCoder(inner))
10550
- throw new Error(`apply: invalid inner value ${inner}`);
10551
- if (!isBaseCoder(base))
10552
- throw new Error(`apply: invalid base value ${inner}`);
10553
- return wrap({
10554
- size: inner.size,
10555
- encodeStream: (w, value) => {
10556
- let innerValue;
10557
- try {
10558
- innerValue = base.decode(value);
10559
- }
10560
- catch (e) {
10561
- throw w.err('' + e);
10562
- }
10563
- return inner.encodeStream(w, innerValue);
10564
- },
10565
- decodeStream: (r) => {
10566
- const innerValue = inner.decodeStream(r);
10567
- try {
10568
- return base.encode(innerValue);
10569
- }
10570
- catch (e) {
10571
- throw r.err('' + e);
10572
- }
10573
- },
10574
- });
10575
- }
10576
- /**
10577
- * Flag CoderType that encodes/decodes a boolean value based on the presence of a marker.
10578
- * @param flagValue - Marker value.
10579
- * @param xor - Whether to invert the flag behavior.
10580
- * @returns CoderType representing the flag value.
10581
- * @example
10582
- * const flag = P.flag(new Uint8Array([0x01, 0x02])); // Encodes true as u8a([0x01, 0x02]), false as u8a([])
10583
- * const flagXor = P.flag(new Uint8Array([0x01, 0x02]), true); // Encodes true as u8a([]), false as u8a([0x01, 0x02])
10584
- * // Conditional encoding with flagged
10585
- * const s = P.struct({ f: P.flag(new Uint8Array([0x0, 0x1])), f2: P.flagged('f', P.U32BE) });
10586
- */
10587
- const flag = (flagValue, xor = false) => {
10588
- if (!isBytes$1(flagValue))
10589
- throw new Error(`flag/flagValue: expected Uint8Array, got ${typeof flagValue}`);
10590
- if (typeof xor !== 'boolean')
10591
- throw new Error(`flag/xor: expected boolean, got ${typeof xor}`);
10592
- return wrap({
10593
- size: flagValue.length,
10594
- encodeStream: (w, value) => {
10595
- if (!!value !== xor)
10596
- w.bytes(flagValue);
10597
- },
10598
- decodeStream: (r) => {
10599
- let hasFlag = r.leftBytes >= flagValue.length;
10600
- if (hasFlag) {
10601
- hasFlag = equalBytes$1(r.bytes(flagValue.length, true), flagValue);
10602
- // Found flag, advance cursor position
10603
- if (hasFlag)
10604
- r.bytes(flagValue.length);
10605
- }
10606
- return hasFlag !== xor; // hasFlag ^ xor
10607
- },
10608
- validate: (value) => {
10609
- if (value !== undefined && typeof value !== 'boolean')
10610
- throw new Error(`flag: expected boolean value or undefined, got ${typeof value}`);
10611
- return value;
10612
- },
10613
- });
10614
- };
10615
- /**
10616
- * Conditional CoderType that encodes/decodes a value only if a flag is present.
10617
- * @param path - Path to the flag value or a CoderType for the flag.
10618
- * @param inner - Inner CoderType for the value.
10619
- * @param def - Optional default value to use if the flag is not present.
10620
- * @returns CoderType representing the conditional value.
10621
- * @example
10622
- * const s = P.struct({
10623
- * f: P.flag(new Uint8Array([0x0, 0x1])),
10624
- * f2: P.flagged('f', P.U32BE)
10625
- * });
10626
- *
10627
- * @example
10628
- * const s2 = P.struct({
10629
- * f: P.flag(new Uint8Array([0x0, 0x1])),
10630
- * f2: P.flagged('f', P.U32BE, 123)
10631
- * });
10632
- */
10633
- function flagged(path, inner, def) {
10634
- if (!isCoder(inner))
10635
- throw new Error(`flagged: invalid inner value ${inner}`);
10636
- return wrap({
10637
- encodeStream: (w, value) => {
10638
- {
10639
- if (Path.resolve(w.stack, path))
10640
- inner.encodeStream(w, value);
10641
- }
10642
- },
10643
- decodeStream: (r) => {
10644
- let hasFlag = false;
10645
- hasFlag = !!Path.resolve(r.stack, path);
10646
- // If there is a flag -- decode and return value
10647
- if (hasFlag)
10648
- return inner.decodeStream(r);
10649
- return;
10650
- },
10651
- });
10652
- }
10653
- /**
10654
- * Magic value CoderType that encodes/decodes a constant value.
10655
- * This can be used to check for a specific magic value or sequence of bytes at the beginning of a data structure.
10656
- * @param inner - Inner CoderType for the value.
10657
- * @param constant - Constant value.
10658
- * @param check - Whether to check the decoded value against the constant.
10659
- * @returns CoderType representing the magic value.
10660
- * @example
10661
- * // Always encodes constant as bytes using inner CoderType, throws if encoded value is not present
10662
- * const magicU8 = P.magic(P.U8, 0x42);
10663
- */
10664
- function magic(inner, constant, check = true) {
10665
- if (!isCoder(inner))
10666
- throw new Error(`magic: invalid inner value ${inner}`);
10667
- if (typeof check !== 'boolean')
10668
- throw new Error(`magic: expected boolean, got ${typeof check}`);
10669
- return wrap({
10670
- size: inner.size,
10671
- encodeStream: (w, _value) => inner.encodeStream(w, constant),
10672
- decodeStream: (r) => {
10673
- const value = inner.decodeStream(r);
10674
- if ((check && typeof value !== 'object' && value !== constant) ||
10675
- (isBytes$1(constant) && !equalBytes$1(constant, value))) {
10676
- throw r.err(`magic: invalid value: ${value} !== ${constant}`);
10677
- }
10678
- return;
10679
- },
10680
- validate: (value) => {
10681
- if (value !== undefined)
10682
- throw new Error(`magic: wrong value=${typeof value}`);
10683
- return value;
10684
- },
10685
- });
10686
- }
10687
- function sizeof(fields) {
10688
- let size = 0;
10689
- for (const f of fields) {
10690
- if (f.size === undefined)
10691
- return;
10692
- if (!isNum(f.size))
10693
- throw new Error(`sizeof: wrong element size=${size}`);
10694
- size += f.size;
10695
- }
10696
- return size;
10697
- }
10698
- /**
10699
- * Structure of composable primitives (C/Rust struct)
10700
- * @param fields - Object mapping field names to CoderTypes.
10701
- * @returns CoderType representing the structure.
10702
- * @example
10703
- * // Define a structure with a 32-bit big-endian unsigned integer, a string, and a nested structure
10704
- * const myStruct = P.struct({
10705
- * id: P.U32BE,
10706
- * name: P.string(P.U8),
10707
- * nested: P.struct({
10708
- * flag: P.bool,
10709
- * value: P.I16LE
10710
- * })
10711
- * });
10712
- */
10713
- function struct(fields) {
10714
- if (!isPlainObject(fields))
10715
- throw new Error(`struct: expected plain object, got ${fields}`);
10716
- for (const name in fields) {
10717
- if (!isCoder(fields[name]))
10718
- throw new Error(`struct: field ${name} is not CoderType`);
10719
- }
10720
- return wrap({
10721
- size: sizeof(Object.values(fields)),
10722
- encodeStream: (w, value) => {
10723
- w.pushObj(value, (fieldFn) => {
10724
- for (const name in fields)
10725
- fieldFn(name, () => fields[name].encodeStream(w, value[name]));
10726
- });
10727
- },
10728
- decodeStream: (r) => {
10729
- const res = {};
10730
- r.pushObj(res, (fieldFn) => {
10731
- for (const name in fields)
10732
- fieldFn(name, () => (res[name] = fields[name].decodeStream(r)));
10733
- });
10734
- return res;
10735
- },
10736
- validate: (value) => {
10737
- if (typeof value !== 'object' || value === null)
10738
- throw new Error(`struct: invalid value ${value}`);
10739
- return value;
10740
- },
10741
- });
10742
- }
10743
- /**
10744
- * Tuple (unnamed structure) of CoderTypes. Same as struct but with unnamed fields.
10745
- * @param fields - Array of CoderTypes.
10746
- * @returns CoderType representing the tuple.
10747
- * @example
10748
- * const myTuple = P.tuple([P.U8, P.U16LE, P.string(P.U8)]);
10749
- */
10750
- function tuple(fields) {
10751
- if (!Array.isArray(fields))
10752
- throw new Error(`Packed.Tuple: got ${typeof fields} instead of array`);
10753
- for (let i = 0; i < fields.length; i++) {
10754
- if (!isCoder(fields[i]))
10755
- throw new Error(`tuple: field ${i} is not CoderType`);
10756
- }
10757
- return wrap({
10758
- size: sizeof(fields),
10759
- encodeStream: (w, value) => {
10760
- // TODO: fix types
10761
- if (!Array.isArray(value))
10762
- throw w.err(`tuple: invalid value ${value}`);
10763
- w.pushObj(value, (fieldFn) => {
10764
- for (let i = 0; i < fields.length; i++)
10765
- fieldFn(`${i}`, () => fields[i].encodeStream(w, value[i]));
10766
- });
10767
- },
10768
- decodeStream: (r) => {
10769
- const res = [];
10770
- r.pushObj(res, (fieldFn) => {
10771
- for (let i = 0; i < fields.length; i++)
10772
- fieldFn(`${i}`, () => res.push(fields[i].decodeStream(r)));
10773
- });
10774
- return res;
10775
- },
10776
- validate: (value) => {
10777
- if (!Array.isArray(value))
10778
- throw new Error(`tuple: invalid value ${value}`);
10779
- if (value.length !== fields.length)
10780
- throw new Error(`tuple: wrong length=${value.length}, expected ${fields.length}`);
10781
- return value;
10782
- },
10783
- });
10784
- }
10785
- /**
10786
- * Array of items (inner type) with a specified length.
10787
- * @param len - Length CoderType (dynamic size), number (fixed size), Uint8Array (for terminator), or null (will parse until end of buffer)
10788
- * @param inner - CoderType for encoding/decoding each array item.
10789
- * @returns CoderType representing the array.
10790
- * @example
10791
- * const a1 = P.array(P.U16BE, child); // Dynamic size array (prefixed with P.U16BE number of array length)
10792
- * const a2 = P.array(4, child); // Fixed size array
10793
- * const a3 = P.array(null, child); // Unknown size array, will parse until end of buffer
10794
- * const a4 = P.array(new Uint8Array([0]), child); // zero-terminated array (NOTE: terminator can be any buffer)
10795
- */
10796
- function array(len, inner) {
10797
- if (!isCoder(inner))
10798
- throw new Error(`array: invalid inner value ${inner}`);
10799
- // By construction length is inside array (otherwise there will be various incorrect stack states)
10800
- // But forcing users always write '..' seems like bad idea. Also, breaking change.
10801
- const _length = lengthCoder(typeof len === 'string' ? `../${len}` : len);
10802
- return wrap({
10803
- size: typeof len === 'number' && inner.size ? len * inner.size : undefined,
10804
- encodeStream: (w, value) => {
10805
- const _w = w;
10806
- _w.pushObj(value, (fieldFn) => {
10807
- if (!isBytes$1(len))
10808
- _length.encodeStream(w, value.length);
10809
- for (let i = 0; i < value.length; i++) {
10810
- fieldFn(`${i}`, () => {
10811
- const elm = value[i];
10812
- const startPos = w.pos;
10813
- inner.encodeStream(w, elm);
10814
- if (isBytes$1(len)) {
10815
- // Terminator is bigger than elm size, so skip
10816
- if (len.length > _w.pos - startPos)
10817
- return;
10818
- const data = _w.finish(false).subarray(startPos, _w.pos);
10819
- // There is still possible case when multiple elements create terminator,
10820
- // but it is hard to catch here, will be very slow
10821
- if (equalBytes$1(data.subarray(0, len.length), len))
10822
- throw _w.err(`array: inner element encoding same as separator. elm=${elm} data=${data}`);
10823
- }
10824
- });
10825
- }
10826
- });
10827
- if (isBytes$1(len))
10828
- w.bytes(len);
10829
- },
10830
- decodeStream: (r) => {
10831
- const res = [];
10832
- r.pushObj(res, (fieldFn) => {
10833
- if (len === null) {
10834
- for (let i = 0; !r.isEnd(); i++) {
10835
- fieldFn(`${i}`, () => res.push(inner.decodeStream(r)));
10836
- if (inner.size && r.leftBytes < inner.size)
10837
- break;
10838
- }
10839
- }
10840
- else if (isBytes$1(len)) {
10841
- for (let i = 0;; i++) {
10842
- if (equalBytes$1(r.bytes(len.length, true), len)) {
10843
- // Advance cursor position if terminator found
10844
- r.bytes(len.length);
10845
- break;
10846
- }
10847
- fieldFn(`${i}`, () => res.push(inner.decodeStream(r)));
10848
- }
10849
- }
10850
- else {
10851
- let length;
10852
- fieldFn('arrayLen', () => (length = _length.decodeStream(r)));
10853
- for (let i = 0; i < length; i++)
10854
- fieldFn(`${i}`, () => res.push(inner.decodeStream(r)));
10855
- }
10856
- });
10857
- return res;
10858
- },
10859
- validate: (value) => {
10860
- if (!Array.isArray(value))
10861
- throw new Error(`array: invalid value ${value}`);
10862
- return value;
10863
- },
10864
- });
10865
- }
10866
-
10867
- const Point = secp256k1.ProjectivePoint;
10868
- const CURVE_ORDER = secp256k1.CURVE.n;
10869
- const isBytes = utils.isBytes;
10870
- const concatBytes = utils.concatBytes;
10871
- const equalBytes = utils.equalBytes;
10872
- const hash160 = (msg) => ripemd160(sha256$1(msg));
10873
- const sha256x2 = (...msgs) => sha256$1(sha256$1(concatBytes(...msgs)));
10874
- const pubSchnorr = schnorr.getPublicKey;
10875
- const pubECDSA = secp256k1.getPublicKey;
10876
- // low-r signature grinding. Used to reduce tx size by 1 byte.
10877
- // noble/secp256k1 does not support the feature: it is not used outside of BTC.
10878
- // We implement it manually, because in BTC it's common.
10879
- // Not best way, but closest to bitcoin implementation (easier to check)
10880
- const hasLowR = (sig) => sig.r < CURVE_ORDER / 2n;
10881
- function signECDSA(hash, privateKey, lowR = false) {
10882
- let sig = secp256k1.sign(hash, privateKey);
10883
- if (lowR && !hasLowR(sig)) {
10884
- const extraEntropy = new Uint8Array(32);
10885
- let counter = 0;
10886
- while (!hasLowR(sig)) {
10887
- extraEntropy.set(U32LE.encode(counter++));
10888
- sig = secp256k1.sign(hash, privateKey, { extraEntropy });
10889
- if (counter > 4294967295)
10890
- throw new Error('lowR counter overflow: report the error');
10891
- }
10892
- }
10893
- return sig.toDERRawBytes();
10894
- }
10895
- const signSchnorr = schnorr.sign;
10896
- const tagSchnorr = schnorr.utils.taggedHash;
10897
- var PubT;
10898
- (function (PubT) {
10899
- PubT[PubT["ecdsa"] = 0] = "ecdsa";
10900
- PubT[PubT["schnorr"] = 1] = "schnorr";
10901
- })(PubT || (PubT = {}));
10902
- function validatePubkey(pub, type) {
10903
- const len = pub.length;
10904
- if (type === PubT.ecdsa) {
10905
- if (len === 32)
10906
- throw new Error('Expected non-Schnorr key');
10907
- Point.fromHex(pub); // does assertValidity
10908
- return pub;
10909
- }
10910
- else if (type === PubT.schnorr) {
10911
- if (len !== 32)
10912
- throw new Error('Expected 32-byte Schnorr key');
10913
- schnorr.utils.lift_x(schnorr.utils.bytesToNumberBE(pub));
10914
- return pub;
10915
- }
10916
- else {
10917
- throw new Error('Unknown key type');
10918
- }
10919
- }
10920
- function tapTweak(a, b) {
10921
- const u = schnorr.utils;
10922
- const t = u.taggedHash('TapTweak', a, b);
10923
- const tn = u.bytesToNumberBE(t);
10924
- if (tn >= CURVE_ORDER)
10925
- throw new Error('tweak higher than curve order');
10926
- return tn;
10927
- }
10928
- function taprootTweakPrivKey(privKey, merkleRoot = Uint8Array.of()) {
10929
- const u = schnorr.utils;
10930
- const seckey0 = u.bytesToNumberBE(privKey); // seckey0 = int_from_bytes(seckey0)
10931
- const P = Point.fromPrivateKey(seckey0); // P = point_mul(G, seckey0)
10932
- // seckey = seckey0 if has_even_y(P) else SECP256K1_ORDER - seckey0
10933
- const seckey = P.hasEvenY() ? seckey0 : u.mod(-seckey0, CURVE_ORDER);
10934
- const xP = u.pointToBytes(P);
10935
- // t = int_from_bytes(tagged_hash("TapTweak", bytes_from_int(x(P)) + h)); >= SECP256K1_ORDER check
10936
- const t = tapTweak(xP, merkleRoot);
10937
- // bytes_from_int((seckey + t) % SECP256K1_ORDER)
10938
- return u.numberToBytesBE(u.mod(seckey + t, CURVE_ORDER), 32);
10939
- }
10940
- function taprootTweakPubkey(pubKey, h) {
10941
- const u = schnorr.utils;
10942
- const t = tapTweak(pubKey, h); // t = int_from_bytes(tagged_hash("TapTweak", pubkey + h))
10943
- const P = u.lift_x(u.bytesToNumberBE(pubKey)); // P = lift_x(int_from_bytes(pubkey))
10944
- const Q = P.add(Point.fromPrivateKey(t)); // Q = point_add(P, point_mul(G, t))
10945
- const parity = Q.hasEvenY() ? 0 : 1; // 0 if has_even_y(Q) else 1
10946
- return [u.pointToBytes(Q), parity]; // bytes_from_int(x(Q))
10947
- }
10948
- // Another stupid decision, where lack of standard affects security.
10949
- // Multisig needs to be generated with some key.
10950
- // We are using approach from BIP 341/bitcoinjs-lib: SHA256(uncompressedDER(SECP256K1_GENERATOR_POINT))
10951
- // It is possible to switch SECP256K1_GENERATOR_POINT with some random point;
10952
- // but it's too complex to prove.
10953
- // Also used by bitcoin-core and bitcoinjs-lib
10954
- sha256$1(Point.BASE.toRawBytes(false));
10955
- const NETWORK = {
10956
- bech32: 'bc',
10957
- pubKeyHash: 0x00,
10958
- scriptHash: 0x05,
10959
- wif: 0x80,
10960
- };
10961
- // Exported for tests, internal method
10962
- function compareBytes(a, b) {
10963
- if (!isBytes(a) || !isBytes(b))
10964
- throw new Error(`cmp: wrong type a=${typeof a} b=${typeof b}`);
10965
- // -1 -> a<b, 0 -> a==b, 1 -> a>b
10966
- const len = Math.min(a.length, b.length);
10967
- for (let i = 0; i < len; i++)
10968
- if (a[i] != b[i])
10969
- return Math.sign(a[i] - b[i]);
10970
- return Math.sign(a.length - b.length);
10971
- }
10972
-
10973
- // prettier-ignore
10974
- var OP;
10975
- (function (OP) {
10976
- OP[OP["OP_0"] = 0] = "OP_0";
10977
- OP[OP["PUSHDATA1"] = 76] = "PUSHDATA1";
10978
- OP[OP["PUSHDATA2"] = 77] = "PUSHDATA2";
10979
- OP[OP["PUSHDATA4"] = 78] = "PUSHDATA4";
10980
- OP[OP["1NEGATE"] = 79] = "1NEGATE";
10981
- OP[OP["RESERVED"] = 80] = "RESERVED";
10982
- OP[OP["OP_1"] = 81] = "OP_1";
10983
- OP[OP["OP_2"] = 82] = "OP_2";
10984
- OP[OP["OP_3"] = 83] = "OP_3";
10985
- OP[OP["OP_4"] = 84] = "OP_4";
10986
- OP[OP["OP_5"] = 85] = "OP_5";
10987
- OP[OP["OP_6"] = 86] = "OP_6";
10988
- OP[OP["OP_7"] = 87] = "OP_7";
10989
- OP[OP["OP_8"] = 88] = "OP_8";
10990
- OP[OP["OP_9"] = 89] = "OP_9";
10991
- OP[OP["OP_10"] = 90] = "OP_10";
10992
- OP[OP["OP_11"] = 91] = "OP_11";
10993
- OP[OP["OP_12"] = 92] = "OP_12";
10994
- OP[OP["OP_13"] = 93] = "OP_13";
10995
- OP[OP["OP_14"] = 94] = "OP_14";
10996
- OP[OP["OP_15"] = 95] = "OP_15";
10997
- OP[OP["OP_16"] = 96] = "OP_16";
10998
- // Control
10999
- OP[OP["NOP"] = 97] = "NOP";
11000
- OP[OP["VER"] = 98] = "VER";
11001
- OP[OP["IF"] = 99] = "IF";
11002
- OP[OP["NOTIF"] = 100] = "NOTIF";
11003
- OP[OP["VERIF"] = 101] = "VERIF";
11004
- OP[OP["VERNOTIF"] = 102] = "VERNOTIF";
11005
- OP[OP["ELSE"] = 103] = "ELSE";
11006
- OP[OP["ENDIF"] = 104] = "ENDIF";
11007
- OP[OP["VERIFY"] = 105] = "VERIFY";
11008
- OP[OP["RETURN"] = 106] = "RETURN";
11009
- // Stack
11010
- OP[OP["TOALTSTACK"] = 107] = "TOALTSTACK";
11011
- OP[OP["FROMALTSTACK"] = 108] = "FROMALTSTACK";
11012
- OP[OP["2DROP"] = 109] = "2DROP";
11013
- OP[OP["2DUP"] = 110] = "2DUP";
11014
- OP[OP["3DUP"] = 111] = "3DUP";
11015
- OP[OP["2OVER"] = 112] = "2OVER";
11016
- OP[OP["2ROT"] = 113] = "2ROT";
11017
- OP[OP["2SWAP"] = 114] = "2SWAP";
11018
- OP[OP["IFDUP"] = 115] = "IFDUP";
11019
- OP[OP["DEPTH"] = 116] = "DEPTH";
11020
- OP[OP["DROP"] = 117] = "DROP";
11021
- OP[OP["DUP"] = 118] = "DUP";
11022
- OP[OP["NIP"] = 119] = "NIP";
11023
- OP[OP["OVER"] = 120] = "OVER";
11024
- OP[OP["PICK"] = 121] = "PICK";
11025
- OP[OP["ROLL"] = 122] = "ROLL";
11026
- OP[OP["ROT"] = 123] = "ROT";
11027
- OP[OP["SWAP"] = 124] = "SWAP";
11028
- OP[OP["TUCK"] = 125] = "TUCK";
11029
- // Splice
11030
- OP[OP["CAT"] = 126] = "CAT";
11031
- OP[OP["SUBSTR"] = 127] = "SUBSTR";
11032
- OP[OP["LEFT"] = 128] = "LEFT";
11033
- OP[OP["RIGHT"] = 129] = "RIGHT";
11034
- OP[OP["SIZE"] = 130] = "SIZE";
11035
- // Boolean logic
11036
- OP[OP["INVERT"] = 131] = "INVERT";
11037
- OP[OP["AND"] = 132] = "AND";
11038
- OP[OP["OR"] = 133] = "OR";
11039
- OP[OP["XOR"] = 134] = "XOR";
11040
- OP[OP["EQUAL"] = 135] = "EQUAL";
11041
- OP[OP["EQUALVERIFY"] = 136] = "EQUALVERIFY";
11042
- OP[OP["RESERVED1"] = 137] = "RESERVED1";
11043
- OP[OP["RESERVED2"] = 138] = "RESERVED2";
11044
- // Numbers
11045
- OP[OP["1ADD"] = 139] = "1ADD";
11046
- OP[OP["1SUB"] = 140] = "1SUB";
11047
- OP[OP["2MUL"] = 141] = "2MUL";
11048
- OP[OP["2DIV"] = 142] = "2DIV";
11049
- OP[OP["NEGATE"] = 143] = "NEGATE";
11050
- OP[OP["ABS"] = 144] = "ABS";
11051
- OP[OP["NOT"] = 145] = "NOT";
11052
- OP[OP["0NOTEQUAL"] = 146] = "0NOTEQUAL";
11053
- OP[OP["ADD"] = 147] = "ADD";
11054
- OP[OP["SUB"] = 148] = "SUB";
11055
- OP[OP["MUL"] = 149] = "MUL";
11056
- OP[OP["DIV"] = 150] = "DIV";
11057
- OP[OP["MOD"] = 151] = "MOD";
11058
- OP[OP["LSHIFT"] = 152] = "LSHIFT";
11059
- OP[OP["RSHIFT"] = 153] = "RSHIFT";
11060
- OP[OP["BOOLAND"] = 154] = "BOOLAND";
11061
- OP[OP["BOOLOR"] = 155] = "BOOLOR";
11062
- OP[OP["NUMEQUAL"] = 156] = "NUMEQUAL";
11063
- OP[OP["NUMEQUALVERIFY"] = 157] = "NUMEQUALVERIFY";
11064
- OP[OP["NUMNOTEQUAL"] = 158] = "NUMNOTEQUAL";
11065
- OP[OP["LESSTHAN"] = 159] = "LESSTHAN";
11066
- OP[OP["GREATERTHAN"] = 160] = "GREATERTHAN";
11067
- OP[OP["LESSTHANOREQUAL"] = 161] = "LESSTHANOREQUAL";
11068
- OP[OP["GREATERTHANOREQUAL"] = 162] = "GREATERTHANOREQUAL";
11069
- OP[OP["MIN"] = 163] = "MIN";
11070
- OP[OP["MAX"] = 164] = "MAX";
11071
- OP[OP["WITHIN"] = 165] = "WITHIN";
11072
- // Crypto
11073
- OP[OP["RIPEMD160"] = 166] = "RIPEMD160";
11074
- OP[OP["SHA1"] = 167] = "SHA1";
11075
- OP[OP["SHA256"] = 168] = "SHA256";
11076
- OP[OP["HASH160"] = 169] = "HASH160";
11077
- OP[OP["HASH256"] = 170] = "HASH256";
11078
- OP[OP["CODESEPARATOR"] = 171] = "CODESEPARATOR";
11079
- OP[OP["CHECKSIG"] = 172] = "CHECKSIG";
11080
- OP[OP["CHECKSIGVERIFY"] = 173] = "CHECKSIGVERIFY";
11081
- OP[OP["CHECKMULTISIG"] = 174] = "CHECKMULTISIG";
11082
- OP[OP["CHECKMULTISIGVERIFY"] = 175] = "CHECKMULTISIGVERIFY";
11083
- // Expansion
11084
- OP[OP["NOP1"] = 176] = "NOP1";
11085
- OP[OP["CHECKLOCKTIMEVERIFY"] = 177] = "CHECKLOCKTIMEVERIFY";
11086
- OP[OP["CHECKSEQUENCEVERIFY"] = 178] = "CHECKSEQUENCEVERIFY";
11087
- OP[OP["NOP4"] = 179] = "NOP4";
11088
- OP[OP["NOP5"] = 180] = "NOP5";
11089
- OP[OP["NOP6"] = 181] = "NOP6";
11090
- OP[OP["NOP7"] = 182] = "NOP7";
11091
- OP[OP["NOP8"] = 183] = "NOP8";
11092
- OP[OP["NOP9"] = 184] = "NOP9";
11093
- OP[OP["NOP10"] = 185] = "NOP10";
11094
- // BIP 342
11095
- OP[OP["CHECKSIGADD"] = 186] = "CHECKSIGADD";
11096
- // Invalid
11097
- OP[OP["INVALID"] = 255] = "INVALID";
11098
- })(OP || (OP = {}));
11099
- // We can encode almost any number as ScriptNum, however, parsing will be a problem
11100
- // since we can't know if buffer is a number or something else.
11101
- function ScriptNum(bytesLimit = 6, forceMinimal = false) {
11102
- return wrap({
11103
- encodeStream: (w, value) => {
11104
- if (value === 0n)
11105
- return;
11106
- const neg = value < 0;
11107
- const val = BigInt(value);
11108
- const nums = [];
11109
- for (let abs = neg ? -val : val; abs; abs >>= 8n)
11110
- nums.push(Number(abs & 0xffn));
11111
- if (nums[nums.length - 1] >= 0x80)
11112
- nums.push(neg ? 0x80 : 0);
11113
- else if (neg)
11114
- nums[nums.length - 1] |= 0x80;
11115
- w.bytes(new Uint8Array(nums));
11116
- },
11117
- decodeStream: (r) => {
11118
- const len = r.leftBytes;
11119
- if (len > bytesLimit)
11120
- throw new Error(`ScriptNum: number (${len}) bigger than limit=${bytesLimit}`);
11121
- if (len === 0)
11122
- return 0n;
11123
- if (forceMinimal) {
11124
- const data = r.bytes(len, true);
11125
- // MSB is zero (without sign bit) -> not minimally encoded
11126
- if ((data[data.length - 1] & 0x7f) === 0) {
11127
- // exception
11128
- if (len <= 1 || (data[data.length - 2] & 0x80) === 0)
11129
- throw new Error('Non-minimally encoded ScriptNum');
11130
- }
11131
- }
11132
- let last = 0;
11133
- let res = 0n;
11134
- for (let i = 0; i < len; ++i) {
11135
- last = r.byte();
11136
- res |= BigInt(last) << (8n * BigInt(i));
11137
- }
11138
- if (last >= 0x80) {
11139
- res &= (2n ** BigInt(len * 8) - 1n) >> 1n;
11140
- res = -res;
11141
- }
11142
- return res;
11143
- },
11144
- });
11145
- }
11146
- function OpToNum(op, bytesLimit = 4, forceMinimal = true) {
11147
- if (typeof op === 'number')
11148
- return op;
11149
- if (isBytes(op)) {
11150
- try {
11151
- const val = ScriptNum(bytesLimit, forceMinimal).decode(op);
11152
- if (val > Number.MAX_SAFE_INTEGER)
11153
- return;
11154
- return Number(val);
11155
- }
11156
- catch (e) {
11157
- return;
11158
- }
11159
- }
11160
- return;
11161
- }
11162
- // Converts script bytes to parsed script
11163
- // 5221030000000000000000000000000000000000000000000000000000000000000001210300000000000000000000000000000000000000000000000000000000000000022103000000000000000000000000000000000000000000000000000000000000000353ae
11164
- // =>
11165
- // OP_2
11166
- // 030000000000000000000000000000000000000000000000000000000000000001
11167
- // 030000000000000000000000000000000000000000000000000000000000000002
11168
- // 030000000000000000000000000000000000000000000000000000000000000003
11169
- // OP_3
11170
- // CHECKMULTISIG
11171
- const Script = wrap({
11172
- encodeStream: (w, value) => {
11173
- for (let o of value) {
11174
- if (typeof o === 'string') {
11175
- if (OP[o] === undefined)
11176
- throw new Error(`Unknown opcode=${o}`);
11177
- w.byte(OP[o]);
11178
- continue;
11179
- }
11180
- else if (typeof o === 'number') {
11181
- if (o === 0x00) {
11182
- w.byte(0x00);
11183
- continue;
11184
- }
11185
- else if (1 <= o && o <= 16) {
11186
- w.byte(OP.OP_1 - 1 + o);
11187
- continue;
11188
- }
11189
- }
11190
- // Encode big numbers
11191
- if (typeof o === 'number')
11192
- o = ScriptNum().encode(BigInt(o));
11193
- if (!isBytes(o))
11194
- throw new Error(`Wrong Script OP=${o} (${typeof o})`);
11195
- // Bytes
11196
- const len = o.length;
11197
- if (len < OP.PUSHDATA1)
11198
- w.byte(len);
11199
- else if (len <= 0xff) {
11200
- w.byte(OP.PUSHDATA1);
11201
- w.byte(len);
11202
- }
11203
- else if (len <= 0xffff) {
11204
- w.byte(OP.PUSHDATA2);
11205
- w.bytes(U16LE.encode(len));
11206
- }
11207
- else {
11208
- w.byte(OP.PUSHDATA4);
11209
- w.bytes(U32LE.encode(len));
11210
- }
11211
- w.bytes(o);
11212
- }
11213
- },
11214
- decodeStream: (r) => {
11215
- const out = [];
11216
- while (!r.isEnd()) {
11217
- const cur = r.byte();
11218
- // if 0 < cur < 78
11219
- if (OP.OP_0 < cur && cur <= OP.PUSHDATA4) {
11220
- let len;
11221
- if (cur < OP.PUSHDATA1)
11222
- len = cur;
11223
- else if (cur === OP.PUSHDATA1)
11224
- len = U8.decodeStream(r);
11225
- else if (cur === OP.PUSHDATA2)
11226
- len = U16LE.decodeStream(r);
11227
- else if (cur === OP.PUSHDATA4)
11228
- len = U32LE.decodeStream(r);
11229
- else
11230
- throw new Error('Should be not possible');
11231
- out.push(r.bytes(len));
11232
- }
11233
- else if (cur === 0x00) {
11234
- out.push(0);
11235
- }
11236
- else if (OP.OP_1 <= cur && cur <= OP.OP_16) {
11237
- out.push(cur - (OP.OP_1 - 1));
11238
- }
11239
- else {
11240
- const op = OP[cur];
11241
- if (op === undefined)
11242
- throw new Error(`Unknown opcode=${cur.toString(16)}`);
11243
- out.push(op);
11244
- }
11245
- }
11246
- return out;
11247
- },
11248
- });
11249
- // BTC specific variable length integer encoding
11250
- // https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
11251
- const CSLimits = {
11252
- 0xfd: [0xfd, 2, 253n, 65535n],
11253
- 0xfe: [0xfe, 4, 65536n, 4294967295n],
11254
- 0xff: [0xff, 8, 4294967296n, 18446744073709551615n],
11255
- };
11256
- const CompactSize = wrap({
11257
- encodeStream: (w, value) => {
11258
- if (typeof value === 'number')
11259
- value = BigInt(value);
11260
- if (0n <= value && value <= 252n)
11261
- return w.byte(Number(value));
11262
- for (const [flag, bytes, start, stop] of Object.values(CSLimits)) {
11263
- if (start > value || value > stop)
11264
- continue;
11265
- w.byte(flag);
11266
- for (let i = 0; i < bytes; i++)
11267
- w.byte(Number((value >> (8n * BigInt(i))) & 0xffn));
11268
- return;
11269
- }
11270
- throw w.err(`VarInt too big: ${value}`);
11271
- },
11272
- decodeStream: (r) => {
11273
- const b0 = r.byte();
11274
- if (b0 <= 0xfc)
11275
- return BigInt(b0);
11276
- const [_, bytes, start] = CSLimits[b0];
11277
- let num = 0n;
11278
- for (let i = 0; i < bytes; i++)
11279
- num |= BigInt(r.byte()) << (8n * BigInt(i));
11280
- if (num < start)
11281
- throw r.err(`Wrong CompactSize(${8 * bytes})`);
11282
- return num;
11283
- },
11284
- });
11285
- // Same thing, but in number instead of bigint. Checks for safe integer inside
11286
- const CompactSizeLen = apply(CompactSize, coders.numberBigint);
11287
- // ui8a of size <CompactSize>
11288
- const VarBytes = createBytes(CompactSize);
11289
- // SegWit v0 stack of witness buffers
11290
- const RawWitness = array(CompactSizeLen, VarBytes);
11291
- // Array of size <CompactSize>
11292
- const BTCArray = (t) => array(CompactSize, t);
11293
- const RawInput = struct({
11294
- txid: createBytes(32, true), // hash(prev_tx),
11295
- index: U32LE, // output number of previous tx
11296
- finalScriptSig: VarBytes, // btc merges input and output script, executes it. If ok = tx passes
11297
- sequence: U32LE, // ?
11298
- });
11299
- const RawOutput = struct({ amount: U64LE, script: VarBytes });
11300
- // https://en.bitcoin.it/wiki/Protocol_documentation#tx
11301
- const _RawTx = struct({
11302
- version: I32LE,
11303
- segwitFlag: flag(new Uint8Array([0x00, 0x01])),
11304
- inputs: BTCArray(RawInput),
11305
- outputs: BTCArray(RawOutput),
11306
- witnesses: flagged('segwitFlag', array('inputs/length', RawWitness)),
11307
- // < 500000000 Block number at which this transaction is unlocked
11308
- // >= 500000000 UNIX timestamp at which this transaction is unlocked
11309
- // Handled as part of PSBTv2
11310
- lockTime: U32LE,
11311
- });
11312
- function validateRawTx(tx) {
11313
- if (tx.segwitFlag && tx.witnesses && !tx.witnesses.length)
11314
- throw new Error('Segwit flag with empty witnesses array');
11315
- return tx;
11316
- }
11317
- const RawTx = validate(_RawTx, validateRawTx);
11318
- // Pre-SegWit serialization format (for PSBTv0)
11319
- const RawOldTx = struct({
11320
- version: I32LE,
11321
- inputs: BTCArray(RawInput),
11322
- outputs: BTCArray(RawOutput),
11323
- lockTime: U32LE,
11324
- });
11325
-
11326
- // PSBT BIP174, BIP370, BIP371
11327
- // Can be 33 or 64 bytes
11328
- const PubKeyECDSA = validate(createBytes(null), (pub) => validatePubkey(pub, PubT.ecdsa));
11329
- const PubKeySchnorr = validate(createBytes(32), (pub) => validatePubkey(pub, PubT.schnorr));
11330
- const SignatureSchnorr = validate(createBytes(null), (sig) => {
11331
- if (sig.length !== 64 && sig.length !== 65)
11332
- throw new Error('Schnorr signature should be 64 or 65 bytes long');
11333
- return sig;
11334
- });
11335
- const BIP32Der = struct({
11336
- fingerprint: U32BE,
11337
- path: array(null, U32LE),
11338
- });
11339
- const TaprootBIP32Der = struct({
11340
- hashes: array(CompactSizeLen, createBytes(32)),
11341
- der: BIP32Der,
11342
- });
11343
- // The 78 byte serialized extended public key as defined by BIP 32.
11344
- const GlobalXPUB = createBytes(78);
11345
- const tapScriptSigKey = struct({ pubKey: PubKeySchnorr, leafHash: createBytes(32) });
11346
- // Complex structure for PSBT fields
11347
- // <control byte with leaf version and parity bit> <internal key p> <C> <E> <AB>
11348
- const _TaprootControlBlock = struct({
11349
- version: U8, // With parity :(
11350
- internalKey: createBytes(32),
11351
- merklePath: array(null, createBytes(32)),
11352
- });
11353
- const TaprootControlBlock = validate(_TaprootControlBlock, (cb) => {
11354
- if (cb.merklePath.length > 128)
11355
- throw new Error('TaprootControlBlock: merklePath should be of length 0..128 (inclusive)');
11356
- return cb;
11357
- });
11358
- // {<8-bit uint depth> <8-bit uint leaf version> <compact size uint scriptlen> <bytes script>}*
11359
- const tapTree = array(null, struct({
11360
- depth: U8,
11361
- version: U8,
11362
- script: VarBytes,
11363
- }));
11364
- const BytesInf = createBytes(null); // Bytes will conflict with Bytes type
11365
- const Bytes20 = createBytes(20);
11366
- const Bytes32 = createBytes(32);
11367
- // versionsRequiringExclusing = !versionsAllowsInclusion (as set)
11368
- // {name: [tag, keyCoder, valueCoder, versionsRequiringInclusion, versionsRequiringExclusing, versionsAllowsInclusion, silentIgnore]}
11369
- // SilentIgnore: we use some v2 fields for v1 representation too, so we just clean them before serialize
11370
- // Tables from BIP-0174 (https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)
11371
- // prettier-ignore
11372
- const PSBTGlobal = {
11373
- unsignedTx: [0x00, false, RawOldTx, [0], [0], false],
11374
- xpub: [0x01, GlobalXPUB, BIP32Der, [], [0, 2], false],
11375
- txVersion: [0x02, false, U32LE, [2], [2], false],
11376
- fallbackLocktime: [0x03, false, U32LE, [], [2], false],
11377
- inputCount: [0x04, false, CompactSizeLen, [2], [2], false],
11378
- outputCount: [0x05, false, CompactSizeLen, [2], [2], false],
11379
- txModifiable: [0x06, false, U8, [], [2], false], // TODO: bitfield
11380
- version: [0xfb, false, U32LE, [], [0, 2], false],
11381
- proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
11382
- };
11383
- // prettier-ignore
11384
- const PSBTInput = {
11385
- nonWitnessUtxo: [0x00, false, RawTx, [], [0, 2], false],
11386
- witnessUtxo: [0x01, false, RawOutput, [], [0, 2], false],
11387
- partialSig: [0x02, PubKeyECDSA, BytesInf, [], [0, 2], false],
11388
- sighashType: [0x03, false, U32LE, [], [0, 2], false],
11389
- redeemScript: [0x04, false, BytesInf, [], [0, 2], false],
11390
- witnessScript: [0x05, false, BytesInf, [], [0, 2], false],
11391
- bip32Derivation: [0x06, PubKeyECDSA, BIP32Der, [], [0, 2], false],
11392
- finalScriptSig: [0x07, false, BytesInf, [], [0, 2], false],
11393
- finalScriptWitness: [0x08, false, RawWitness, [], [0, 2], false],
11394
- porCommitment: [0x09, false, BytesInf, [], [0, 2], false],
11395
- ripemd160: [0x0a, Bytes20, BytesInf, [], [0, 2], false],
11396
- sha256: [0x0b, Bytes32, BytesInf, [], [0, 2], false],
11397
- hash160: [0x0c, Bytes20, BytesInf, [], [0, 2], false],
11398
- hash256: [0x0d, Bytes32, BytesInf, [], [0, 2], false],
11399
- txid: [0x0e, false, Bytes32, [2], [2], true],
11400
- index: [0x0f, false, U32LE, [2], [2], true],
11401
- sequence: [0x10, false, U32LE, [], [2], true],
11402
- requiredTimeLocktime: [0x11, false, U32LE, [], [2], false],
11403
- requiredHeightLocktime: [0x12, false, U32LE, [], [2], false],
11404
- tapKeySig: [0x13, false, SignatureSchnorr, [], [0, 2], false],
11405
- tapScriptSig: [0x14, tapScriptSigKey, SignatureSchnorr, [], [0, 2], false],
11406
- tapLeafScript: [0x15, TaprootControlBlock, BytesInf, [], [0, 2], false],
11407
- tapBip32Derivation: [0x16, Bytes32, TaprootBIP32Der, [], [0, 2], false],
11408
- tapInternalKey: [0x17, false, PubKeySchnorr, [], [0, 2], false],
11409
- tapMerkleRoot: [0x18, false, Bytes32, [], [0, 2], false],
11410
- proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
11411
- };
11412
- // All other keys removed when finalizing
11413
- const PSBTInputFinalKeys = [
11414
- 'txid',
11415
- 'sequence',
11416
- 'index',
11417
- 'witnessUtxo',
11418
- 'nonWitnessUtxo',
11419
- 'finalScriptSig',
11420
- 'finalScriptWitness',
11421
- 'unknown',
11422
- ];
11423
- // Can be modified even on signed input
11424
- const PSBTInputUnsignedKeys = [
11425
- 'partialSig',
11426
- 'finalScriptSig',
11427
- 'finalScriptWitness',
11428
- 'tapKeySig',
11429
- 'tapScriptSig',
11430
- ];
11431
- // prettier-ignore
11432
- const PSBTOutput = {
11433
- redeemScript: [0x00, false, BytesInf, [], [0, 2], false],
11434
- witnessScript: [0x01, false, BytesInf, [], [0, 2], false],
11435
- bip32Derivation: [0x02, PubKeyECDSA, BIP32Der, [], [0, 2], false],
11436
- amount: [0x03, false, I64LE, [2], [2], true],
11437
- script: [0x04, false, BytesInf, [2], [2], true],
11438
- tapInternalKey: [0x05, false, PubKeySchnorr, [], [0, 2], false],
11439
- tapTree: [0x06, false, tapTree, [], [0, 2], false],
11440
- tapBip32Derivation: [0x07, PubKeySchnorr, TaprootBIP32Der, [], [0, 2], false],
11441
- proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
11442
- };
11443
- // Can be modified even on signed input
11444
- const PSBTOutputUnsignedKeys = [];
11445
- const PSBTKeyPair = array(NULL, struct({
11446
- // <key> := <keylen> <keytype> <keydata> WHERE keylen = len(keytype)+len(keydata)
11447
- key: prefix(CompactSizeLen, struct({ type: CompactSizeLen, key: createBytes(null) })),
11448
- // <value> := <valuelen> <valuedata>
11449
- value: createBytes(CompactSizeLen),
11450
- }));
11451
- function PSBTKeyInfo(info) {
11452
- const [type, kc, vc, reqInc, allowInc, silentIgnore] = info;
11453
- return { type, kc, vc, reqInc, allowInc, silentIgnore };
11454
- }
11455
- struct({ type: CompactSizeLen, key: createBytes(null) });
11456
- // Key cannot be 'unknown', value coder cannot be array for elements with empty key
11457
- function PSBTKeyMap(psbtEnum) {
11458
- // -> Record<type, [keyName, ...coders]>
11459
- const byType = {};
11460
- for (const k in psbtEnum) {
11461
- const [num, kc, vc] = psbtEnum[k];
11462
- byType[num] = [k, kc, vc];
11463
- }
11464
- return wrap({
11465
- encodeStream: (w, value) => {
11466
- let out = [];
11467
- // Because we use order of psbtEnum, keymap is sorted here
11468
- for (const name in psbtEnum) {
11469
- const val = value[name];
11470
- if (val === undefined)
11471
- continue;
11472
- const [type, kc, vc] = psbtEnum[name];
11473
- if (!kc) {
11474
- out.push({ key: { type, key: EMPTY }, value: vc.encode(val) });
11475
- }
11476
- else {
11477
- // Low level interface, returns keys as is (with duplicates). Useful for debug
11478
- const kv = val.map(([k, v]) => [
11479
- kc.encode(k),
11480
- vc.encode(v),
11481
- ]);
11482
- // sort by keys
11483
- kv.sort((a, b) => compareBytes(a[0], b[0]));
11484
- for (const [key, value] of kv)
11485
- out.push({ key: { key, type }, value });
11486
- }
11487
- }
11488
- if (value.unknown) {
11489
- value.unknown.sort((a, b) => compareBytes(a[0].key, b[0].key));
11490
- for (const [k, v] of value.unknown)
11491
- out.push({ key: k, value: v });
11492
- }
11493
- PSBTKeyPair.encodeStream(w, out);
11494
- },
11495
- decodeStream: (r) => {
11496
- const raw = PSBTKeyPair.decodeStream(r);
11497
- const out = {};
11498
- const noKey = {};
11499
- for (const elm of raw) {
11500
- let name = 'unknown';
11501
- let key = elm.key.key;
11502
- let value = elm.value;
11503
- if (byType[elm.key.type]) {
11504
- const [_name, kc, vc] = byType[elm.key.type];
11505
- name = _name;
11506
- if (!kc && key.length) {
11507
- throw new Error(`PSBT: Non-empty key for ${name} (key=${hex.encode(key)} value=${hex.encode(value)}`);
11508
- }
11509
- key = kc ? kc.decode(key) : undefined;
11510
- value = vc.decode(value);
11511
- if (!kc) {
11512
- if (out[name])
11513
- throw new Error(`PSBT: Same keys: ${name} (key=${key} value=${value})`);
11514
- out[name] = value;
11515
- noKey[name] = true;
11516
- continue;
11517
- }
11518
- }
11519
- else {
11520
- // For unknown: add key type inside key
11521
- key = { type: elm.key.type, key: elm.key.key };
11522
- }
11523
- // Only keyed elements at this point
11524
- if (noKey[name])
11525
- throw new Error(`PSBT: Key type with empty key and no key=${name} val=${value}`);
11526
- if (!out[name])
11527
- out[name] = [];
11528
- out[name].push([key, value]);
11529
- }
11530
- return out;
11531
- },
11532
- });
11533
- }
11534
- const PSBTInputCoder = validate(PSBTKeyMap(PSBTInput), (i) => {
11535
- if (i.finalScriptWitness && !i.finalScriptWitness.length)
11536
- throw new Error('validateInput: empty finalScriptWitness');
11537
- //if (i.finalScriptSig && !i.finalScriptSig.length) throw new Error('validateInput: empty finalScriptSig');
11538
- if (i.partialSig && !i.partialSig.length)
11539
- throw new Error('Empty partialSig');
11540
- if (i.partialSig)
11541
- for (const [k] of i.partialSig)
11542
- validatePubkey(k, PubT.ecdsa);
11543
- if (i.bip32Derivation)
11544
- for (const [k] of i.bip32Derivation)
11545
- validatePubkey(k, PubT.ecdsa);
11546
- // Locktime = unsigned little endian integer greater than or equal to 500000000 representing
11547
- if (i.requiredTimeLocktime !== undefined && i.requiredTimeLocktime < 500000000)
11548
- throw new Error(`validateInput: wrong timeLocktime=${i.requiredTimeLocktime}`);
11549
- // unsigned little endian integer greater than 0 and less than 500000000
11550
- if (i.requiredHeightLocktime !== undefined &&
11551
- (i.requiredHeightLocktime <= 0 || i.requiredHeightLocktime >= 500000000))
11552
- throw new Error(`validateInput: wrong heighLocktime=${i.requiredHeightLocktime}`);
11553
- if (i.tapLeafScript) {
11554
- // tap leaf version appears here twice: in control block and at the end of script
11555
- for (const [k, v] of i.tapLeafScript) {
11556
- if ((k.version & 254) !== v[v.length - 1])
11557
- throw new Error('validateInput: tapLeafScript version mimatch');
11558
- if (v[v.length - 1] & 1)
11559
- throw new Error('validateInput: tapLeafScript version has parity bit!');
11560
- }
11561
- }
11562
- return i;
11563
- });
11564
- const PSBTOutputCoder = validate(PSBTKeyMap(PSBTOutput), (o) => {
11565
- if (o.bip32Derivation)
11566
- for (const [k] of o.bip32Derivation)
11567
- validatePubkey(k, PubT.ecdsa);
11568
- return o;
11569
- });
11570
- const PSBTGlobalCoder = validate(PSBTKeyMap(PSBTGlobal), (g) => {
11571
- const version = g.version || 0;
11572
- if (version === 0) {
11573
- if (!g.unsignedTx)
11574
- throw new Error('PSBTv0: missing unsignedTx');
11575
- for (const inp of g.unsignedTx.inputs)
11576
- if (inp.finalScriptSig && inp.finalScriptSig.length)
11577
- throw new Error('PSBTv0: input scriptSig found in unsignedTx');
11578
- }
11579
- return g;
11580
- });
11581
- const _RawPSBTV0 = struct({
11582
- magic: magic(string(new Uint8Array([0xff])), 'psbt'),
11583
- global: PSBTGlobalCoder,
11584
- inputs: array('global/unsignedTx/inputs/length', PSBTInputCoder),
11585
- outputs: array(null, PSBTOutputCoder),
11586
- });
11587
- const _RawPSBTV2 = struct({
11588
- magic: magic(string(new Uint8Array([0xff])), 'psbt'),
11589
- global: PSBTGlobalCoder,
11590
- inputs: array('global/inputCount', PSBTInputCoder),
11591
- outputs: array('global/outputCount', PSBTOutputCoder),
11592
- });
11593
- struct({
11594
- magic: magic(string(new Uint8Array([0xff])), 'psbt'),
11595
- items: array(null, apply(array(NULL, tuple([createHex(CompactSizeLen), createBytes(CompactSize)])), coders.dict())),
11596
- });
11597
- function validatePSBTFields(version, info, lst) {
11598
- for (const k in lst) {
11599
- if (k === 'unknown')
11600
- continue;
11601
- if (!info[k])
11602
- continue;
11603
- const { allowInc } = PSBTKeyInfo(info[k]);
11604
- if (!allowInc.includes(version))
11605
- throw new Error(`PSBTv${version}: field ${k} is not allowed`);
11606
- }
11607
- for (const k in info) {
11608
- const { reqInc } = PSBTKeyInfo(info[k]);
11609
- if (reqInc.includes(version) && lst[k] === undefined)
11610
- throw new Error(`PSBTv${version}: missing required field ${k}`);
11611
- }
11612
- }
11613
- function cleanPSBTFields(version, info, lst) {
11614
- const out = {};
11615
- for (const _k in lst) {
11616
- const k = _k;
11617
- if (k !== 'unknown') {
11618
- if (!info[k])
11619
- continue;
11620
- const { allowInc, silentIgnore } = PSBTKeyInfo(info[k]);
11621
- if (!allowInc.includes(version)) {
11622
- if (silentIgnore)
11623
- continue;
11624
- throw new Error(`Failed to serialize in PSBTv${version}: ${k} but versions allows inclusion=${allowInc}`);
11625
- }
11626
- }
11627
- out[k] = lst[k];
11628
- }
11629
- return out;
11630
- }
11631
- function validatePSBT(tx) {
11632
- const version = (tx && tx.global && tx.global.version) || 0;
11633
- validatePSBTFields(version, PSBTGlobal, tx.global);
11634
- for (const i of tx.inputs)
11635
- validatePSBTFields(version, PSBTInput, i);
11636
- for (const o of tx.outputs)
11637
- validatePSBTFields(version, PSBTOutput, o);
11638
- // We allow only one empty element at the end of map (compat with bitcoinjs-lib bug)
11639
- const inputCount = !version ? tx.global.unsignedTx.inputs.length : tx.global.inputCount;
11640
- if (tx.inputs.length < inputCount)
11641
- throw new Error('Not enough inputs');
11642
- const inputsLeft = tx.inputs.slice(inputCount);
11643
- if (inputsLeft.length > 1 || (inputsLeft.length && Object.keys(inputsLeft[0]).length))
11644
- throw new Error(`Unexpected inputs left in tx=${inputsLeft}`);
11645
- // Same for inputs
11646
- const outputCount = !version ? tx.global.unsignedTx.outputs.length : tx.global.outputCount;
11647
- if (tx.outputs.length < outputCount)
11648
- throw new Error('Not outputs inputs');
11649
- const outputsLeft = tx.outputs.slice(outputCount);
11650
- if (outputsLeft.length > 1 || (outputsLeft.length && Object.keys(outputsLeft[0]).length))
11651
- throw new Error(`Unexpected outputs left in tx=${outputsLeft}`);
11652
- return tx;
11653
- }
11654
- function mergeKeyMap(psbtEnum, val, cur, allowedFields, allowUnknown) {
11655
- const res = { ...cur, ...val };
11656
- // All arguments can be provided as hex
11657
- for (const k in psbtEnum) {
11658
- const key = k;
11659
- const [_, kC, vC] = psbtEnum[key];
11660
- const cannotChange = allowedFields && !allowedFields.includes(k);
11661
- if (val[k] === undefined && k in val) {
11662
- if (cannotChange)
11663
- throw new Error(`Cannot remove signed field=${k}`);
11664
- delete res[k];
11665
- }
11666
- else if (kC) {
11667
- const oldKV = (cur && cur[k] ? cur[k] : []);
11668
- let newKV = val[key];
11669
- if (newKV) {
11670
- if (!Array.isArray(newKV))
11671
- throw new Error(`keyMap(${k}): KV pairs should be [k, v][]`);
11672
- // Decode hex in k-v
11673
- newKV = newKV.map((val) => {
11674
- if (val.length !== 2)
11675
- throw new Error(`keyMap(${k}): KV pairs should be [k, v][]`);
11676
- return [
11677
- typeof val[0] === 'string' ? kC.decode(hex.decode(val[0])) : val[0],
11678
- typeof val[1] === 'string' ? vC.decode(hex.decode(val[1])) : val[1],
11679
- ];
11680
- });
11681
- const map = {};
11682
- const add = (kStr, k, v) => {
11683
- if (map[kStr] === undefined) {
11684
- map[kStr] = [k, v];
11685
- return;
11686
- }
11687
- const oldVal = hex.encode(vC.encode(map[kStr][1]));
11688
- const newVal = hex.encode(vC.encode(v));
11689
- if (oldVal !== newVal)
11690
- throw new Error(`keyMap(${key}): same key=${kStr} oldVal=${oldVal} newVal=${newVal}`);
11691
- };
11692
- for (const [k, v] of oldKV) {
11693
- const kStr = hex.encode(kC.encode(k));
11694
- add(kStr, k, v);
11695
- }
11696
- for (const [k, v] of newKV) {
11697
- const kStr = hex.encode(kC.encode(k));
11698
- // undefined removes previous value
11699
- if (v === undefined) {
11700
- if (cannotChange)
11701
- throw new Error(`Cannot remove signed field=${key}/${k}`);
11702
- delete map[kStr];
11703
- }
11704
- else
11705
- add(kStr, k, v);
11706
- }
11707
- res[key] = Object.values(map);
11708
- }
11709
- }
11710
- else if (typeof res[k] === 'string') {
11711
- res[k] = vC.decode(hex.decode(res[k]));
11712
- }
11713
- else if (cannotChange && k in val && cur && cur[k] !== undefined) {
11714
- if (!equalBytes(vC.encode(val[k]), vC.encode(cur[k])))
11715
- throw new Error(`Cannot change signed field=${k}`);
11716
- }
11717
- }
11718
- // Remove unknown keys except the "unknown" array if allowUnknown is true
11719
- for (const k in res) {
11720
- if (!psbtEnum[k]) {
11721
- if (allowUnknown && k === 'unknown')
11722
- continue;
11723
- delete res[k];
11724
- }
11725
- }
11726
- return res;
11727
- }
11728
- const RawPSBTV0 = validate(_RawPSBTV0, validatePSBT);
11729
- const RawPSBTV2 = validate(_RawPSBTV2, validatePSBT);
11730
-
11731
- const OutP2A = {
11732
- encode(from) {
11733
- if (from.length !== 2 || from[0] !== 1 || !isBytes(from[1]) || hex.encode(from[1]) !== '4e73')
11734
- return;
11735
- return { type: 'p2a', script: Script.encode(from) };
11736
- },
11737
- decode: (to) => {
11738
- if (to.type !== 'p2a')
11739
- return;
11740
- return [1, hex.decode('4e73')];
11741
- },
11742
- };
11743
- function isValidPubkey(pub, type) {
11744
- try {
11745
- validatePubkey(pub, type);
11746
- return true;
11747
- }
11748
- catch (e) {
11749
- return false;
11750
- }
11751
- }
11752
- const OutPK = {
11753
- encode(from) {
11754
- if (from.length !== 2 ||
11755
- !isBytes(from[0]) ||
11756
- !isValidPubkey(from[0], PubT.ecdsa) ||
11757
- from[1] !== 'CHECKSIG')
11758
- return;
11759
- return { type: 'pk', pubkey: from[0] };
11760
- },
11761
- decode: (to) => (to.type === 'pk' ? [to.pubkey, 'CHECKSIG'] : undefined),
11762
- };
11763
- const OutPKH = {
11764
- encode(from) {
11765
- if (from.length !== 5 || from[0] !== 'DUP' || from[1] !== 'HASH160' || !isBytes(from[2]))
11766
- return;
11767
- if (from[3] !== 'EQUALVERIFY' || from[4] !== 'CHECKSIG')
11768
- return;
11769
- return { type: 'pkh', hash: from[2] };
11770
- },
11771
- decode: (to) => to.type === 'pkh' ? ['DUP', 'HASH160', to.hash, 'EQUALVERIFY', 'CHECKSIG'] : undefined,
11772
- };
11773
- const OutSH = {
11774
- encode(from) {
11775
- if (from.length !== 3 || from[0] !== 'HASH160' || !isBytes(from[1]) || from[2] !== 'EQUAL')
11776
- return;
11777
- return { type: 'sh', hash: from[1] };
11778
- },
11779
- decode: (to) => to.type === 'sh' ? ['HASH160', to.hash, 'EQUAL'] : undefined,
11780
- };
11781
- const OutWSH = {
11782
- encode(from) {
11783
- if (from.length !== 2 || from[0] !== 0 || !isBytes(from[1]))
11784
- return;
11785
- if (from[1].length !== 32)
11786
- return;
11787
- return { type: 'wsh', hash: from[1] };
11788
- },
11789
- decode: (to) => (to.type === 'wsh' ? [0, to.hash] : undefined),
11790
- };
11791
- const OutWPKH = {
11792
- encode(from) {
11793
- if (from.length !== 2 || from[0] !== 0 || !isBytes(from[1]))
11794
- return;
11795
- if (from[1].length !== 20)
11796
- return;
11797
- return { type: 'wpkh', hash: from[1] };
11798
- },
11799
- decode: (to) => (to.type === 'wpkh' ? [0, to.hash] : undefined),
11800
- };
11801
- const OutMS = {
11802
- encode(from) {
11803
- const last = from.length - 1;
11804
- if (from[last] !== 'CHECKMULTISIG')
11805
- return;
11806
- const m = from[0];
11807
- const n = from[last - 1];
11808
- if (typeof m !== 'number' || typeof n !== 'number')
11809
- return;
11810
- const pubkeys = from.slice(1, -2);
11811
- if (n !== pubkeys.length)
11812
- return;
11813
- for (const pub of pubkeys)
11814
- if (!isBytes(pub))
11815
- return;
11816
- return { type: 'ms', m, pubkeys: pubkeys }; // we don't need n, since it is the same as pubkeys
11817
- },
11818
- // checkmultisig(n, ..pubkeys, m)
11819
- decode: (to) => to.type === 'ms' ? [to.m, ...to.pubkeys, to.pubkeys.length, 'CHECKMULTISIG'] : undefined,
11820
- };
11821
- const OutTR = {
11822
- encode(from) {
11823
- if (from.length !== 2 || from[0] !== 1 || !isBytes(from[1]))
11824
- return;
11825
- return { type: 'tr', pubkey: from[1] };
11826
- },
11827
- decode: (to) => (to.type === 'tr' ? [1, to.pubkey] : undefined),
11828
- };
11829
- const OutTRNS = {
11830
- encode(from) {
11831
- const last = from.length - 1;
11832
- if (from[last] !== 'CHECKSIG')
11833
- return;
11834
- const pubkeys = [];
11835
- // On error return, since it can be different script
11836
- for (let i = 0; i < last; i++) {
11837
- const elm = from[i];
11838
- if (i & 1) {
11839
- if (elm !== 'CHECKSIGVERIFY' || i === last - 1)
11840
- return;
11841
- continue;
11842
- }
11843
- if (!isBytes(elm))
11844
- return;
11845
- pubkeys.push(elm);
11846
- }
11847
- return { type: 'tr_ns', pubkeys };
11848
- },
11849
- decode: (to) => {
11850
- if (to.type !== 'tr_ns')
11851
- return;
11852
- const out = [];
11853
- for (let i = 0; i < to.pubkeys.length - 1; i++)
11854
- out.push(to.pubkeys[i], 'CHECKSIGVERIFY');
11855
- out.push(to.pubkeys[to.pubkeys.length - 1], 'CHECKSIG');
11856
- return out;
11857
- },
11858
- };
11859
- const OutTRMS = {
11860
- encode(from) {
11861
- const last = from.length - 1;
11862
- if (from[last] !== 'NUMEQUAL' || from[1] !== 'CHECKSIG')
11863
- return;
11864
- const pubkeys = [];
11865
- const m = OpToNum(from[last - 1]);
11866
- if (typeof m !== 'number')
11867
- return;
11868
- for (let i = 0; i < last - 1; i++) {
11869
- const elm = from[i];
11870
- if (i & 1) {
11871
- if (elm !== (i === 1 ? 'CHECKSIG' : 'CHECKSIGADD'))
11872
- throw new Error('OutScript.encode/tr_ms: wrong element');
11873
- continue;
11874
- }
11875
- if (!isBytes(elm))
11876
- throw new Error('OutScript.encode/tr_ms: wrong key element');
11877
- pubkeys.push(elm);
11878
- }
11879
- return { type: 'tr_ms', pubkeys, m };
11880
- },
11881
- decode: (to) => {
11882
- if (to.type !== 'tr_ms')
11883
- return;
11884
- const out = [to.pubkeys[0], 'CHECKSIG'];
11885
- for (let i = 1; i < to.pubkeys.length; i++)
11886
- out.push(to.pubkeys[i], 'CHECKSIGADD');
11887
- out.push(to.m, 'NUMEQUAL');
11888
- return out;
11889
- },
11890
- };
11891
- const OutUnknown = {
11892
- encode(from) {
11893
- return { type: 'unknown', script: Script.encode(from) };
11894
- },
11895
- decode: (to) => to.type === 'unknown' ? Script.decode(to.script) : undefined,
11896
- };
11897
- // /Payments
11898
- const OutScripts = [
11899
- OutP2A,
11900
- OutPK,
11901
- OutPKH,
11902
- OutSH,
11903
- OutWSH,
11904
- OutWPKH,
11905
- OutMS,
11906
- OutTR,
11907
- OutTRNS,
11908
- OutTRMS,
11909
- OutUnknown,
11910
- ];
11911
- // TODO: we can support user supplied output scripts now
11912
- // - addOutScript
11913
- // - removeOutScript
11914
- // - We can do that as log we modify array in-place
11915
- // - Actually is very hard, since there is sign/finalize logic
11916
- const _OutScript = apply(Script, coders.match(OutScripts));
11917
- // We can validate this once, because of packed & coders
11918
- const OutScript = validate(_OutScript, (i) => {
11919
- if (i.type === 'pk' && !isValidPubkey(i.pubkey, PubT.ecdsa))
11920
- throw new Error('OutScript/pk: wrong key');
11921
- if ((i.type === 'pkh' || i.type === 'sh' || i.type === 'wpkh') &&
11922
- (!isBytes(i.hash) || i.hash.length !== 20))
11923
- throw new Error(`OutScript/${i.type}: wrong hash`);
11924
- if (i.type === 'wsh' && (!isBytes(i.hash) || i.hash.length !== 32))
11925
- throw new Error(`OutScript/wsh: wrong hash`);
11926
- if (i.type === 'tr' && (!isBytes(i.pubkey) || !isValidPubkey(i.pubkey, PubT.schnorr)))
11927
- throw new Error('OutScript/tr: wrong taproot public key');
11928
- if (i.type === 'ms' || i.type === 'tr_ns' || i.type === 'tr_ms')
11929
- if (!Array.isArray(i.pubkeys))
11930
- throw new Error('OutScript/multisig: wrong pubkeys array');
11931
- if (i.type === 'ms') {
11932
- const n = i.pubkeys.length;
11933
- for (const p of i.pubkeys)
11934
- if (!isValidPubkey(p, PubT.ecdsa))
11935
- throw new Error('OutScript/multisig: wrong pubkey');
11936
- if (i.m <= 0 || n > 16 || i.m > n)
11937
- throw new Error('OutScript/multisig: invalid params');
11938
- }
11939
- if (i.type === 'tr_ns' || i.type === 'tr_ms') {
11940
- for (const p of i.pubkeys)
11941
- if (!isValidPubkey(p, PubT.schnorr))
11942
- throw new Error(`OutScript/${i.type}: wrong pubkey`);
11943
- }
11944
- if (i.type === 'tr_ms') {
11945
- const n = i.pubkeys.length;
11946
- if (i.m <= 0 || n > 999 || i.m > n)
11947
- throw new Error('OutScript/tr_ms: invalid params');
11948
- }
11949
- return i;
11950
- });
11951
- // Basic sanity check for scripts
11952
- function checkWSH(s, witnessScript) {
11953
- if (!equalBytes(s.hash, sha256$1(witnessScript)))
11954
- throw new Error('checkScript: wsh wrong witnessScript hash');
11955
- const w = OutScript.decode(witnessScript);
11956
- if (w.type === 'tr' || w.type === 'tr_ns' || w.type === 'tr_ms')
11957
- throw new Error(`checkScript: P2${w.type} cannot be wrapped in P2SH`);
11958
- if (w.type === 'wpkh' || w.type === 'sh')
11959
- throw new Error(`checkScript: P2${w.type} cannot be wrapped in P2WSH`);
11960
- }
11961
- function checkScript(script, redeemScript, witnessScript) {
11962
- if (script) {
11963
- const s = OutScript.decode(script);
11964
- // ms||pk maybe work, but there will be no address, hard to spend
11965
- if (s.type === 'tr_ns' || s.type === 'tr_ms' || s.type === 'ms' || s.type == 'pk')
11966
- throw new Error(`checkScript: non-wrapped ${s.type}`);
11967
- if (s.type === 'sh' && redeemScript) {
11968
- if (!equalBytes(s.hash, hash160(redeemScript)))
11969
- throw new Error('checkScript: sh wrong redeemScript hash');
11970
- const r = OutScript.decode(redeemScript);
11971
- if (r.type === 'tr' || r.type === 'tr_ns' || r.type === 'tr_ms')
11972
- throw new Error(`checkScript: P2${r.type} cannot be wrapped in P2SH`);
11973
- // Not sure if this unspendable, but we cannot represent this via PSBT
11974
- if (r.type === 'sh')
11975
- throw new Error('checkScript: P2SH cannot be wrapped in P2SH');
11976
- }
11977
- if (s.type === 'wsh' && witnessScript)
11978
- checkWSH(s, witnessScript);
11979
- }
11980
- if (redeemScript) {
11981
- const r = OutScript.decode(redeemScript);
11982
- if (r.type === 'wsh' && witnessScript)
11983
- checkWSH(r, witnessScript);
11984
- }
11985
- }
11986
- const TAP_LEAF_VERSION = 0xc0;
11987
- const tapLeafHash = (script, version = TAP_LEAF_VERSION) => tagSchnorr('TapLeaf', new Uint8Array([version]), VarBytes.encode(script));
11988
- const base58check = createBase58check(sha256$1);
11989
- function validateWitness(version, data) {
11990
- if (data.length < 2 || data.length > 40)
11991
- throw new Error('Witness: invalid length');
11992
- if (version > 16)
11993
- throw new Error('Witness: invalid version');
11994
- if (version === 0 && !(data.length === 20 || data.length === 32))
11995
- throw new Error('Witness: invalid length for version');
11996
- }
11997
- function programToWitness(version, data, network = NETWORK) {
11998
- validateWitness(version, data);
11999
- const coder = version === 0 ? bech32 : bech32m;
12000
- return coder.encode(network.bech32, [version].concat(coder.toWords(data)));
12001
- }
12002
- function formatKey(hashed, prefix) {
12003
- return base58check.encode(concatBytes(Uint8Array.from(prefix), hashed));
12004
- }
12005
- // Returns OutType, which can be used to create outscript
12006
- function Address(network = NETWORK) {
12007
- return {
12008
- encode(from) {
12009
- const { type } = from;
12010
- if (type === 'wpkh')
12011
- return programToWitness(0, from.hash, network);
12012
- else if (type === 'wsh')
12013
- return programToWitness(0, from.hash, network);
12014
- else if (type === 'tr')
12015
- return programToWitness(1, from.pubkey, network);
12016
- else if (type === 'pkh')
12017
- return formatKey(from.hash, [network.pubKeyHash]);
12018
- else if (type === 'sh')
12019
- return formatKey(from.hash, [network.scriptHash]);
12020
- throw new Error(`Unknown address type=${type}`);
12021
- },
12022
- decode(address) {
12023
- if (address.length < 14 || address.length > 74)
12024
- throw new Error('Invalid address length');
12025
- // Bech32
12026
- if (network.bech32 && address.toLowerCase().startsWith(`${network.bech32}1`)) {
12027
- let res;
12028
- try {
12029
- res = bech32.decode(address);
12030
- if (res.words[0] !== 0)
12031
- throw new Error(`bech32: wrong version=${res.words[0]}`);
12032
- }
12033
- catch (_) {
12034
- // Starting from version 1 it is decoded as bech32m
12035
- res = bech32m.decode(address);
12036
- if (res.words[0] === 0)
12037
- throw new Error(`bech32m: wrong version=${res.words[0]}`);
12038
- }
12039
- if (res.prefix !== network.bech32)
12040
- throw new Error(`wrong bech32 prefix=${res.prefix}`);
12041
- const [version, ...program] = res.words;
12042
- const data = bech32.fromWords(program);
12043
- validateWitness(version, data);
12044
- if (version === 0 && data.length === 32)
12045
- return { type: 'wsh', hash: data };
12046
- else if (version === 0 && data.length === 20)
12047
- return { type: 'wpkh', hash: data };
12048
- else if (version === 1 && data.length === 32)
12049
- return { type: 'tr', pubkey: data };
12050
- else
12051
- throw new Error('Unknown witness program');
12052
- }
12053
- const data = base58check.decode(address);
12054
- if (data.length !== 21)
12055
- throw new Error('Invalid base58 address');
12056
- // Pay To Public Key Hash
12057
- if (data[0] === network.pubKeyHash) {
12058
- return { type: 'pkh', hash: data.slice(1) };
12059
- }
12060
- else if (data[0] === network.scriptHash) {
12061
- return {
12062
- type: 'sh',
12063
- hash: data.slice(1),
12064
- };
12065
- }
12066
- throw new Error(`Invalid address prefix=${data[0]}`);
12067
- },
12068
- };
12069
- }
12070
-
12071
- const EMPTY32 = new Uint8Array(32);
12072
- const EMPTY_OUTPUT = {
12073
- amount: 0xffffffffffffffffn,
12074
- script: EMPTY,
12075
- };
12076
- const toVsize = (weight) => Math.ceil(weight / 4);
12077
- const PRECISION = 8;
12078
- const DEFAULT_VERSION$2 = 2;
12079
- const DEFAULT_LOCKTIME = 0;
12080
- const DEFAULT_SEQUENCE = 4294967295;
12081
- coders.decimal(PRECISION);
12082
- // Same as value || def, but doesn't overwrites zero ('0', 0, 0n, etc)
12083
- const def = (value, def) => (value === undefined ? def : value);
12084
- function cloneDeep(obj) {
12085
- if (Array.isArray(obj))
12086
- return obj.map((i) => cloneDeep(i));
12087
- // slice of nodejs Buffer doesn't copy
12088
- else if (isBytes(obj))
12089
- return Uint8Array.from(obj);
12090
- // immutable
12091
- else if (['number', 'bigint', 'boolean', 'string', 'undefined'].includes(typeof obj))
12092
- return obj;
12093
- // null is object
12094
- else if (obj === null)
12095
- return obj;
12096
- // should be last, so it won't catch other types
12097
- else if (typeof obj === 'object') {
12098
- return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, cloneDeep(v)]));
12099
- }
12100
- throw new Error(`cloneDeep: unknown type=${obj} (${typeof obj})`);
12101
- }
12102
- /**
12103
- * Internal, exported only for backwards-compat. Use `SigHash` instead.
12104
- * @deprecated
12105
- */
12106
- var SignatureHash;
12107
- (function (SignatureHash) {
12108
- SignatureHash[SignatureHash["DEFAULT"] = 0] = "DEFAULT";
12109
- SignatureHash[SignatureHash["ALL"] = 1] = "ALL";
12110
- SignatureHash[SignatureHash["NONE"] = 2] = "NONE";
12111
- SignatureHash[SignatureHash["SINGLE"] = 3] = "SINGLE";
12112
- SignatureHash[SignatureHash["ANYONECANPAY"] = 128] = "ANYONECANPAY";
12113
- })(SignatureHash || (SignatureHash = {}));
12114
- var SigHash;
12115
- (function (SigHash) {
12116
- SigHash[SigHash["DEFAULT"] = 0] = "DEFAULT";
12117
- SigHash[SigHash["ALL"] = 1] = "ALL";
12118
- SigHash[SigHash["NONE"] = 2] = "NONE";
12119
- SigHash[SigHash["SINGLE"] = 3] = "SINGLE";
12120
- SigHash[SigHash["DEFAULT_ANYONECANPAY"] = 128] = "DEFAULT_ANYONECANPAY";
12121
- SigHash[SigHash["ALL_ANYONECANPAY"] = 129] = "ALL_ANYONECANPAY";
12122
- SigHash[SigHash["NONE_ANYONECANPAY"] = 130] = "NONE_ANYONECANPAY";
12123
- SigHash[SigHash["SINGLE_ANYONECANPAY"] = 131] = "SINGLE_ANYONECANPAY";
12124
- })(SigHash || (SigHash = {}));
12125
- function getTaprootKeys(privKey, pubKey, internalKey, merkleRoot = EMPTY) {
12126
- if (equalBytes(internalKey, pubKey)) {
12127
- privKey = taprootTweakPrivKey(privKey, merkleRoot);
12128
- pubKey = pubSchnorr(privKey);
12129
- }
12130
- return { privKey, pubKey };
12131
- }
12132
- // Force check amount/script
12133
- function outputBeforeSign(i) {
12134
- if (i.script === undefined || i.amount === undefined)
12135
- throw new Error('Transaction/output: script and amount required');
12136
- return { script: i.script, amount: i.amount };
12137
- }
12138
- // Force check index/txid/sequence
12139
- function inputBeforeSign(i) {
12140
- if (i.txid === undefined || i.index === undefined)
12141
- throw new Error('Transaction/input: txid and index required');
12142
- return {
12143
- txid: i.txid,
12144
- index: i.index,
12145
- sequence: def(i.sequence, DEFAULT_SEQUENCE),
12146
- finalScriptSig: def(i.finalScriptSig, EMPTY),
12147
- };
12148
- }
12149
- function cleanFinalInput(i) {
12150
- for (const _k in i) {
12151
- const k = _k;
12152
- if (!PSBTInputFinalKeys.includes(k))
12153
- delete i[k];
12154
- }
12155
- }
12156
- // (TxHash, Idx)
12157
- const TxHashIdx = struct({ txid: createBytes(32, true), index: U32LE });
12158
- function validateSigHash(s) {
12159
- if (typeof s !== 'number' || typeof SigHash[s] !== 'string')
12160
- throw new Error(`Invalid SigHash=${s}`);
12161
- return s;
12162
- }
12163
- function unpackSighash(hashType) {
12164
- const masked = hashType & 0b0011111;
12165
- return {
12166
- isAny: !!(hashType & SignatureHash.ANYONECANPAY),
12167
- isNone: masked === SignatureHash.NONE,
12168
- isSingle: masked === SignatureHash.SINGLE,
12169
- };
12170
- }
12171
- function validateOpts(opts) {
12172
- if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')
12173
- throw new Error(`Wrong object type for transaction options: ${opts}`);
12174
- const _opts = {
12175
- ...opts,
12176
- // Defaults
12177
- version: def(opts.version, DEFAULT_VERSION$2),
12178
- lockTime: def(opts.lockTime, 0),
12179
- PSBTVersion: def(opts.PSBTVersion, 0),
12180
- };
12181
- if (typeof _opts.allowUnknowInput !== 'undefined')
12182
- opts.allowUnknownInputs = _opts.allowUnknowInput;
12183
- if (typeof _opts.allowUnknowOutput !== 'undefined')
12184
- opts.allowUnknownOutputs = _opts.allowUnknowOutput;
12185
- if (typeof _opts.lockTime !== 'number')
12186
- throw new Error('Transaction lock time should be number');
12187
- U32LE.encode(_opts.lockTime); // Additional range checks that lockTime
12188
- // There is no PSBT v1, and any new version will probably have fields which we don't know how to parse, which
12189
- // can lead to constructing broken transactions
12190
- if (_opts.PSBTVersion !== 0 && _opts.PSBTVersion !== 2)
12191
- throw new Error(`Unknown PSBT version ${_opts.PSBTVersion}`);
12192
- // Flags
12193
- for (const k of [
12194
- 'allowUnknownVersion',
12195
- 'allowUnknownOutputs',
12196
- 'allowUnknownInputs',
12197
- 'disableScriptCheck',
12198
- 'bip174jsCompat',
12199
- 'allowLegacyWitnessUtxo',
12200
- 'lowR',
12201
- ]) {
12202
- const v = _opts[k];
12203
- if (v === undefined)
12204
- continue; // optional
12205
- if (typeof v !== 'boolean')
12206
- throw new Error(`Transation options wrong type: ${k}=${v} (${typeof v})`);
12207
- }
12208
- // 0 and -1 happens in tests
12209
- if (_opts.allowUnknownVersion
12210
- ? typeof _opts.version === 'number'
12211
- : ![-1, 0, 1, 2, 3].includes(_opts.version))
12212
- throw new Error(`Unknown version: ${_opts.version}`);
12213
- if (_opts.customScripts !== undefined) {
12214
- const cs = _opts.customScripts;
12215
- if (!Array.isArray(cs)) {
12216
- throw new Error(`wrong custom scripts type (expected array): customScripts=${cs} (${typeof cs})`);
12217
- }
12218
- for (const s of cs) {
12219
- if (typeof s.encode !== 'function' || typeof s.decode !== 'function')
12220
- throw new Error(`wrong script=${s} (${typeof s})`);
12221
- if (s.finalizeTaproot !== undefined && typeof s.finalizeTaproot !== 'function')
12222
- throw new Error(`wrong script=${s} (${typeof s})`);
12223
- }
12224
- }
12225
- return Object.freeze(_opts);
12226
- }
12227
- // NOTE: we cannot do this inside PSBTInput coder, because there is no index/txid at this point!
12228
- function validateInput(i) {
12229
- if (i.nonWitnessUtxo && i.index !== undefined) {
12230
- const last = i.nonWitnessUtxo.outputs.length - 1;
12231
- if (i.index > last)
12232
- throw new Error(`validateInput: index(${i.index}) not in nonWitnessUtxo`);
12233
- const prevOut = i.nonWitnessUtxo.outputs[i.index];
12234
- if (i.witnessUtxo &&
12235
- (!equalBytes(i.witnessUtxo.script, prevOut.script) || i.witnessUtxo.amount !== prevOut.amount))
12236
- throw new Error('validateInput: witnessUtxo different from nonWitnessUtxo');
12237
- if (i.txid) {
12238
- const outputs = i.nonWitnessUtxo.outputs;
12239
- if (outputs.length - 1 < i.index)
12240
- throw new Error('nonWitnessUtxo: incorect output index');
12241
- // At this point, we are using previous tx output to create new input.
12242
- // Script safety checks are unnecessary:
12243
- // - User has no control over previous tx. If somebody send money in same tx
12244
- // as unspendable output, we still want user able to spend money
12245
- // - We still want some checks to notify user about possible errors early
12246
- // in case user wants to use wrong input by mistake
12247
- // - Worst case: tx will be rejected by nodes. Still better than disallowing user
12248
- // to spend real input, no matter how broken it looks
12249
- const tx = Transaction.fromRaw(RawTx.encode(i.nonWitnessUtxo), {
12250
- allowUnknownOutputs: true,
12251
- disableScriptCheck: true,
12252
- allowUnknownInputs: true,
12253
- });
12254
- const txid = hex.encode(i.txid);
12255
- // PSBTv2 vectors have non-final tx in inputs
12256
- if (tx.isFinal && tx.id !== txid)
12257
- throw new Error(`nonWitnessUtxo: wrong txid, exp=${txid} got=${tx.id}`);
12258
- }
12259
- }
12260
- return i;
12261
- }
12262
- // Normalizes input
12263
- function getPrevOut(input) {
12264
- if (input.nonWitnessUtxo) {
12265
- if (input.index === undefined)
12266
- throw new Error('Unknown input index');
12267
- return input.nonWitnessUtxo.outputs[input.index];
12268
- }
12269
- else if (input.witnessUtxo)
12270
- return input.witnessUtxo;
12271
- else
12272
- throw new Error('Cannot find previous output info');
12273
- }
12274
- function normalizeInput(i, cur, allowedFields, disableScriptCheck = false, allowUnknown = false) {
12275
- let { nonWitnessUtxo, txid } = i;
12276
- // String support for common fields. We usually prefer Uint8Array to avoid errors
12277
- // like hex looking string accidentally passed, however, in case of nonWitnessUtxo
12278
- // it is better to expect string, since constructing this complex object will be
12279
- // difficult for user
12280
- if (typeof nonWitnessUtxo === 'string')
12281
- nonWitnessUtxo = hex.decode(nonWitnessUtxo);
12282
- if (isBytes(nonWitnessUtxo))
12283
- nonWitnessUtxo = RawTx.decode(nonWitnessUtxo);
12284
- if (!('nonWitnessUtxo' in i) && nonWitnessUtxo === undefined)
12285
- nonWitnessUtxo = cur?.nonWitnessUtxo;
12286
- if (typeof txid === 'string')
12287
- txid = hex.decode(txid);
12288
- // TODO: if we have nonWitnessUtxo, we can extract txId from here
12289
- if (txid === undefined)
12290
- txid = cur?.txid;
12291
- let res = { ...cur, ...i, nonWitnessUtxo, txid };
12292
- if (!('nonWitnessUtxo' in i) && res.nonWitnessUtxo === undefined)
12293
- delete res.nonWitnessUtxo;
12294
- if (res.sequence === undefined)
12295
- res.sequence = DEFAULT_SEQUENCE;
12296
- if (res.tapMerkleRoot === null)
12297
- delete res.tapMerkleRoot;
12298
- res = mergeKeyMap(PSBTInput, res, cur, allowedFields, allowUnknown);
12299
- PSBTInputCoder.encode(res); // Validates that everything is correct at this point
12300
- let prevOut;
12301
- if (res.nonWitnessUtxo && res.index !== undefined)
12302
- prevOut = res.nonWitnessUtxo.outputs[res.index];
12303
- else if (res.witnessUtxo)
12304
- prevOut = res.witnessUtxo;
12305
- if (prevOut && !disableScriptCheck)
12306
- checkScript(prevOut && prevOut.script, res.redeemScript, res.witnessScript);
12307
- return res;
12308
- }
12309
- function getInputType(input, allowLegacyWitnessUtxo = false) {
12310
- let txType = 'legacy';
12311
- let defaultSighash = SignatureHash.ALL;
12312
- const prevOut = getPrevOut(input);
12313
- const first = OutScript.decode(prevOut.script);
12314
- let type = first.type;
12315
- let cur = first;
12316
- const stack = [first];
12317
- if (first.type === 'tr') {
12318
- defaultSighash = SignatureHash.DEFAULT;
12319
- return {
12320
- txType: 'taproot',
12321
- type: 'tr',
12322
- last: first,
12323
- lastScript: prevOut.script,
12324
- defaultSighash,
12325
- sighash: input.sighashType || defaultSighash,
12326
- };
12327
- }
12328
- else {
12329
- if (first.type === 'wpkh' || first.type === 'wsh')
12330
- txType = 'segwit';
12331
- if (first.type === 'sh') {
12332
- if (!input.redeemScript)
12333
- throw new Error('inputType: sh without redeemScript');
12334
- let child = OutScript.decode(input.redeemScript);
12335
- if (child.type === 'wpkh' || child.type === 'wsh')
12336
- txType = 'segwit';
12337
- stack.push(child);
12338
- cur = child;
12339
- type += `-${child.type}`;
12340
- }
12341
- // wsh can be inside sh
12342
- if (cur.type === 'wsh') {
12343
- if (!input.witnessScript)
12344
- throw new Error('inputType: wsh without witnessScript');
12345
- let child = OutScript.decode(input.witnessScript);
12346
- if (child.type === 'wsh')
12347
- txType = 'segwit';
12348
- stack.push(child);
12349
- cur = child;
12350
- type += `-${child.type}`;
12351
- }
12352
- const last = stack[stack.length - 1];
12353
- if (last.type === 'sh' || last.type === 'wsh')
12354
- throw new Error('inputType: sh/wsh cannot be terminal type');
12355
- const lastScript = OutScript.encode(last);
12356
- const res = {
12357
- type,
12358
- txType,
12359
- last,
12360
- lastScript,
12361
- defaultSighash,
12362
- sighash: input.sighashType || defaultSighash,
12363
- };
12364
- if (txType === 'legacy' && !allowLegacyWitnessUtxo && !input.nonWitnessUtxo) {
12365
- throw new Error(`Transaction/sign: legacy input without nonWitnessUtxo, can result in attack that forces paying higher fees. Pass allowLegacyWitnessUtxo=true, if you sure`);
12366
- }
12367
- return res;
12368
- }
12369
- }
12370
- class Transaction {
12371
- constructor(opts = {}) {
12372
- this.global = {};
12373
- this.inputs = []; // use getInput()
12374
- this.outputs = []; // use getOutput()
12375
- const _opts = (this.opts = validateOpts(opts));
12376
- // Merge with global structure of PSBTv2
12377
- if (_opts.lockTime !== DEFAULT_LOCKTIME)
12378
- this.global.fallbackLocktime = _opts.lockTime;
12379
- this.global.txVersion = _opts.version;
12380
- }
12381
- // Import
12382
- static fromRaw(raw, opts = {}) {
12383
- const parsed = RawTx.decode(raw);
12384
- const tx = new Transaction({ ...opts, version: parsed.version, lockTime: parsed.lockTime });
12385
- for (const o of parsed.outputs)
12386
- tx.addOutput(o);
12387
- tx.outputs = parsed.outputs;
12388
- tx.inputs = parsed.inputs;
12389
- if (parsed.witnesses) {
12390
- for (let i = 0; i < parsed.witnesses.length; i++)
12391
- tx.inputs[i].finalScriptWitness = parsed.witnesses[i];
12392
- }
12393
- return tx;
12394
- }
12395
- // PSBT
12396
- static fromPSBT(psbt_, opts = {}) {
12397
- let parsed;
12398
- try {
12399
- parsed = RawPSBTV0.decode(psbt_);
12400
- }
12401
- catch (e0) {
12402
- try {
12403
- parsed = RawPSBTV2.decode(psbt_);
12404
- }
12405
- catch (e2) {
12406
- // Throw error for v0 parsing, since it popular, otherwise it would be shadowed by v2 error
12407
- throw e0;
12408
- }
12409
- }
12410
- const PSBTVersion = parsed.global.version || 0;
12411
- if (PSBTVersion !== 0 && PSBTVersion !== 2)
12412
- throw new Error(`Wrong PSBT version=${PSBTVersion}`);
12413
- const unsigned = parsed.global.unsignedTx;
12414
- const version = PSBTVersion === 0 ? unsigned?.version : parsed.global.txVersion;
12415
- const lockTime = PSBTVersion === 0 ? unsigned?.lockTime : parsed.global.fallbackLocktime;
12416
- const tx = new Transaction({ ...opts, version, lockTime, PSBTVersion });
12417
- // We need slice here, because otherwise
12418
- const inputCount = PSBTVersion === 0 ? unsigned?.inputs.length : parsed.global.inputCount;
12419
- tx.inputs = parsed.inputs.slice(0, inputCount).map((i, j) => validateInput({
12420
- finalScriptSig: EMPTY,
12421
- ...parsed.global.unsignedTx?.inputs[j],
12422
- ...i,
12423
- }));
12424
- const outputCount = PSBTVersion === 0 ? unsigned?.outputs.length : parsed.global.outputCount;
12425
- tx.outputs = parsed.outputs.slice(0, outputCount).map((i, j) => ({
12426
- ...i,
12427
- ...parsed.global.unsignedTx?.outputs[j],
12428
- }));
12429
- tx.global = { ...parsed.global, txVersion: version }; // just in case proprietary/unknown fields
12430
- if (lockTime !== DEFAULT_LOCKTIME)
12431
- tx.global.fallbackLocktime = lockTime;
12432
- return tx;
12433
- }
12434
- toPSBT(PSBTVersion = this.opts.PSBTVersion) {
12435
- if (PSBTVersion !== 0 && PSBTVersion !== 2)
12436
- throw new Error(`Wrong PSBT version=${PSBTVersion}`);
12437
- // if (PSBTVersion === 0 && this.inputs.length === 0) {
12438
- // throw new Error(
12439
- // 'PSBT version=0 export for transaction without inputs disabled, please use version=2. Please check `toPSBT` method for explanation.'
12440
- // );
12441
- // }
12442
- const inputs = this.inputs.map((i) => validateInput(cleanPSBTFields(PSBTVersion, PSBTInput, i)));
12443
- for (const inp of inputs) {
12444
- // Don't serialize empty fields
12445
- if (inp.partialSig && !inp.partialSig.length)
12446
- delete inp.partialSig;
12447
- if (inp.finalScriptSig && !inp.finalScriptSig.length)
12448
- delete inp.finalScriptSig;
12449
- if (inp.finalScriptWitness && !inp.finalScriptWitness.length)
12450
- delete inp.finalScriptWitness;
12451
- }
12452
- const outputs = this.outputs.map((i) => cleanPSBTFields(PSBTVersion, PSBTOutput, i));
12453
- const global = { ...this.global };
12454
- if (PSBTVersion === 0) {
12455
- /*
12456
- - Bitcoin raw transaction expects to have at least 1 input because it uses case with zero inputs as marker for SegWit
12457
- - this means we cannot serialize raw tx with zero inputs since it will be parsed as SegWit tx
12458
- - Parsing of PSBTv0 depends on unsignedTx (it looks for input count here)
12459
- - BIP-174 requires old serialization format (without witnesses) inside global, which solves this
12460
- */
12461
- global.unsignedTx = RawOldTx.decode(RawOldTx.encode({
12462
- version: this.version,
12463
- lockTime: this.lockTime,
12464
- inputs: this.inputs.map(inputBeforeSign).map((i) => ({
12465
- ...i,
12466
- finalScriptSig: EMPTY,
12467
- })),
12468
- outputs: this.outputs.map(outputBeforeSign),
12469
- }));
12470
- delete global.fallbackLocktime;
12471
- delete global.txVersion;
12472
- }
12473
- else {
12474
- global.version = PSBTVersion;
12475
- global.txVersion = this.version;
12476
- global.inputCount = this.inputs.length;
12477
- global.outputCount = this.outputs.length;
12478
- if (global.fallbackLocktime && global.fallbackLocktime === DEFAULT_LOCKTIME)
12479
- delete global.fallbackLocktime;
12480
- }
12481
- if (this.opts.bip174jsCompat) {
12482
- if (!inputs.length)
12483
- inputs.push({});
12484
- if (!outputs.length)
12485
- outputs.push({});
12486
- }
12487
- return (PSBTVersion === 0 ? RawPSBTV0 : RawPSBTV2).encode({
12488
- global,
12489
- inputs,
12490
- outputs,
12491
- });
12492
- }
12493
- // BIP370 lockTime (https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#determining-lock-time)
12494
- get lockTime() {
12495
- let height = DEFAULT_LOCKTIME;
12496
- let heightCnt = 0;
12497
- let time = DEFAULT_LOCKTIME;
12498
- let timeCnt = 0;
12499
- for (const i of this.inputs) {
12500
- if (i.requiredHeightLocktime) {
12501
- height = Math.max(height, i.requiredHeightLocktime);
12502
- heightCnt++;
12503
- }
12504
- if (i.requiredTimeLocktime) {
12505
- time = Math.max(time, i.requiredTimeLocktime);
12506
- timeCnt++;
12507
- }
12508
- }
12509
- if (heightCnt && heightCnt >= timeCnt)
12510
- return height;
12511
- if (time !== DEFAULT_LOCKTIME)
12512
- return time;
12513
- return this.global.fallbackLocktime || DEFAULT_LOCKTIME;
12514
- }
12515
- get version() {
12516
- // Should be not possible
12517
- if (this.global.txVersion === undefined)
12518
- throw new Error('No global.txVersion');
12519
- return this.global.txVersion;
12520
- }
12521
- inputStatus(idx) {
12522
- this.checkInputIdx(idx);
12523
- const input = this.inputs[idx];
12524
- // Finalized
12525
- if (input.finalScriptSig && input.finalScriptSig.length)
12526
- return 'finalized';
12527
- if (input.finalScriptWitness && input.finalScriptWitness.length)
12528
- return 'finalized';
12529
- // Signed taproot
12530
- if (input.tapKeySig)
12531
- return 'signed';
12532
- if (input.tapScriptSig && input.tapScriptSig.length)
12533
- return 'signed';
12534
- // Signed
12535
- if (input.partialSig && input.partialSig.length)
12536
- return 'signed';
12537
- return 'unsigned';
12538
- }
12539
- // Cannot replace unpackSighash, tests rely on very generic implemenetation with signing inputs outside of range
12540
- // We will lose some vectors -> smaller test coverage of preimages (very important!)
12541
- inputSighash(idx) {
12542
- this.checkInputIdx(idx);
12543
- const inputSighash = this.inputs[idx].sighashType;
12544
- const sighash = inputSighash === undefined ? SignatureHash.DEFAULT : inputSighash;
12545
- // ALL or DEFAULT -- everything signed
12546
- // NONE -- all inputs + no outputs
12547
- // SINGLE -- all inputs + output with same index
12548
- // ALL + ANYONE -- specific input + all outputs
12549
- // NONE + ANYONE -- specific input + no outputs
12550
- // SINGLE -- specific inputs + output with same index
12551
- const sigOutputs = sighash === SignatureHash.DEFAULT ? SignatureHash.ALL : sighash & 0b11;
12552
- const sigInputs = sighash & SignatureHash.ANYONECANPAY;
12553
- return { sigInputs, sigOutputs };
12554
- }
12555
- // Very nice for debug purposes, but slow. If there is too much inputs/outputs to add, will be quadratic.
12556
- // Some cache will be nice, but there chance to have bugs with cache invalidation
12557
- signStatus() {
12558
- // if addInput or addOutput is not possible, then all inputs or outputs are signed
12559
- let addInput = true, addOutput = true;
12560
- let inputs = [], outputs = [];
12561
- for (let idx = 0; idx < this.inputs.length; idx++) {
12562
- const status = this.inputStatus(idx);
12563
- // Unsigned input doesn't affect anything
12564
- if (status === 'unsigned')
12565
- continue;
12566
- const { sigInputs, sigOutputs } = this.inputSighash(idx);
12567
- // Input type
12568
- if (sigInputs === SignatureHash.ANYONECANPAY)
12569
- inputs.push(idx);
12570
- else
12571
- addInput = false;
12572
- // Output type
12573
- if (sigOutputs === SignatureHash.ALL)
12574
- addOutput = false;
12575
- else if (sigOutputs === SignatureHash.SINGLE)
12576
- outputs.push(idx);
12577
- else if (sigOutputs === SignatureHash.NONE) ;
12578
- else
12579
- throw new Error(`Wrong signature hash output type: ${sigOutputs}`);
12580
- }
12581
- return { addInput, addOutput, inputs, outputs };
12582
- }
12583
- get isFinal() {
12584
- for (let idx = 0; idx < this.inputs.length; idx++)
12585
- if (this.inputStatus(idx) !== 'finalized')
12586
- return false;
12587
- return true;
12588
- }
12589
- // Info utils
12590
- get hasWitnesses() {
12591
- let out = false;
12592
- for (const i of this.inputs)
12593
- if (i.finalScriptWitness && i.finalScriptWitness.length)
12594
- out = true;
12595
- return out;
12596
- }
12597
- // https://en.bitcoin.it/wiki/Weight_units
12598
- get weight() {
12599
- if (!this.isFinal)
12600
- throw new Error('Transaction is not finalized');
12601
- let out = 32;
12602
- // Outputs
12603
- const outputs = this.outputs.map(outputBeforeSign);
12604
- out += 4 * CompactSizeLen.encode(this.outputs.length).length;
12605
- for (const o of outputs)
12606
- out += 32 + 4 * VarBytes.encode(o.script).length;
12607
- // Inputs
12608
- if (this.hasWitnesses)
12609
- out += 2;
12610
- out += 4 * CompactSizeLen.encode(this.inputs.length).length;
12611
- for (const i of this.inputs) {
12612
- out += 160 + 4 * VarBytes.encode(i.finalScriptSig || EMPTY).length;
12613
- if (this.hasWitnesses && i.finalScriptWitness)
12614
- out += RawWitness.encode(i.finalScriptWitness).length;
12615
- }
12616
- return out;
12617
- }
12618
- get vsize() {
12619
- return toVsize(this.weight);
12620
- }
12621
- toBytes(withScriptSig = false, withWitness = false) {
12622
- return RawTx.encode({
12623
- version: this.version,
12624
- lockTime: this.lockTime,
12625
- inputs: this.inputs.map(inputBeforeSign).map((i) => ({
12626
- ...i,
12627
- finalScriptSig: (withScriptSig && i.finalScriptSig) || EMPTY,
12628
- })),
12629
- outputs: this.outputs.map(outputBeforeSign),
12630
- witnesses: this.inputs.map((i) => i.finalScriptWitness || []),
12631
- segwitFlag: withWitness && this.hasWitnesses,
12632
- });
12633
- }
12634
- get unsignedTx() {
12635
- return this.toBytes(false, false);
12636
- }
12637
- get hex() {
12638
- return hex.encode(this.toBytes(true, this.hasWitnesses));
12639
- }
12640
- get hash() {
12641
- if (!this.isFinal)
12642
- throw new Error('Transaction is not finalized');
12643
- return hex.encode(sha256x2(this.toBytes(true)));
12644
- }
12645
- get id() {
12646
- if (!this.isFinal)
12647
- throw new Error('Transaction is not finalized');
12648
- return hex.encode(sha256x2(this.toBytes(true)).reverse());
12649
- }
12650
- // Input stuff
12651
- checkInputIdx(idx) {
12652
- if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.inputs.length)
12653
- throw new Error(`Wrong input index=${idx}`);
12654
- }
12655
- getInput(idx) {
12656
- this.checkInputIdx(idx);
12657
- return cloneDeep(this.inputs[idx]);
12658
- }
12659
- get inputsLength() {
12660
- return this.inputs.length;
12661
- }
12662
- // Modification
12663
- addInput(input, _ignoreSignStatus = false) {
12664
- if (!_ignoreSignStatus && !this.signStatus().addInput)
12665
- throw new Error('Tx has signed inputs, cannot add new one');
12666
- this.inputs.push(normalizeInput(input, undefined, undefined, this.opts.disableScriptCheck));
12667
- return this.inputs.length - 1;
12668
- }
12669
- updateInput(idx, input, _ignoreSignStatus = false) {
12670
- this.checkInputIdx(idx);
12671
- let allowedFields = undefined;
12672
- if (!_ignoreSignStatus) {
12673
- const status = this.signStatus();
12674
- if (!status.addInput || status.inputs.includes(idx))
12675
- allowedFields = PSBTInputUnsignedKeys;
12676
- }
12677
- this.inputs[idx] = normalizeInput(input, this.inputs[idx], allowedFields, this.opts.disableScriptCheck, this.opts.allowUnknown);
12678
- }
12679
- // Output stuff
12680
- checkOutputIdx(idx) {
12681
- if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.outputs.length)
12682
- throw new Error(`Wrong output index=${idx}`);
12683
- }
12684
- getOutput(idx) {
12685
- this.checkOutputIdx(idx);
12686
- return cloneDeep(this.outputs[idx]);
12687
- }
12688
- getOutputAddress(idx, network = NETWORK) {
12689
- const out = this.getOutput(idx);
12690
- if (!out.script)
12691
- return;
12692
- return Address(network).encode(OutScript.decode(out.script));
12693
- }
12694
- get outputsLength() {
12695
- return this.outputs.length;
12696
- }
12697
- normalizeOutput(o, cur, allowedFields) {
12698
- let { amount, script } = o;
12699
- if (amount === undefined)
12700
- amount = cur?.amount;
12701
- if (typeof amount !== 'bigint')
12702
- throw new Error(`Wrong amount type, should be of type bigint in sats, but got ${amount} of type ${typeof amount}`);
12703
- if (typeof script === 'string')
12704
- script = hex.decode(script);
12705
- if (script === undefined)
12706
- script = cur?.script;
12707
- let res = { ...cur, ...o, amount, script };
12708
- if (res.amount === undefined)
12709
- delete res.amount;
12710
- res = mergeKeyMap(PSBTOutput, res, cur, allowedFields, this.opts.allowUnknown);
12711
- PSBTOutputCoder.encode(res);
12712
- if (res.script &&
12713
- !this.opts.allowUnknownOutputs &&
12714
- OutScript.decode(res.script).type === 'unknown') {
12715
- throw new Error('Transaction/output: unknown output script type, there is a chance that input is unspendable. Pass allowUnknownOutputs=true, if you sure');
12716
- }
12717
- if (!this.opts.disableScriptCheck)
12718
- checkScript(res.script, res.redeemScript, res.witnessScript);
12719
- return res;
12720
- }
12721
- addOutput(o, _ignoreSignStatus = false) {
12722
- if (!_ignoreSignStatus && !this.signStatus().addOutput)
12723
- throw new Error('Tx has signed outputs, cannot add new one');
12724
- this.outputs.push(this.normalizeOutput(o));
12725
- return this.outputs.length - 1;
12726
- }
12727
- updateOutput(idx, output, _ignoreSignStatus = false) {
12728
- this.checkOutputIdx(idx);
12729
- let allowedFields = undefined;
12730
- if (!_ignoreSignStatus) {
12731
- const status = this.signStatus();
12732
- if (!status.addOutput || status.outputs.includes(idx))
12733
- allowedFields = PSBTOutputUnsignedKeys;
12734
- }
12735
- this.outputs[idx] = this.normalizeOutput(output, this.outputs[idx], allowedFields);
12736
- }
12737
- addOutputAddress(address, amount, network = NETWORK) {
12738
- return this.addOutput({ script: OutScript.encode(Address(network).decode(address)), amount });
12739
- }
12740
- // Utils
12741
- get fee() {
12742
- let res = 0n;
12743
- for (const i of this.inputs) {
12744
- const prevOut = getPrevOut(i);
12745
- if (!prevOut)
12746
- throw new Error('Empty input amount');
12747
- res += prevOut.amount;
12748
- }
12749
- const outputs = this.outputs.map(outputBeforeSign);
12750
- for (const o of outputs)
12751
- res -= o.amount;
12752
- return res;
12753
- }
12754
- // Signing
12755
- // Based on https://github.com/bitcoin/bitcoin/blob/5871b5b5ab57a0caf9b7514eb162c491c83281d5/test/functional/test_framework/script.py#L624
12756
- // There is optimization opportunity to re-use hashes for multiple inputs for witness v0/v1,
12757
- // but we are trying to be less complicated for audit purpose for now.
12758
- preimageLegacy(idx, prevOutScript, hashType) {
12759
- const { isAny, isNone, isSingle } = unpackSighash(hashType);
12760
- if (idx < 0 || !Number.isSafeInteger(idx))
12761
- throw new Error(`Invalid input idx=${idx}`);
12762
- if ((isSingle && idx >= this.outputs.length) || idx >= this.inputs.length)
12763
- return U256BE.encode(1n);
12764
- prevOutScript = Script.encode(Script.decode(prevOutScript).filter((i) => i !== 'CODESEPARATOR'));
12765
- let inputs = this.inputs
12766
- .map(inputBeforeSign)
12767
- .map((input, inputIdx) => ({
12768
- ...input,
12769
- finalScriptSig: inputIdx === idx ? prevOutScript : EMPTY,
12770
- }));
12771
- if (isAny)
12772
- inputs = [inputs[idx]];
12773
- else if (isNone || isSingle) {
12774
- inputs = inputs.map((input, inputIdx) => ({
12775
- ...input,
12776
- sequence: inputIdx === idx ? input.sequence : 0,
12777
- }));
12778
- }
12779
- let outputs = this.outputs.map(outputBeforeSign);
12780
- if (isNone)
12781
- outputs = [];
12782
- else if (isSingle) {
12783
- outputs = outputs.slice(0, idx).fill(EMPTY_OUTPUT).concat([outputs[idx]]);
12784
- }
12785
- const tmpTx = RawTx.encode({
12786
- lockTime: this.lockTime,
12787
- version: this.version,
12788
- segwitFlag: false,
12789
- inputs,
12790
- outputs,
12791
- });
12792
- return sha256x2(tmpTx, I32LE.encode(hashType));
12793
- }
12794
- preimageWitnessV0(idx, prevOutScript, hashType, amount) {
12795
- const { isAny, isNone, isSingle } = unpackSighash(hashType);
12796
- let inputHash = EMPTY32;
12797
- let sequenceHash = EMPTY32;
12798
- let outputHash = EMPTY32;
12799
- const inputs = this.inputs.map(inputBeforeSign);
12800
- const outputs = this.outputs.map(outputBeforeSign);
12801
- if (!isAny)
12802
- inputHash = sha256x2(...inputs.map(TxHashIdx.encode));
12803
- if (!isAny && !isSingle && !isNone)
12804
- sequenceHash = sha256x2(...inputs.map((i) => U32LE.encode(i.sequence)));
12805
- if (!isSingle && !isNone) {
12806
- outputHash = sha256x2(...outputs.map(RawOutput.encode));
12807
- }
12808
- else if (isSingle && idx < outputs.length)
12809
- outputHash = sha256x2(RawOutput.encode(outputs[idx]));
12810
- const input = inputs[idx];
12811
- return sha256x2(I32LE.encode(this.version), inputHash, sequenceHash, createBytes(32, true).encode(input.txid), U32LE.encode(input.index), VarBytes.encode(prevOutScript), U64LE.encode(amount), U32LE.encode(input.sequence), outputHash, U32LE.encode(this.lockTime), U32LE.encode(hashType));
12812
- }
12813
- preimageWitnessV1(idx, prevOutScript, hashType, amount, codeSeparator = -1, leafScript, leafVer = 0xc0, annex) {
12814
- if (!Array.isArray(amount) || this.inputs.length !== amount.length)
12815
- throw new Error(`Invalid amounts array=${amount}`);
12816
- if (!Array.isArray(prevOutScript) || this.inputs.length !== prevOutScript.length)
12817
- throw new Error(`Invalid prevOutScript array=${prevOutScript}`);
12818
- const out = [
12819
- U8.encode(0),
12820
- U8.encode(hashType), // U8 sigHash
12821
- I32LE.encode(this.version),
12822
- U32LE.encode(this.lockTime),
12823
- ];
12824
- const outType = hashType === SignatureHash.DEFAULT ? SignatureHash.ALL : hashType & 0b11;
12825
- const inType = hashType & SignatureHash.ANYONECANPAY;
12826
- const inputs = this.inputs.map(inputBeforeSign);
12827
- const outputs = this.outputs.map(outputBeforeSign);
12828
- if (inType !== SignatureHash.ANYONECANPAY) {
12829
- out.push(...[
12830
- inputs.map(TxHashIdx.encode),
12831
- amount.map(U64LE.encode),
12832
- prevOutScript.map(VarBytes.encode),
12833
- inputs.map((i) => U32LE.encode(i.sequence)),
12834
- ].map((i) => sha256$1(concatBytes(...i))));
12835
- }
12836
- if (outType === SignatureHash.ALL) {
12837
- out.push(sha256$1(concatBytes(...outputs.map(RawOutput.encode))));
12838
- }
12839
- const spendType = (annex ? 1 : 0) | (leafScript ? 2 : 0);
12840
- out.push(new Uint8Array([spendType]));
12841
- if (inType === SignatureHash.ANYONECANPAY) {
12842
- const inp = inputs[idx];
12843
- out.push(TxHashIdx.encode(inp), U64LE.encode(amount[idx]), VarBytes.encode(prevOutScript[idx]), U32LE.encode(inp.sequence));
12844
- }
12845
- else
12846
- out.push(U32LE.encode(idx));
12847
- if (spendType & 1)
12848
- out.push(sha256$1(VarBytes.encode(annex || EMPTY)));
12849
- if (outType === SignatureHash.SINGLE)
12850
- out.push(idx < outputs.length ? sha256$1(RawOutput.encode(outputs[idx])) : EMPTY32);
12851
- if (leafScript)
12852
- out.push(tapLeafHash(leafScript, leafVer), U8.encode(0), I32LE.encode(codeSeparator));
12853
- return tagSchnorr('TapSighash', ...out);
12854
- }
12855
- // Signer can be privateKey OR instance of bip32 HD stuff
12856
- signIdx(privateKey, idx, allowedSighash, _auxRand) {
12857
- this.checkInputIdx(idx);
12858
- const input = this.inputs[idx];
12859
- const inputType = getInputType(input, this.opts.allowLegacyWitnessUtxo);
12860
- // Handle BIP32 HDKey
12861
- if (!isBytes(privateKey)) {
12862
- if (!input.bip32Derivation || !input.bip32Derivation.length)
12863
- throw new Error('bip32Derivation: empty');
12864
- const signers = input.bip32Derivation
12865
- .filter((i) => i[1].fingerprint == privateKey.fingerprint)
12866
- .map(([pubKey, { path }]) => {
12867
- let s = privateKey;
12868
- for (const i of path)
12869
- s = s.deriveChild(i);
12870
- if (!equalBytes(s.publicKey, pubKey))
12871
- throw new Error('bip32Derivation: wrong pubKey');
12872
- if (!s.privateKey)
12873
- throw new Error('bip32Derivation: no privateKey');
12874
- return s;
12875
- });
12876
- if (!signers.length)
12877
- throw new Error(`bip32Derivation: no items with fingerprint=${privateKey.fingerprint}`);
12878
- let signed = false;
12879
- for (const s of signers)
12880
- if (this.signIdx(s.privateKey, idx))
12881
- signed = true;
12882
- return signed;
12883
- }
12884
- // Sighash checks
12885
- // Just for compat with bitcoinjs-lib, so users won't face unexpected behaviour.
12886
- if (!allowedSighash)
12887
- allowedSighash = [inputType.defaultSighash];
12888
- else
12889
- allowedSighash.forEach(validateSigHash);
12890
- const sighash = inputType.sighash;
12891
- if (!allowedSighash.includes(sighash)) {
12892
- throw new Error(`Input with not allowed sigHash=${sighash}. Allowed: ${allowedSighash.join(', ')}`);
12893
- }
12894
- // It is possible to sign these inputs for legacy/segwit v0 (but no taproot!),
12895
- // however this was because of bug in bitcoin-core, which remains here because of consensus.
12896
- // If this is absolutely neccessary for your case, please open issue.
12897
- // We disable it to avoid complicated workflow where SINGLE will block adding new outputs
12898
- const { sigOutputs } = this.inputSighash(idx);
12899
- if (sigOutputs === SignatureHash.SINGLE && idx >= this.outputs.length) {
12900
- throw new Error(`Input with sighash SINGLE, but there is no output with corresponding index=${idx}`);
12901
- }
12902
- // Actual signing
12903
- // Taproot
12904
- const prevOut = getPrevOut(input);
12905
- if (inputType.txType === 'taproot') {
12906
- const prevOuts = this.inputs.map(getPrevOut);
12907
- const prevOutScript = prevOuts.map((i) => i.script);
12908
- const amount = prevOuts.map((i) => i.amount);
12909
- let signed = false;
12910
- let schnorrPub = pubSchnorr(privateKey);
12911
- let merkleRoot = input.tapMerkleRoot || EMPTY;
12912
- if (input.tapInternalKey) {
12913
- // internal + tweak = tweaked key
12914
- // if internal key == current public key, we need to tweak private key,
12915
- // otherwise sign as is. bitcoinjs implementation always wants tweaked
12916
- // priv key to be provided
12917
- const { pubKey, privKey } = getTaprootKeys(privateKey, schnorrPub, input.tapInternalKey, merkleRoot);
12918
- const [taprootPubKey, _] = taprootTweakPubkey(input.tapInternalKey, merkleRoot);
12919
- if (equalBytes(taprootPubKey, pubKey)) {
12920
- const hash = this.preimageWitnessV1(idx, prevOutScript, sighash, amount);
12921
- const sig = concatBytes(signSchnorr(hash, privKey, _auxRand), sighash !== SignatureHash.DEFAULT ? new Uint8Array([sighash]) : EMPTY);
12922
- this.updateInput(idx, { tapKeySig: sig }, true);
12923
- signed = true;
12924
- }
12925
- }
12926
- if (input.tapLeafScript) {
12927
- input.tapScriptSig = input.tapScriptSig || [];
12928
- for (const [_, _script] of input.tapLeafScript) {
12929
- const script = _script.subarray(0, -1);
12930
- const scriptDecoded = Script.decode(script);
12931
- const ver = _script[_script.length - 1];
12932
- const hash = tapLeafHash(script, ver);
12933
- // NOTE: no need to tweak internal key here, since we don't support nested p2tr
12934
- const pos = scriptDecoded.findIndex((i) => isBytes(i) && equalBytes(i, schnorrPub));
12935
- // Skip if there is no public key in tapLeafScript
12936
- if (pos === -1)
12937
- continue;
12938
- const msg = this.preimageWitnessV1(idx, prevOutScript, sighash, amount, undefined, script, ver);
12939
- const sig = concatBytes(signSchnorr(msg, privateKey, _auxRand), sighash !== SignatureHash.DEFAULT ? new Uint8Array([sighash]) : EMPTY);
12940
- this.updateInput(idx, { tapScriptSig: [[{ pubKey: schnorrPub, leafHash: hash }, sig]] }, true);
12941
- signed = true;
12942
- }
12943
- }
12944
- if (!signed)
12945
- throw new Error('No taproot scripts signed');
12946
- return true;
12947
- }
12948
- else {
12949
- // only compressed keys are supported for now
12950
- const pubKey = pubECDSA(privateKey);
12951
- // TODO: replace with explicit checks
12952
- // Check if script has public key or its has inside
12953
- let hasPubkey = false;
12954
- const pubKeyHash = hash160(pubKey);
12955
- for (const i of Script.decode(inputType.lastScript)) {
12956
- if (isBytes(i) && (equalBytes(i, pubKey) || equalBytes(i, pubKeyHash)))
12957
- hasPubkey = true;
12958
- }
12959
- if (!hasPubkey)
12960
- throw new Error(`Input script doesn't have pubKey: ${inputType.lastScript}`);
12961
- let hash;
12962
- if (inputType.txType === 'legacy') {
12963
- hash = this.preimageLegacy(idx, inputType.lastScript, sighash);
12964
- }
12965
- else if (inputType.txType === 'segwit') {
12966
- let script = inputType.lastScript;
12967
- // If wpkh OR sh-wpkh, wsh-wpkh is impossible, so looks ok
12968
- if (inputType.last.type === 'wpkh')
12969
- script = OutScript.encode({ type: 'pkh', hash: inputType.last.hash });
12970
- hash = this.preimageWitnessV0(idx, script, sighash, prevOut.amount);
12971
- }
12972
- else
12973
- throw new Error(`Transaction/sign: unknown tx type: ${inputType.txType}`);
12974
- const sig = signECDSA(hash, privateKey, this.opts.lowR);
12975
- this.updateInput(idx, {
12976
- partialSig: [[pubKey, concatBytes(sig, new Uint8Array([sighash]))]],
12977
- }, true);
12978
- }
12979
- return true;
12980
- }
12981
- // This is bad API. Will work if user creates and signs tx, but if
12982
- // there is some complex workflow with exchanging PSBT and signing them,
12983
- // then it is better to validate which output user signs. How could a better API look like?
12984
- // Example: user adds input, sends to another party, then signs received input (mixer etc),
12985
- // another user can add different input for same key and user will sign it.
12986
- // Even worse: another user can add bip32 derivation, and spend money from different address.
12987
- // Better api: signIdx
12988
- sign(privateKey, allowedSighash, _auxRand) {
12989
- let num = 0;
12990
- for (let i = 0; i < this.inputs.length; i++) {
12991
- try {
12992
- if (this.signIdx(privateKey, i, allowedSighash, _auxRand))
12993
- num++;
12994
- }
12995
- catch (e) { }
12996
- }
12997
- if (!num)
12998
- throw new Error('No inputs signed');
12999
- return num;
13000
- }
13001
- finalizeIdx(idx) {
13002
- this.checkInputIdx(idx);
13003
- if (this.fee < 0n)
13004
- throw new Error('Outputs spends more than inputs amount');
13005
- const input = this.inputs[idx];
13006
- const inputType = getInputType(input, this.opts.allowLegacyWitnessUtxo);
13007
- // Taproot finalize
13008
- if (inputType.txType === 'taproot') {
13009
- if (input.tapKeySig)
13010
- input.finalScriptWitness = [input.tapKeySig];
13011
- else if (input.tapLeafScript && input.tapScriptSig) {
13012
- // Sort leafs by control block length.
13013
- const leafs = input.tapLeafScript.sort((a, b) => TaprootControlBlock.encode(a[0]).length -
13014
- TaprootControlBlock.encode(b[0]).length);
13015
- for (const [cb, _script] of leafs) {
13016
- // Last byte is version
13017
- const script = _script.slice(0, -1);
13018
- const ver = _script[_script.length - 1];
13019
- const outScript = OutScript.decode(script);
13020
- const hash = tapLeafHash(script, ver);
13021
- const scriptSig = input.tapScriptSig.filter((i) => equalBytes(i[0].leafHash, hash));
13022
- let signatures = [];
13023
- if (outScript.type === 'tr_ms') {
13024
- const m = outScript.m;
13025
- const pubkeys = outScript.pubkeys;
13026
- let added = 0;
13027
- for (const pub of pubkeys) {
13028
- const sigIdx = scriptSig.findIndex((i) => equalBytes(i[0].pubKey, pub));
13029
- // Should have exact amount of signatures (more -- will fail)
13030
- if (added === m || sigIdx === -1) {
13031
- signatures.push(EMPTY);
13032
- continue;
13033
- }
13034
- signatures.push(scriptSig[sigIdx][1]);
13035
- added++;
13036
- }
13037
- // Should be exact same as m
13038
- if (added !== m)
13039
- continue;
13040
- }
13041
- else if (outScript.type === 'tr_ns') {
13042
- for (const pub of outScript.pubkeys) {
13043
- const sigIdx = scriptSig.findIndex((i) => equalBytes(i[0].pubKey, pub));
13044
- if (sigIdx === -1)
13045
- continue;
13046
- signatures.push(scriptSig[sigIdx][1]);
13047
- }
13048
- if (signatures.length !== outScript.pubkeys.length)
13049
- continue;
13050
- }
13051
- else if (outScript.type === 'unknown' && this.opts.allowUnknownInputs) {
13052
- // Trying our best to sign what we can
13053
- const scriptDecoded = Script.decode(script);
13054
- signatures = scriptSig
13055
- .map(([{ pubKey }, signature]) => {
13056
- const pos = scriptDecoded.findIndex((i) => isBytes(i) && equalBytes(i, pubKey));
13057
- if (pos === -1)
13058
- throw new Error('finalize/taproot: cannot find position of pubkey in script');
13059
- return { signature, pos };
13060
- })
13061
- // Reverse order (because witness is stack and we take last element first from it)
13062
- .sort((a, b) => a.pos - b.pos)
13063
- .map((i) => i.signature);
13064
- if (!signatures.length)
13065
- continue;
13066
- }
13067
- else {
13068
- const custom = this.opts.customScripts;
13069
- if (custom) {
13070
- for (const c of custom) {
13071
- if (!c.finalizeTaproot)
13072
- continue;
13073
- const scriptDecoded = Script.decode(script);
13074
- const csEncoded = c.encode(scriptDecoded);
13075
- if (csEncoded === undefined)
13076
- continue;
13077
- const finalized = c.finalizeTaproot(script, csEncoded, scriptSig);
13078
- if (!finalized)
13079
- continue;
13080
- input.finalScriptWitness = finalized.concat(TaprootControlBlock.encode(cb));
13081
- input.finalScriptSig = EMPTY;
13082
- cleanFinalInput(input);
13083
- return;
13084
- }
13085
- }
13086
- throw new Error('Finalize: Unknown tapLeafScript');
13087
- }
13088
- // Witness is stack, so last element will be used first
13089
- input.finalScriptWitness = signatures
13090
- .reverse()
13091
- .concat([script, TaprootControlBlock.encode(cb)]);
13092
- break;
13093
- }
13094
- if (!input.finalScriptWitness)
13095
- throw new Error('finalize/taproot: empty witness');
13096
- }
13097
- else
13098
- throw new Error('finalize/taproot: unknown input');
13099
- input.finalScriptSig = EMPTY;
13100
- cleanFinalInput(input);
13101
- return;
13102
- }
13103
- if (!input.partialSig || !input.partialSig.length)
13104
- throw new Error('Not enough partial sign');
13105
- let inputScript = EMPTY;
13106
- let witness = [];
13107
- // TODO: move input scripts closer to payments/output scripts
13108
- // Multisig
13109
- if (inputType.last.type === 'ms') {
13110
- const m = inputType.last.m;
13111
- const pubkeys = inputType.last.pubkeys;
13112
- let signatures = [];
13113
- // partial: [pubkey, sign]
13114
- for (const pub of pubkeys) {
13115
- const sign = input.partialSig.find((s) => equalBytes(pub, s[0]));
13116
- if (!sign)
13117
- continue;
13118
- signatures.push(sign[1]);
13119
- }
13120
- signatures = signatures.slice(0, m);
13121
- if (signatures.length !== m) {
13122
- throw new Error(`Multisig: wrong signatures count, m=${m} n=${pubkeys.length} signatures=${signatures.length}`);
13123
- }
13124
- inputScript = Script.encode([0, ...signatures]);
13125
- }
13126
- else if (inputType.last.type === 'pk') {
13127
- inputScript = Script.encode([input.partialSig[0][1]]);
13128
- }
13129
- else if (inputType.last.type === 'pkh') {
13130
- inputScript = Script.encode([input.partialSig[0][1], input.partialSig[0][0]]);
13131
- }
13132
- else if (inputType.last.type === 'wpkh') {
13133
- inputScript = EMPTY;
13134
- witness = [input.partialSig[0][1], input.partialSig[0][0]];
13135
- }
13136
- else if (inputType.last.type === 'unknown' && !this.opts.allowUnknownInputs)
13137
- throw new Error('Unknown inputs not allowed');
13138
- // Create final scripts (generic part)
13139
- let finalScriptSig, finalScriptWitness;
13140
- if (inputType.type.includes('wsh-')) {
13141
- // P2WSH
13142
- if (inputScript.length && inputType.lastScript.length) {
13143
- witness = Script.decode(inputScript).map((i) => {
13144
- if (i === 0)
13145
- return EMPTY;
13146
- if (isBytes(i))
13147
- return i;
13148
- throw new Error(`Wrong witness op=${i}`);
13149
- });
13150
- }
13151
- witness = witness.concat(inputType.lastScript);
13152
- }
13153
- if (inputType.txType === 'segwit')
13154
- finalScriptWitness = witness;
13155
- if (inputType.type.startsWith('sh-wsh-')) {
13156
- finalScriptSig = Script.encode([Script.encode([0, sha256$1(inputType.lastScript)])]);
13157
- }
13158
- else if (inputType.type.startsWith('sh-')) {
13159
- finalScriptSig = Script.encode([...Script.decode(inputScript), inputType.lastScript]);
13160
- }
13161
- else if (inputType.type.startsWith('wsh-')) ;
13162
- else if (inputType.txType !== 'segwit')
13163
- finalScriptSig = inputScript;
13164
- if (!finalScriptSig && !finalScriptWitness)
13165
- throw new Error('Unknown error finalizing input');
13166
- if (finalScriptSig)
13167
- input.finalScriptSig = finalScriptSig;
13168
- if (finalScriptWitness)
13169
- input.finalScriptWitness = finalScriptWitness;
13170
- cleanFinalInput(input);
13171
- }
13172
- finalize() {
13173
- for (let i = 0; i < this.inputs.length; i++)
13174
- this.finalizeIdx(i);
13175
- }
13176
- extract() {
13177
- if (!this.isFinal)
13178
- throw new Error('Transaction has unfinalized inputs');
13179
- if (!this.outputs.length)
13180
- throw new Error('Transaction has no outputs');
13181
- if (this.fee < 0n)
13182
- throw new Error('Outputs spends more than inputs amount');
13183
- return this.toBytes(true, true);
13184
- }
13185
- combine(other) {
13186
- for (const k of ['PSBTVersion', 'version', 'lockTime']) {
13187
- if (this.opts[k] !== other.opts[k]) {
13188
- throw new Error(`Transaction/combine: different ${k} this=${this.opts[k]} other=${other.opts[k]}`);
13189
- }
13190
- }
13191
- for (const k of ['inputs', 'outputs']) {
13192
- if (this[k].length !== other[k].length) {
13193
- throw new Error(`Transaction/combine: different ${k} length this=${this[k].length} other=${other[k].length}`);
13194
- }
13195
- }
13196
- const thisUnsigned = this.global.unsignedTx ? RawOldTx.encode(this.global.unsignedTx) : EMPTY;
13197
- const otherUnsigned = other.global.unsignedTx
13198
- ? RawOldTx.encode(other.global.unsignedTx)
13199
- : EMPTY;
13200
- if (!equalBytes(thisUnsigned, otherUnsigned))
13201
- throw new Error(`Transaction/combine: different unsigned tx`);
13202
- this.global = mergeKeyMap(PSBTGlobal, this.global, other.global, undefined, this.opts.allowUnknown);
13203
- for (let i = 0; i < this.inputs.length; i++)
13204
- this.updateInput(i, other.inputs[i], true);
13205
- for (let i = 0; i < this.outputs.length; i++)
13206
- this.updateOutput(i, other.outputs[i], true);
13207
- return this;
13208
- }
13209
- clone() {
13210
- // deepClone probably faster, but this enforces that encoding is valid
13211
- return Transaction.fromPSBT(this.toPSBT(this.opts.PSBTVersion), this.opts);
13212
- }
13213
- }
13214
-
13215
- function decode_psbt(b64str) {
13216
- const psbt = Base64.decode(b64str);
13217
- return Transaction.fromPSBT(psbt, { allowUnknownOutputs: true });
13218
- }
13219
- function encode_psbt(psbt) {
13220
- const psbt_bytes = psbt.toPSBT(0);
13221
- return Base64.encode(psbt_bytes);
13222
- }
13223
- function parse_psbt(psbt) {
13224
- if (psbt instanceof Transaction) {
13225
- return psbt;
13226
- }
13227
- else if (typeof psbt === 'string') {
13228
- return decode_psbt(psbt);
13229
- }
13230
- else {
13231
- throw new Error('invalid psbt input: ' + psbt);
13232
- }
13233
- }
13234
-
13235
- function collect_vins(psbt) {
13236
- const pdata = parse_psbt(psbt);
13237
- const count = pdata.inputsLength;
13238
- const vins = [];
13239
- for (let i = 0; i < count; i++) {
13240
- const vin = pdata.getInput(i);
13241
- vins.push(vin);
13242
- }
13243
- return vins;
13244
- }
13245
- function collect_vouts(psbt) {
13246
- const pdata = parse_psbt(psbt);
13247
- const count = pdata.outputsLength;
13248
- const vouts = [];
13249
- for (let i = 0; i < count; i++) {
13250
- const vout = pdata.getOutput(i);
13251
- vouts.push(vout);
13252
- }
13253
- return vouts;
13254
- }
13255
- function collect_prevouts(psbt) {
13256
- const amounts = [], scripts = [];
13257
- const pdata = parse_psbt(psbt);
13258
- for (let i = 0; i < pdata.inputsLength; i++) {
13259
- const txin = pdata.getInput(i);
13260
- Assert.exists(txin.witnessUtxo, `witness utxo does not exist for input ${i}`);
13261
- amounts.push(txin.witnessUtxo.amount);
13262
- scripts.push(txin.witnessUtxo.script);
13263
- }
13264
- return { amounts, scripts };
13265
- }
13266
- function finalize_legacy_inputs(pdata) {
13267
- for (let i = 0; i < pdata.inputsLength; i++) {
13268
- const pvin = pdata.getInput(i);
13269
- const script = pvin.redeemScript;
13270
- const psig = pvin.partialSig?.at(0);
13271
- if (script !== undefined && psig !== undefined) {
13272
- pdata.finalizeIdx(i);
13273
- }
13274
- }
13275
- return pdata;
13276
- }
13277
-
13278
- function get_vsize$1(psbt) {
13279
- const pdata = parse_psbt(psbt);
13280
- return pdata.vsize;
13281
- }
13282
- function get_txhex(psbt) {
13283
- let pdata = parse_psbt(psbt);
13284
- pdata = finalize_legacy_inputs(pdata);
13285
- return pdata.hex;
13286
- }
13287
-
13288
- function assert_psbt_is_funded(psbt) {
13289
- const pdata = parse_psbt(psbt);
13290
- const pvouts = collect_vins(pdata);
13291
- const txouts = collect_vouts(pdata);
13292
- const vin_amt = pvouts.reduce((p, n) => p + Number(n.witnessUtxo?.amount ?? 0), 0);
13293
- const out_amt = txouts.reduce((p, n) => p + Number(n.amount ?? 0), 0);
13294
- Assert.ok(vin_amt >= out_amt, `value in (${vin_amt}) < value out (${out_amt})`);
13295
- }
13296
-
13297
- var index$7 = /*#__PURE__*/Object.freeze({
13298
- __proto__: null,
13299
- assert_psbt_is_funded: assert_psbt_is_funded,
13300
- collect_prevouts: collect_prevouts,
13301
- collect_vins: collect_vins,
13302
- collect_vouts: collect_vouts,
13303
- decode_psbt: decode_psbt,
13304
- encode_psbt: encode_psbt,
13305
- finalize_legacy_inputs: finalize_legacy_inputs,
13306
- get_txhex: get_txhex,
13307
- get_vsize: get_vsize$1,
13308
- parse_psbt: parse_psbt
13309
- });
13310
-
13311
- function prefix_script_size(script) {
13312
- return Buff.bytes(script).prefix_varint('le').hex;
13313
- }
13314
- function parse_script_pubkeys(script) {
13315
- const scriptHex = typeof script === 'string' ? script : Buff.bytes(script).hex;
13316
- const pubkeyPattern = /20([0-9a-f]{64})(ac|ad|ba)/gi;
13317
- const matches = [...scriptHex.matchAll(pubkeyPattern)];
13318
- return matches.map(match => match[1]);
13319
- }
13320
-
13321
- var ScriptUtil;
13322
- (function (ScriptUtil) {
13323
- ScriptUtil.prefix_size = prefix_script_size;
13324
- ScriptUtil.decode = decode_script;
13325
- ScriptUtil.encode = encode_script;
13326
- ScriptUtil.is_valid = is_valid_script;
13327
- ScriptUtil.get_pubkeys = parse_script_pubkeys;
13328
- ScriptUtil.OPCODES = OPCODE_MAP;
13329
- })(ScriptUtil || (ScriptUtil = {}));
13330
-
13331
- var index$6 = /*#__PURE__*/Object.freeze({
13332
- __proto__: null,
13333
- OPCODE_MAP: OPCODE_MAP,
13334
- get ScriptUtil () { return ScriptUtil; },
13335
- decode_script: decode_script,
13336
- encode_script: encode_script,
13337
- encode_script_word: encode_script_word,
13338
- get_asm_code: get_asm_code,
13339
- get_op_code: get_op_code,
13340
- get_op_type: get_op_type,
13341
- get_size_varint: get_size_varint,
13342
- is_valid_op: is_valid_op,
13343
- is_valid_script: is_valid_script,
13344
- parse_script_pubkeys: parse_script_pubkeys,
13345
- prefix_script_size: prefix_script_size,
13346
- prefix_word_size: prefix_word_size,
13347
- split_script_word: split_script_word
13348
- });
13349
-
13350
- function get_prevout(vin) {
13351
- Assert.exists(vin.prevout, 'Prevout data missing for input: ' + String(vin.txid));
13352
- return vin.prevout;
13353
- }
13354
- function parse_txinput(txdata, config) {
13355
- let { txindex, txinput } = config ?? {};
13356
- if (txindex !== undefined) {
13357
- if (txindex >= txdata.vin.length) {
13358
- throw new Error('Input index out of bounds: ' + String(txindex));
13359
- }
13360
- txinput = txdata.vin.at(txindex);
13361
- }
13362
- Assert.ok(txinput !== undefined);
13363
- return txinput;
13364
- }
13365
- function get_annex_data(witness) {
13366
- if (witness === undefined)
13367
- return;
13368
- if (witness.length < 2)
13369
- return;
13370
- const annex = witness.at(-1);
13371
- if (typeof annex === 'string' && annex.startsWith('50')) {
13372
- const bytes = Buff.hex(annex).prefix_varint('be');
13373
- return sha256(bytes);
13374
- }
13375
- return undefined;
13376
- }
13377
-
13378
- const COINBASE = {
13379
- TXID: '00'.repeat(32),
13380
- VOUT: 0xFFFFFFFF,
13381
- };
13382
- const DEFAULT = {
13383
- LOCKTIME: 0,
13384
- SEQUENCE: 0xFFFFFFFF,
13385
- VERSION: 2,
9443
+ const DEFAULT = {
9444
+ LOCKTIME: 0,
9445
+ SEQUENCE: 0xFFFFFFFF,
9446
+ VERSION: 2,
13386
9447
  };
13387
9448
  const TAPLEAF_VERSIONS = [
13388
9449
  0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce,
@@ -13440,19 +9501,19 @@ var taproot = /*#__PURE__*/Object.freeze({
13440
9501
  taptree: taptree
13441
9502
  });
13442
9503
 
13443
- const sats = bigIntType().positive().max(2100000000000000n);
9504
+ const sats = bigIntType().min(0n).max(2100000000000000n);
13444
9505
  const tx_output = objectType({
13445
9506
  value: sats,
13446
- script_pk: hex$1,
9507
+ script_pk: hex,
13447
9508
  });
13448
9509
  const tx_input = objectType({
13449
- coinbase: hex$1.nullable(),
9510
+ coinbase: hex.nullable(),
13450
9511
  txid: hex32,
13451
9512
  vout: uint,
13452
9513
  prevout: tx_output.nullable(),
13453
- script_sig: hex$1.nullable(),
9514
+ script_sig: hex.nullable(),
13454
9515
  sequence: uint,
13455
- witness: arrayType(hex$1)
9516
+ witness: arrayType(hex)
13456
9517
  });
13457
9518
  const tx_data = objectType({
13458
9519
  version: uint,
@@ -13464,16 +9525,16 @@ const vout_template = tx_output.extend({
13464
9525
  value: unionType([uint, sats])
13465
9526
  });
13466
9527
  const vin_template = tx_input.extend({
13467
- coinbase: hex$1.nullable().optional(),
9528
+ coinbase: hex.nullable().optional(),
13468
9529
  prevout: vout_template.nullable().optional(),
13469
- script_sig: hex$1.nullable().optional(),
13470
- sequence: unionType([hex$1, uint]).optional(),
13471
- witness: arrayType(hex$1).optional(),
9530
+ script_sig: hex.nullable().optional(),
9531
+ sequence: unionType([hex, uint]).optional(),
9532
+ witness: arrayType(hex).optional(),
13472
9533
  });
13473
9534
  const tx_template = objectType({
13474
- version: uint.default(1),
13475
- vin: arrayType(vin_template).default([]),
13476
- vout: arrayType(vout_template).default([]),
9535
+ version: uint.optional(),
9536
+ vin: arrayType(vin_template),
9537
+ vout: arrayType(vout_template),
13477
9538
  locktime: uint.optional(),
13478
9539
  });
13479
9540
 
@@ -13972,7 +10033,7 @@ function hash_segwit_tx(txdata, options = {}) {
13972
10033
  }
13973
10034
  let { pubkey, script } = options;
13974
10035
  if (script === undefined && pubkey !== undefined) {
13975
- const pkhash = hash160$1(pubkey).hex;
10036
+ const pkhash = hash160(pubkey).hex;
13976
10037
  script = `76a914${String(pkhash)}88ac`;
13977
10038
  }
13978
10039
  if (script === undefined) {
@@ -14403,6 +10464,7 @@ function create_taproot(config$1) {
14403
10464
  const cblock = Buff.join(block);
14404
10465
  return {
14405
10466
  int_key: Buff.bytes(pubkey).hex,
10467
+ path,
14406
10468
  parity,
14407
10469
  taproot: taproot ?? null,
14408
10470
  cblock: cblock.hex,
@@ -14459,5 +10521,5 @@ var index = /*#__PURE__*/Object.freeze({
14459
10521
  parse_witness: parse_witness
14460
10522
  });
14461
10523
 
14462
- export { index$9 as ADDRESS, _const as CONST, index$8 as META, index$7 as PSBT, index$5 as SCHEMA, index$6 as SCRIPT, index$3 as SIGHASH, index$2 as SIGNER, index$1 as TAPROOT, index$4 as TX, index as WITNESS };
10524
+ export { index$8 as ADDRESS, _const as CONST, index$7 as META, index$5 as SCHEMA, index$6 as SCRIPT, index$3 as SIGHASH, index$2 as SIGNER, index$1 as TAPROOT, index$4 as TX, index as WITNESS };
14463
10525
  //# sourceMappingURL=module.mjs.map