@did-btcr2/method 0.32.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +25 -13
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/browser.js +332 -582
  4. package/dist/browser.mjs +332 -582
  5. package/dist/cjs/index.js +213 -35
  6. package/dist/esm/core/aggregation/beacon-strategy.js +5 -4
  7. package/dist/esm/core/aggregation/beacon-strategy.js.map +1 -1
  8. package/dist/esm/core/aggregation/runner/aggregation-runner.js +66 -0
  9. package/dist/esm/core/aggregation/runner/aggregation-runner.js.map +1 -0
  10. package/dist/esm/core/aggregation/runner/index.js +1 -0
  11. package/dist/esm/core/aggregation/runner/index.js.map +1 -1
  12. package/dist/esm/core/aggregation/transport/in-memory.js +146 -0
  13. package/dist/esm/core/aggregation/transport/in-memory.js.map +1 -0
  14. package/dist/esm/core/aggregation/transport/index.js +1 -0
  15. package/dist/esm/core/aggregation/transport/index.js.map +1 -1
  16. package/dist/esm/core/beacon/beacon.js +10 -8
  17. package/dist/esm/core/beacon/beacon.js.map +1 -1
  18. package/dist/esm/core/beacon/cas-beacon.js +4 -4
  19. package/dist/esm/core/beacon/cas-beacon.js.map +1 -1
  20. package/dist/esm/core/beacon/factory.js +1 -1
  21. package/dist/esm/core/beacon/singleton-beacon.js +4 -4
  22. package/dist/esm/core/beacon/singleton-beacon.js.map +1 -1
  23. package/dist/esm/core/beacon/smt-beacon.js +23 -15
  24. package/dist/esm/core/beacon/smt-beacon.js.map +1 -1
  25. package/dist/esm/core/resolver.js +7 -4
  26. package/dist/esm/core/resolver.js.map +1 -1
  27. package/dist/types/core/aggregation/beacon-strategy.d.ts.map +1 -1
  28. package/dist/types/core/aggregation/runner/aggregation-runner.d.ts +56 -0
  29. package/dist/types/core/aggregation/runner/aggregation-runner.d.ts.map +1 -0
  30. package/dist/types/core/aggregation/runner/index.d.ts +1 -0
  31. package/dist/types/core/aggregation/runner/index.d.ts.map +1 -1
  32. package/dist/types/core/aggregation/transport/in-memory.d.ts +64 -0
  33. package/dist/types/core/aggregation/transport/in-memory.d.ts.map +1 -0
  34. package/dist/types/core/aggregation/transport/index.d.ts +1 -0
  35. package/dist/types/core/aggregation/transport/index.d.ts.map +1 -1
  36. package/dist/types/core/beacon/beacon.d.ts +12 -10
  37. package/dist/types/core/beacon/beacon.d.ts.map +1 -1
  38. package/dist/types/core/beacon/cas-beacon.d.ts +4 -4
  39. package/dist/types/core/beacon/cas-beacon.d.ts.map +1 -1
  40. package/dist/types/core/beacon/factory.d.ts +3 -3
  41. package/dist/types/core/beacon/factory.d.ts.map +1 -1
  42. package/dist/types/core/beacon/singleton-beacon.d.ts +4 -4
  43. package/dist/types/core/beacon/singleton-beacon.d.ts.map +1 -1
  44. package/dist/types/core/beacon/smt-beacon.d.ts +4 -4
  45. package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -1
  46. package/dist/types/core/interfaces.d.ts +14 -11
  47. package/dist/types/core/interfaces.d.ts.map +1 -1
  48. package/dist/types/core/resolver.d.ts +1 -1
  49. package/dist/types/core/resolver.d.ts.map +1 -1
  50. package/package.json +20 -8
  51. package/src/core/aggregation/beacon-strategy.ts +5 -4
  52. package/src/core/aggregation/runner/aggregation-runner.ts +96 -0
  53. package/src/core/aggregation/runner/index.ts +1 -0
  54. package/src/core/aggregation/transport/in-memory.ts +174 -0
  55. package/src/core/aggregation/transport/index.ts +1 -0
  56. package/src/core/beacon/beacon.ts +12 -10
  57. package/src/core/beacon/cas-beacon.ts +4 -4
  58. package/src/core/beacon/factory.ts +3 -3
  59. package/src/core/beacon/singleton-beacon.ts +4 -4
  60. package/src/core/beacon/smt-beacon.ts +24 -16
  61. package/src/core/interfaces.ts +14 -11
  62. package/src/core/resolver.ts +9 -6
package/dist/browser.mjs CHANGED
@@ -46575,11 +46575,11 @@ function padNumber(inputNumber, fullLength) {
46575
46575
  return "";
46576
46576
  }
46577
46577
  const dif = fullLength - str.length;
46578
- const padding3 = new Array(dif);
46578
+ const padding2 = new Array(dif);
46579
46579
  for (let i4 = 0; i4 < dif; i4++) {
46580
- padding3[i4] = "0";
46580
+ padding2[i4] = "0";
46581
46581
  }
46582
- const paddingString = padding3.join("");
46582
+ const paddingString = padding2.join("");
46583
46583
  return paddingString.concat(str);
46584
46584
  }
46585
46585
  var log22;
@@ -93252,32 +93252,6 @@ function join(separator = "") {
93252
93252
  };
93253
93253
  }
93254
93254
  // @__NO_SIDE_EFFECTS__
93255
- function padding(bits, chr = "=") {
93256
- anumber2(bits);
93257
- astr("padding", chr);
93258
- return {
93259
- encode(data) {
93260
- astrArr("padding.encode", data);
93261
- while (data.length * bits % 8)
93262
- data.push(chr);
93263
- return data;
93264
- },
93265
- decode(input) {
93266
- astrArr("padding.decode", input);
93267
- let end = input.length;
93268
- if (end * bits % 8)
93269
- throw new Error("padding: invalid, string should have whole number of bytes");
93270
- for (; end > 0 && input[end - 1] === chr; end--) {
93271
- const last = end - 1;
93272
- const byte = last * bits;
93273
- if (byte % 8 === 0)
93274
- throw new Error("padding: invalid, string has too much padding");
93275
- }
93276
- return input.slice(0, end);
93277
- }
93278
- };
93279
- }
93280
- // @__NO_SIDE_EFFECTS__
93281
93255
  function normalize(fn) {
93282
93256
  afn(fn);
93283
93257
  return { encode: (from8) => from8, decode: (to) => fn(to) };
@@ -93338,7 +93312,7 @@ var powers = /* @__PURE__ */ (() => {
93338
93312
  res.push(2 ** i4);
93339
93313
  return res;
93340
93314
  })();
93341
- function convertRadix2(data, from8, to, padding3) {
93315
+ function convertRadix2(data, from8, to, padding2) {
93342
93316
  aArr(data);
93343
93317
  if (from8 <= 0 || from8 > 32)
93344
93318
  throw new Error(`convertRadix2: wrong from=${from8}`);
@@ -93368,11 +93342,11 @@ function convertRadix2(data, from8, to, padding3) {
93368
93342
  carry &= pow3 - 1;
93369
93343
  }
93370
93344
  carry = carry << to - pos & mask;
93371
- if (!padding3 && pos >= from8)
93345
+ if (!padding2 && pos >= from8)
93372
93346
  throw new Error("Excess padding");
93373
- if (!padding3 && carry > 0)
93347
+ if (!padding2 && carry > 0)
93374
93348
  throw new Error(`Non-zero padding: ${carry}`);
93375
- if (padding3 && pos > 0)
93349
+ if (padding2 && pos > 0)
93376
93350
  res.push(carry >>> 0);
93377
93351
  return res;
93378
93352
  }
@@ -93446,24 +93420,6 @@ function checksum(len, fn) {
93446
93420
  }
93447
93421
  };
93448
93422
  }
93449
- var hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === "function" && typeof Uint8Array.fromBase64 === "function")();
93450
- var decodeBase64Builtin = (s2, isUrl) => {
93451
- astr("base64", s2);
93452
- const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;
93453
- const alphabet5 = isUrl ? "base64url" : "base64";
93454
- if (s2.length > 0 && !re.test(s2))
93455
- throw new Error("invalid base64");
93456
- return Uint8Array.fromBase64(s2, { alphabet: alphabet5, lastChunkHandling: "strict" });
93457
- };
93458
- var base64 = hasBase64Builtin ? {
93459
- encode(b) {
93460
- abytes2(b);
93461
- return b.toBase64();
93462
- },
93463
- decode(s2) {
93464
- return decodeBase64Builtin(s2, false);
93465
- }
93466
- } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join(""));
93467
93423
  var base64urlnopad = /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"), /* @__PURE__ */ join(""));
93468
93424
  var genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join(""));
93469
93425
  var base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
@@ -97898,7 +97854,7 @@ function join2(separator = "") {
97898
97854
  };
97899
97855
  }
97900
97856
  // @__NO_SIDE_EFFECTS__
97901
- function padding2(bits, chr = "=") {
97857
+ function padding(bits, chr = "=") {
97902
97858
  anumber4(bits);
97903
97859
  astr2("padding", chr);
97904
97860
  return {
@@ -97979,7 +97935,7 @@ var powers2 = /* @__PURE__ */ (() => {
97979
97935
  res.push(2 ** i4);
97980
97936
  return res;
97981
97937
  })();
97982
- function convertRadix22(data, from8, to, padding3) {
97938
+ function convertRadix22(data, from8, to, padding2) {
97983
97939
  aArr2(data);
97984
97940
  if (from8 <= 0 || from8 > 32)
97985
97941
  throw new Error(`convertRadix2: wrong from=${from8}`);
@@ -98009,11 +97965,11 @@ function convertRadix22(data, from8, to, padding3) {
98009
97965
  carry &= pow3 - 1;
98010
97966
  }
98011
97967
  carry = carry << to - pos & mask;
98012
- if (!padding3 && pos >= from8)
97968
+ if (!padding2 && pos >= from8)
98013
97969
  throw new Error("Excess padding");
98014
- if (!padding3 && carry > 0)
97970
+ if (!padding2 && carry > 0)
98015
97971
  throw new Error(`Non-zero padding: ${carry}`);
98016
- if (padding3 && pos > 0)
97972
+ if (padding2 && pos > 0)
98017
97973
  res.push(carry >>> 0);
98018
97974
  return res;
98019
97975
  }
@@ -98061,8 +98017,8 @@ function unsafeWrapper2(fn) {
98061
98017
  }
98062
98018
  };
98063
98019
  }
98064
- var hasBase64Builtin2 = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === "function" && typeof Uint8Array.fromBase64 === "function")();
98065
- var decodeBase64Builtin2 = (s2, isUrl) => {
98020
+ var hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === "function" && typeof Uint8Array.fromBase64 === "function")();
98021
+ var decodeBase64Builtin = (s2, isUrl) => {
98066
98022
  astr2("base64", s2);
98067
98023
  const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;
98068
98024
  const alphabet5 = isUrl ? "base64url" : "base64";
@@ -98070,15 +98026,15 @@ var decodeBase64Builtin2 = (s2, isUrl) => {
98070
98026
  throw new Error("invalid base64");
98071
98027
  return Uint8Array.fromBase64(s2, { alphabet: alphabet5, lastChunkHandling: "strict" });
98072
98028
  };
98073
- var base642 = hasBase64Builtin2 ? {
98029
+ var base64 = hasBase64Builtin ? {
98074
98030
  encode(b) {
98075
98031
  abytes4(b);
98076
98032
  return b.toBase64();
98077
98033
  },
98078
98034
  decode(s2) {
98079
- return decodeBase64Builtin2(s2, false);
98035
+ return decodeBase64Builtin(s2, false);
98080
98036
  }
98081
- } : /* @__PURE__ */ chain2(/* @__PURE__ */ radix22(6), /* @__PURE__ */ alphabet2("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding2(6), /* @__PURE__ */ join2(""));
98037
+ } : /* @__PURE__ */ chain2(/* @__PURE__ */ radix22(6), /* @__PURE__ */ alphabet2("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join2(""));
98082
98038
  var genBase582 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */ join2(""));
98083
98039
  var base582 = /* @__PURE__ */ genBase582("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
98084
98040
  var BECH_ALPHABET2 = /* @__PURE__ */ chain2(/* @__PURE__ */ alphabet2("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join2(""));
@@ -100334,125 +100290,25 @@ function hashToHex(hash3) {
100334
100290
  }
100335
100291
  return s2;
100336
100292
  }
100337
- function hexToHash(hex2) {
100338
- validateHex(hex2, true);
100339
- const hash3 = new Uint8Array(HASH_BYTE_LENGTH);
100340
- for (let i4 = 0; i4 < HASH_BYTE_LENGTH; i4++) {
100341
- hash3[i4] = Number.parseInt(hex2.substring(i4 * 2, i4 * 2 + 2), 16);
100342
- }
100343
- return hash3;
100344
- }
100345
- function bigIntToHex(value2, padded) {
100346
- const s2 = value2.toString(16);
100347
- return padded ? s2.padStart(HASH_HEX_LENGTH, "0") : s2;
100348
- }
100349
- function hexToBigInt(hex2, padded) {
100350
- validateHex(hex2, padded);
100351
- return BigInt(`0x${hex2}`);
100352
- }
100353
100293
  function hashesEqual(a2, b) {
100354
100294
  if (!isValidHash(a2) || !isValidHash(b))
100355
100295
  return false;
100356
100296
  return equalBytes(a2, b);
100357
100297
  }
100358
- function hashToBase64(hash3) {
100298
+ function hashToBase64Url(hash3) {
100359
100299
  validateHash(hash3);
100360
- return base64.encode(hash3);
100300
+ return base64urlnopad.encode(hash3);
100361
100301
  }
100362
- function base64ToHash(b64) {
100363
- const hash3 = base64.decode(b64);
100302
+ function base64UrlToHash(b64u) {
100303
+ const hash3 = base64urlnopad.decode(b64u);
100364
100304
  if (hash3.length !== HASH_BYTE_LENGTH) {
100365
- throw new RangeError(`Invalid base64 hash: expected ${HASH_BYTE_LENGTH} decoded bytes, got ${hash3.length}`);
100305
+ throw new RangeError(`Invalid base64url hash: expected ${HASH_BYTE_LENGTH} decoded bytes, got ${hash3.length}`);
100366
100306
  }
100367
100307
  return hash3;
100368
100308
  }
100369
- function bigIntToBase64(value2, padded) {
100370
- let bytes3 = bigIntToHash(value2);
100371
- if (!padded) {
100372
- const firstNonZero = bytes3.findIndex((b) => b !== 0);
100373
- bytes3 = firstNonZero === -1 ? new Uint8Array(1) : bytes3.slice(firstNonZero);
100374
- }
100375
- return base64.encode(bytes3);
100376
- }
100377
- function base64ToBigInt(b64, padded) {
100378
- const bytes3 = base64.decode(b64);
100379
- if (padded && bytes3.length !== HASH_BYTE_LENGTH) {
100380
- throw new RangeError(`Invalid padded base64 bigint: expected ${HASH_BYTE_LENGTH} decoded bytes, got ${bytes3.length}`);
100381
- }
100382
- if (bytes3.length > HASH_BYTE_LENGTH) {
100383
- throw new RangeError(`Value exceeds ${HASH_BYTE_LENGTH} bytes`);
100384
- }
100385
- let value2 = 0n;
100386
- for (const byte of bytes3) {
100387
- value2 = value2 << 8n | BigInt(byte);
100388
- }
100389
- return value2;
100390
- }
100391
- var HEX_RE = /^[0-9A-Fa-f]+$/;
100392
- function validateHex(s2, requireHashLength) {
100393
- const len = s2.length;
100394
- const minLen = requireHashLength ? HASH_HEX_LENGTH : 1;
100395
- if (len < minLen || len > HASH_HEX_LENGTH || !HEX_RE.test(s2)) {
100396
- throw new RangeError(`Invalid hex string: expected ${requireHashLength ? HASH_HEX_LENGTH : "1-" + HASH_HEX_LENGTH} hex characters, got ${len}`);
100397
- }
100398
- }
100399
100309
 
100400
100310
  // ../smt/dist/esm/node.js
100401
100311
  init_shim();
100402
- var BaseNode = class {
100403
- #index;
100404
- #depth;
100405
- constructor(index, depth) {
100406
- this.#index = index;
100407
- this.#depth = depth;
100408
- }
100409
- get index() {
100410
- return this.#index;
100411
- }
100412
- get depth() {
100413
- return this.#depth;
100414
- }
100415
- };
100416
- var LeafNode = class extends BaseNode {
100417
- #hash = null;
100418
- get hash() {
100419
- return this.#hash;
100420
- }
100421
- set hash(value2) {
100422
- if (this.#hash !== null) {
100423
- throw new RangeError("Leaf hash already set");
100424
- }
100425
- this.#hash = value2;
100426
- }
100427
- reset() {
100428
- this.#hash = null;
100429
- }
100430
- };
100431
- var ParentNode = class extends BaseNode {
100432
- #left;
100433
- #right;
100434
- constructor(index, depth, left, right) {
100435
- super(index, depth);
100436
- this.#left = left;
100437
- this.#right = right;
100438
- }
100439
- get left() {
100440
- return this.#left;
100441
- }
100442
- set left(node) {
100443
- this.#left = node;
100444
- }
100445
- get right() {
100446
- return this.#right;
100447
- }
100448
- set right(node) {
100449
- this.#right = node;
100450
- }
100451
- reset() {
100452
- this.#left.reset();
100453
- this.#right.reset();
100454
- }
100455
- };
100456
100312
 
100457
100313
  // ../smt/dist/esm/smt-proof.js
100458
100314
  init_shim();
@@ -100462,377 +100318,84 @@ var ValidationState;
100462
100318
  ValidationState2[ValidationState2["Valid"] = 1] = "Valid";
100463
100319
  ValidationState2[ValidationState2["Invalid"] = 2] = "Invalid";
100464
100320
  })(ValidationState || (ValidationState = {}));
100465
- var SMTProof = class _SMTProof {
100466
- #converge;
100467
- #hashes;
100468
- constructor(converge, hashes2) {
100469
- this.#converge = converge;
100470
- this.#hashes = hashes2;
100471
- }
100472
- /** Converge bitmap: bit `i` set means a sibling hash exists at depth `256 - i - 1`. */
100473
- get converge() {
100474
- return this.#converge;
100475
- }
100476
- /** Sibling hashes at converge points, ordered leaf-to-root. */
100477
- get hashes() {
100478
- return this.#hashes;
100479
- }
100480
- /**
100481
- * Verify this proof for a single leaf.
100482
- *
100483
- * @param index - Leaf index in the 256-bit key space.
100484
- * @param candidateHash - Expected leaf hash.
100485
- * @param rootHash - Expected root hash.
100486
- * @returns `true` if the proof is valid.
100487
- */
100488
- isValid(index, candidateHash, rootHash) {
100489
- return this.#validate(index, candidateHash, rootHash);
100490
- }
100491
- /**
100492
- * Batch-validate multiple proofs against the same root hash.
100493
- *
100494
- * Caches intermediate (partial) proofs so that subsequent candidates
100495
- * sharing an ancestor path can short-circuit once a cached match is found.
100496
- *
100497
- * @yields One {@link SMTProofResult} per candidate.
100498
- */
100499
- static *isValidBatch(candidates, rootHash) {
100500
- const cache4 = /* @__PURE__ */ new Map();
100501
- for (const candidate of candidates) {
100502
- const added = [];
100503
- const { index } = candidate;
100504
- const valid = candidate.proof.#validate(index | OUTER_BIT, candidate.hash, rootHash, (nodeIndex, partial) => {
100505
- const cached = cache4.get(nodeIndex);
100506
- if (cached === void 0) {
100507
- cache4.set(nodeIndex, partial);
100508
- added.push(nodeIndex);
100509
- return ValidationState.Pending;
100510
- }
100511
- if (hashesEqual(partial.hash, cached.hash) && partial.converge === cached.converge && partial.hashes.length === cached.hashes.length && partial.hashes.every((h, i4) => hashesEqual(h, cached.hashes[i4]))) {
100512
- return ValidationState.Valid;
100513
- }
100514
- return ValidationState.Invalid;
100515
- });
100516
- if (!valid) {
100517
- for (const key of added)
100518
- cache4.delete(key);
100519
- }
100520
- yield { index, valid, additional: candidate.additional };
100521
- }
100522
- }
100523
- /**
100524
- * Export to JSON.
100525
- * @param base64 - Use base64 encoding instead of hex (default: `false`).
100526
- * @param compact - Omit whitespace (default: `true`).
100527
- */
100528
- toJSON(base646 = false, compact = true) {
100529
- const convergeStr = base646 ? bigIntToBase64(this.#converge, false) : bigIntToHex(this.#converge, false);
100530
- const hashStrs = this.#hashes.map((h) => base646 ? hashToBase64(h) : hashToHex(h));
100531
- const obj = { converge: convergeStr, hashes: hashStrs };
100532
- return JSON.stringify(obj, null, compact ? 0 : 2);
100533
- }
100534
- /**
100535
- * Import from JSON.
100536
- * @param json - JSON string.
100537
- * @param base64 - Parse base64 instead of hex (default: `false`).
100538
- */
100539
- static fromJSON(json, base646 = false) {
100540
- const raw = JSON.parse(json);
100541
- if (typeof raw?.converge !== "string" || !Array.isArray(raw.hashes)) {
100542
- throw new RangeError("Invalid SMTProof JSON: expected { converge, hashes }");
100543
- }
100544
- const converge = base646 ? base64ToBigInt(raw.converge, false) : hexToBigInt(raw.converge, false);
100545
- const hashes2 = raw.hashes.map((h) => base646 ? base64ToHash(h) : hexToHash(h));
100546
- return new _SMTProof(converge, hashes2);
100547
- }
100548
- /**
100549
- * Export to compact binary format.
100550
- *
100551
- * Layout: `[convergeZeroCount : 1] [truncatedConverge : 32-zc] [hashCount : 1] [hashes : N*32]`
100552
- */
100553
- toBinary() {
100554
- const convergeBin = bigIntToHash(this.#converge);
100555
- let zc = 0;
100556
- while (zc < HASH_BYTE_LENGTH && convergeBin[zc] === 0)
100557
- zc++;
100558
- const truncated = convergeBin.slice(zc);
100559
- const hashCount = this.#hashes.length;
100560
- const totalBytes = 1 + truncated.length + 1 + hashCount * HASH_BYTE_LENGTH;
100561
- const out = new Uint8Array(totalBytes);
100562
- let pos = 0;
100563
- out[pos++] = zc;
100564
- out.set(truncated, pos);
100565
- pos += truncated.length;
100566
- out[pos++] = hashCount;
100567
- for (const h of this.#hashes) {
100568
- out.set(h, pos);
100569
- pos += HASH_BYTE_LENGTH;
100570
- }
100571
- return out;
100572
- }
100573
- /**
100574
- * Import from compact binary format.
100575
- * Accepts any sync or async byte iterable (e.g. `Uint8Array`, `ReadableStream`).
100576
- */
100577
- static async fromBinary(source) {
100578
- const iter = Symbol.iterator in source ? source[Symbol.iterator]() : source[Symbol.asyncIterator]();
100579
- async function readBytes(n2) {
100580
- const buf2 = new Uint8Array(n2);
100581
- for (let i4 = 0; i4 < n2; i4++) {
100582
- const r2 = await iter.next();
100583
- if (r2.done)
100584
- throw new Error("Unexpected end of binary source");
100585
- buf2[i4] = r2.value;
100586
- }
100587
- return buf2;
100588
- }
100589
- const zc = (await readBytes(1))[0];
100590
- const convergeBin = new Uint8Array(HASH_BYTE_LENGTH);
100591
- convergeBin.set(await readBytes(HASH_BYTE_LENGTH - zc), zc);
100592
- const hashCount = (await readBytes(1))[0];
100593
- const hashes2 = new Array(hashCount);
100594
- for (let i4 = 0; i4 < hashCount; i4++) {
100595
- hashes2[i4] = await readBytes(HASH_BYTE_LENGTH);
100596
- }
100597
- return new _SMTProof(hashToBigInt(convergeBin), hashes2);
100598
- }
100599
- #validate(index, candidateHash, rootHash, onMerge) {
100600
- let nodeIndex = index;
100601
- let nodeHash = candidateHash;
100602
- let remaining = this.#converge;
100603
- const hashes2 = this.#hashes;
100604
- let hi = 0;
100605
- const leftPad = [];
100606
- const rightPad = [];
100607
- const finalizePadding = () => {
100608
- if (leftPad.length > 0 || rightPad.length > 0) {
100609
- nodeHash = blockHash(new Uint8Array(leftPad), nodeHash, new Uint8Array(rightPad));
100610
- leftPad.length = 0;
100611
- rightPad.length = 0;
100612
- }
100613
- };
100614
- let state = ValidationState.Pending;
100615
- for (let i4 = 0; state === ValidationState.Pending && i4 < HASH_BIT_LENGTH; i4++) {
100616
- const isLeft = (nodeIndex & 1n) === 0n;
100617
- nodeIndex >>= 1n;
100618
- const bit = BITS[i4];
100619
- if ((remaining & bit) !== 0n) {
100620
- remaining ^= bit;
100621
- finalizePadding();
100622
- if (hi >= hashes2.length) {
100623
- state = ValidationState.Invalid;
100624
- } else {
100625
- const peer = hashes2[hi++];
100626
- nodeHash = isLeft ? blockHash(nodeHash, peer) : blockHash(peer, nodeHash);
100627
- if (onMerge !== void 0) {
100628
- state = onMerge(nodeIndex, {
100629
- hash: nodeHash,
100630
- converge: remaining,
100631
- hashes: hashes2.slice(hi)
100632
- });
100633
- }
100634
- }
100635
- } else {
100636
- const depth = HASH_BIT_LENGTH - i4 - 1;
100637
- if (isLeft) {
100638
- rightPad.push(depth);
100639
- } else {
100640
- leftPad.unshift(depth);
100641
- }
100642
- }
100643
- }
100644
- finalizePadding();
100645
- if (state === ValidationState.Pending) {
100646
- state = hi === hashes2.length && hashesEqual(nodeHash, rootHash) ? ValidationState.Valid : ValidationState.Invalid;
100647
- }
100648
- return state === ValidationState.Valid;
100649
- }
100650
- };
100651
100321
 
100652
100322
  // ../smt/dist/esm/optimized-smt.js
100653
100323
  init_shim();
100654
- var OptimizedSMT = class _OptimizedSMT {
100655
- /** `2^256` — sentinel bit above the key space. Used by batch validation. */
100656
- static OUTER_BIT = OUTER_BIT;
100657
- /** Pre-computed MSB-first bit masks for tree traversal. */
100658
- static BITS = BITS;
100659
- #allowNonInclusion;
100660
- #root = null;
100661
- #rootHash = null;
100662
- #proofs = /* @__PURE__ */ new Map();
100663
- constructor(allowNonInclusion) {
100664
- this.#allowNonInclusion = allowNonInclusion;
100665
- }
100666
- get allowNonInclusion() {
100667
- return this.#allowNonInclusion;
100668
- }
100669
- /** Root hash. Throws if tree has not been finalized. */
100670
- get rootHash() {
100671
- if (this.#rootHash === null)
100672
- throw new RangeError("SMT not finalized");
100673
- return this.#rootHash;
100324
+
100325
+ // ../smt/dist/esm/zero-hash.js
100326
+ init_shim();
100327
+ var TREE_DEPTH = HASH_BIT_LENGTH;
100328
+ function bitAt(index, position) {
100329
+ return Number(index >> BigInt(position) & 1n);
100330
+ }
100331
+ var CACHED_ZERO = (() => {
100332
+ const arr = new Array(TREE_DEPTH + 1);
100333
+ let z = new Uint8Array(HASH_BYTE_LENGTH);
100334
+ for (let h = 0; h <= TREE_DEPTH; h++) {
100335
+ z = blockHash(z, z);
100336
+ arr[h] = z;
100674
100337
  }
100675
- // -----------------------------------------------------------------------
100676
- // Build phase
100677
- // -----------------------------------------------------------------------
100678
- /**
100679
- * Add leaf indexes to the tree.
100680
- * May be called multiple times before finalization. Duplicate indexes throw.
100681
- */
100682
- add(indexes) {
100683
- this.#checkNotFinalized();
100684
- for (const index of indexes) {
100685
- if (index < 0n || index >= _OptimizedSMT.OUTER_BIT) {
100686
- throw new RangeError("Index out of range");
100687
- }
100688
- const leaf = new LeafNode(index, HASH_BIT_LENGTH);
100689
- if (this.#root === null) {
100690
- this.#root = leaf;
100338
+ return arr;
100339
+ })();
100340
+ function subtreeHash(leaves, height) {
100341
+ if (leaves.length === 0)
100342
+ return CACHED_ZERO[height];
100343
+ if (height === 0)
100344
+ return leaves[0].leaf;
100345
+ const bit = TREE_DEPTH - height;
100346
+ const left = [];
100347
+ const right = [];
100348
+ for (const e2 of leaves)
100349
+ (bitAt(e2.index, bit) === 0 ? left : right).push(e2);
100350
+ return blockHash(subtreeHash(left, height - 1), subtreeHash(right, height - 1));
100351
+ }
100352
+ function zeroHashRoot(leaves) {
100353
+ return subtreeHash(leaves, TREE_DEPTH);
100354
+ }
100355
+ function generateZeroHashProof(leaves, targetIndex) {
100356
+ let collapsed = 0n;
100357
+ const hashes2 = [];
100358
+ for (let height = 1; height <= TREE_DEPTH; height++) {
100359
+ const bit = TREE_DEPTH - height;
100360
+ const siblingLeaves = [];
100361
+ for (const e2 of leaves) {
100362
+ if (e2.index === targetIndex)
100691
100363
  continue;
100692
- }
100693
- let replaceNode = (node2) => {
100694
- this.#root = node2;
100695
- };
100696
- let node = this.#root;
100697
- let commonIndex = 0n;
100698
- let commonDepth = 0;
100699
- let done = false;
100700
- while (!done) {
100701
- const bit = BITS[commonDepth];
100702
- const indexBit = index & bit;
100703
- const isLeft = indexBit === 0n;
100704
- if (commonDepth === node.depth) {
100705
- if (node instanceof ParentNode) {
100706
- const parent = node;
100707
- if (isLeft) {
100708
- node = parent.left;
100709
- replaceNode = (n2) => {
100710
- parent.left = n2;
100711
- };
100712
- } else {
100713
- node = parent.right;
100714
- replaceNode = (n2) => {
100715
- parent.right = n2;
100716
- };
100717
- }
100718
- } else {
100719
- throw new RangeError("Duplicate index");
100720
- }
100721
- } else if ((node.index & bit) === indexBit) {
100722
- commonIndex |= indexBit;
100723
- commonDepth++;
100724
- } else {
100725
- replaceNode(new ParentNode(commonIndex, commonDepth, isLeft ? leaf : node, isLeft ? node : leaf));
100726
- done = true;
100364
+ let sharesLowerPath = true;
100365
+ for (let lower = 0; lower < bit; lower++) {
100366
+ if (bitAt(e2.index, lower) !== bitAt(targetIndex, lower)) {
100367
+ sharesLowerPath = false;
100368
+ break;
100727
100369
  }
100728
100370
  }
100371
+ if (sharesLowerPath && bitAt(e2.index, bit) !== bitAt(targetIndex, bit))
100372
+ siblingLeaves.push(e2);
100729
100373
  }
100730
- }
100731
- /**
100732
- * Set the hash for a leaf at the given index.
100733
- * The index must have been previously added via {@link add}.
100734
- * Each leaf's hash can only be set once (until {@link reset}).
100735
- */
100736
- setHash(index, hash3) {
100737
- this.#checkNotFinalized();
100738
- validateHash(hash3);
100739
- let node = this.#root;
100740
- if (node === null)
100741
- throw new RangeError("Empty SMT");
100742
- while (node instanceof ParentNode) {
100743
- node = (index & BITS[node.depth]) === 0n ? node.left : node.right;
100744
- }
100745
- if (node.index !== index)
100746
- throw new RangeError("Index not found");
100747
- node.hash = hash3;
100748
- }
100749
- // -----------------------------------------------------------------------
100750
- // Finalize phase
100751
- // -----------------------------------------------------------------------
100752
- /**
100753
- * Compute root hash and generate all proofs in a single recursive pass.
100754
- * Must be called after all hashes are set.
100755
- */
100756
- finalize() {
100757
- if (this.#root === null) {
100758
- this.#rootHash = NULL_HASH;
100759
- return;
100374
+ if (siblingLeaves.length === 0) {
100375
+ collapsed |= 1n << BigInt(bit);
100376
+ } else {
100377
+ hashes2.push(subtreeHash(siblingLeaves, height - 1));
100760
100378
  }
100761
- const result = this.#finalizeStep(this.#root, 0n, 0);
100762
- this.#rootHash = result.hash;
100763
- result.saveProofs([]);
100764
- }
100765
- /** Retrieve the proof for an index. Only valid after {@link finalize}. */
100766
- proof(index) {
100767
- const p2 = this.#proofs.get(index);
100768
- if (p2 === void 0)
100769
- throw new RangeError("Proof not found");
100770
- return p2;
100771
- }
100772
- /** Clear hashes and proofs, keeping the tree structure for reuse. */
100773
- reset() {
100774
- this.#root?.reset();
100775
- this.#rootHash = null;
100776
- this.#proofs.clear();
100777
- }
100778
- /**
100779
- * Check if the SMT has not been finalized yet.
100780
- * @throws {Error} If the SMT has already been finalized.
100781
- */
100782
- #checkNotFinalized() {
100783
- if (this.#rootHash !== null)
100784
- throw new Error("SMT already finalized");
100785
100379
  }
100786
- /**
100787
- * Perform a single step of finalization on the given node.
100788
- * @param {Node} node The node to finalize.
100789
- * @param {bigint} parentConverge The convergence value from the parent node.
100790
- * @param {number} depth The current depth in the tree.
100791
- * @returns {FinalizeStepResult} The result of the finalization step.
100792
- */
100793
- #finalizeStep(node, parentConverge, depth) {
100794
- const converge = parentConverge | BITS[HASH_BIT_LENGTH - depth];
100795
- let hash3;
100796
- let saveProofs;
100797
- if (node instanceof ParentNode) {
100798
- const childDepth = node.depth + 1;
100799
- const leftResult = this.#finalizeStep(node.left, converge, childDepth);
100800
- const rightResult = this.#finalizeStep(node.right, converge, childDepth);
100801
- hash3 = blockHash(leftResult.hash, rightResult.hash);
100802
- saveProofs = (hashes2) => {
100803
- const leftHashes = hashes2;
100804
- const rightHashes = hashes2.slice();
100805
- leftHashes.unshift(rightResult.hash);
100806
- rightHashes.unshift(leftResult.hash);
100807
- leftResult.saveProofs(leftHashes);
100808
- rightResult.saveProofs(rightHashes);
100809
- };
100380
+ return { collapsed, hashes: hashes2 };
100381
+ }
100382
+ function verifyZeroHash(collapsed, hashes2, index, candidate, root) {
100383
+ let acc = candidate;
100384
+ let hashPtr = 0;
100385
+ for (let n2 = 0; n2 < TREE_DEPTH; n2++) {
100386
+ const i4 = TREE_DEPTH - 1 - n2;
100387
+ let sibling;
100388
+ if ((collapsed >> BigInt(i4) & 1n) === 1n) {
100389
+ sibling = CACHED_ZERO[n2];
100810
100390
  } else {
100811
- if (node.hash === null) {
100812
- if (!this.#allowNonInclusion)
100813
- throw new RangeError("Hash missing");
100814
- node.hash = NULL_HASH;
100815
- }
100816
- hash3 = node.hash;
100817
- saveProofs = (hashes2) => {
100818
- this.#proofs.set(node.index, new SMTProof(converge, hashes2));
100819
- };
100820
- }
100821
- if (node.depth !== depth) {
100822
- const leftPad = [];
100823
- const rightPad = [];
100824
- for (let i4 = node.depth - 1; i4 >= depth; i4--) {
100825
- if ((node.index & BITS[i4]) === 0n) {
100826
- rightPad.push(i4);
100827
- } else {
100828
- leftPad.unshift(i4);
100829
- }
100830
- }
100831
- hash3 = blockHash(new Uint8Array(leftPad), hash3, new Uint8Array(rightPad));
100391
+ if (hashPtr >= hashes2.length)
100392
+ return false;
100393
+ sibling = hashes2[hashPtr++];
100832
100394
  }
100833
- return { hash: hash3, saveProofs };
100395
+ acc = bitAt(index, i4) === 1 ? blockHash(sibling, acc) : blockHash(acc, sibling);
100834
100396
  }
100835
- };
100397
+ return hashPtr === hashes2.length && hashesEqual(acc, root);
100398
+ }
100836
100399
 
100837
100400
  // ../smt/dist/esm/btcr2-leaf.js
100838
100401
  init_shim();
@@ -100849,51 +100412,53 @@ function nonInclusionLeafHash(nonce) {
100849
100412
 
100850
100413
  // ../smt/dist/esm/btcr2-proof.js
100851
100414
  init_shim();
100852
- function serializeProof(proof, rootHash, options2) {
100415
+ function serializeProof(rootHash, proof, options2) {
100853
100416
  const result = {
100854
- id: hashToHex(rootHash),
100855
- collapsed: bigIntToHex(proof.converge, false),
100856
- hashes: proof.hashes.map((h) => hashToHex(h))
100417
+ id: hashToBase64Url(rootHash),
100418
+ collapsed: hashToBase64Url(bigIntToHash(proof.collapsed)),
100419
+ hashes: proof.hashes.map((h) => hashToBase64Url(h))
100857
100420
  };
100858
100421
  if (options2?.nonce)
100859
- result.nonce = hashToHex(options2.nonce);
100422
+ result.nonce = hashToBase64Url(options2.nonce);
100860
100423
  if (options2?.updateId)
100861
- result.updateId = hashToHex(options2.updateId);
100424
+ result.updateId = hashToBase64Url(options2.updateId);
100862
100425
  return result;
100863
100426
  }
100864
100427
  function deserializeProof(serialized) {
100865
- const converge = hexToBigInt(serialized.collapsed, false);
100866
- const hashes2 = serialized.hashes.map((h) => hexToHash(h));
100867
100428
  const result = {
100868
- proof: new SMTProof(converge, hashes2),
100869
- rootHash: hexToHash(serialized.id)
100429
+ rootHash: base64UrlToHash(serialized.id),
100430
+ collapsed: hashToBigInt(base64UrlToHash(serialized.collapsed)),
100431
+ hashes: serialized.hashes.map((h) => base64UrlToHash(h))
100870
100432
  };
100871
100433
  if (serialized.nonce)
100872
- result.nonce = hexToHash(serialized.nonce);
100434
+ result.nonce = base64UrlToHash(serialized.nonce);
100873
100435
  if (serialized.updateId)
100874
- result.updateId = hexToHash(serialized.updateId);
100436
+ result.updateId = base64UrlToHash(serialized.updateId);
100875
100437
  return result;
100876
100438
  }
100877
100439
  function verifySerializedProof(serialized, index, candidateHash) {
100878
- const { proof, rootHash } = deserializeProof(serialized);
100879
- return proof.isValid(index, candidateHash, rootHash);
100440
+ const { rootHash, collapsed, hashes: hashes2 } = deserializeProof(serialized);
100441
+ return verifyZeroHash(collapsed, hashes2, index, candidateHash, rootHash);
100880
100442
  }
100881
100443
 
100882
100444
  // ../smt/dist/esm/btcr2-tree.js
100883
100445
  init_shim();
100884
100446
  var BTCR2MerkleTree = class {
100885
- #smt;
100886
100447
  #entries = /* @__PURE__ */ new Map();
100887
100448
  #indexByDid = /* @__PURE__ */ new Map();
100888
- constructor(allowNonInclusion = true) {
100889
- this.#smt = new OptimizedSMT(allowNonInclusion);
100449
+ #leaves = null;
100450
+ #root = null;
100451
+ /**
100452
+ * @param _allowNonInclusion Retained for API compatibility; non-inclusion
100453
+ * leaves are always supported (an entry without `signedUpdate`).
100454
+ */
100455
+ constructor(_allowNonInclusion = true) {
100890
100456
  }
100891
100457
  /**
100892
100458
  * Add entries to the tree. May be called multiple times before
100893
100459
  * {@link finalize}. Duplicate DIDs (same index) throw.
100894
100460
  */
100895
100461
  addEntries(entries) {
100896
- const indexes = [];
100897
100462
  for (const entry of entries) {
100898
100463
  const index = didToIndex(entry.did);
100899
100464
  if (this.#entries.has(index)) {
@@ -100901,24 +100466,28 @@ var BTCR2MerkleTree = class {
100901
100466
  }
100902
100467
  this.#entries.set(index, entry);
100903
100468
  this.#indexByDid.set(entry.did, index);
100904
- indexes.push(index);
100905
100469
  }
100906
- this.#smt.add(indexes);
100470
+ this.#leaves = null;
100471
+ this.#root = null;
100907
100472
  }
100908
100473
  /**
100909
- * Compute leaf hashes and finalize the tree.
100474
+ * Compute leaf hashes and the zero-hash root.
100910
100475
  * After this call, {@link rootHash} and {@link proof} become available.
100911
100476
  */
100912
100477
  finalize() {
100478
+ const leaves = [];
100913
100479
  for (const [index, entry] of this.#entries) {
100914
- const leafHash = entry.signedUpdate !== void 0 ? inclusionLeafHash(entry.nonce, entry.signedUpdate) : nonInclusionLeafHash(entry.nonce);
100915
- this.#smt.setHash(index, leafHash);
100480
+ const leaf = entry.signedUpdate !== void 0 ? inclusionLeafHash(entry.nonce, entry.signedUpdate) : nonInclusionLeafHash(entry.nonce);
100481
+ leaves.push({ index, leaf });
100916
100482
  }
100917
- this.#smt.finalize();
100483
+ this.#leaves = leaves;
100484
+ this.#root = zeroHashRoot(leaves);
100918
100485
  }
100919
100486
  /** Root hash of the finalized tree. Throws if not finalized. */
100920
100487
  get rootHash() {
100921
- return this.#smt.rootHash;
100488
+ if (this.#root === null)
100489
+ throw new Error("Tree not finalized: call finalize() first");
100490
+ return this.#root;
100922
100491
  }
100923
100492
  /**
100924
100493
  * Get the did:btcr2 serialized proof for a DID.
@@ -100928,14 +100497,18 @@ var BTCR2MerkleTree = class {
100928
100497
  const index = this.#indexByDid.get(did);
100929
100498
  if (index === void 0)
100930
100499
  throw new RangeError(`DID not in tree: ${did}`);
100500
+ if (this.#leaves === null || this.#root === null) {
100501
+ throw new Error("Tree not finalized: call finalize() first");
100502
+ }
100931
100503
  const entry = this.#entries.get(index);
100932
- const smtProof = this.#smt.proof(index);
100504
+ const proof = generateZeroHashProof(this.#leaves, index);
100933
100505
  const updateId = entry.signedUpdate !== void 0 ? blockHash(entry.signedUpdate) : void 0;
100934
- return serializeProof(smtProof, this.#smt.rootHash, { nonce: entry.nonce, updateId });
100506
+ return serializeProof(this.#root, proof, { nonce: entry.nonce, updateId });
100935
100507
  }
100936
- /** Clear hashes and proofs, keeping tree structure. Entries are preserved. */
100508
+ /** Clear computed leaves and root, keeping entries. */
100937
100509
  reset() {
100938
- this.#smt.reset();
100510
+ this.#leaves = null;
100511
+ this.#root = null;
100939
100512
  }
100940
100513
  };
100941
100514
 
@@ -100970,12 +100543,12 @@ var SMT_STRATEGY = {
100970
100543
  const smtProof = body.smtProof;
100971
100544
  if (!smtProof?.updateId || !smtProof?.nonce) return { matches: false };
100972
100545
  const canonicalBytes = new TextEncoder().encode(canonicalize2(submittedUpdate));
100973
- const expectedUpdateId = hashToHex(blockHash(canonicalBytes));
100546
+ const expectedUpdateId = hashToBase64Url(blockHash(canonicalBytes));
100974
100547
  if (smtProof.updateId !== expectedUpdateId) {
100975
100548
  return { matches: false, smtProof };
100976
100549
  }
100977
100550
  const index = didToIndex(participantDid);
100978
- const candidateHash = blockHash(blockHash(hexToHash(smtProof.nonce)), hexToHash(smtProof.updateId));
100551
+ const candidateHash = blockHash(blockHash(base64UrlToHash(smtProof.nonce)), base64UrlToHash(smtProof.updateId));
100979
100552
  return {
100980
100553
  matches: verifySerializedProof(smtProof, index, candidateHash),
100981
100554
  smtProof
@@ -108312,8 +107885,8 @@ function encrypt2(secretKey, pubkey, text) {
108312
107885
  let iv = Uint8Array.from(randomBytes2(16));
108313
107886
  let plaintext = utf8Encoder.encode(text);
108314
107887
  let ciphertext = cbc(normalizedKey, iv).encrypt(plaintext);
108315
- let ctb64 = base642.encode(new Uint8Array(ciphertext));
108316
- let ivb64 = base642.encode(new Uint8Array(iv.buffer));
107888
+ let ctb64 = base64.encode(new Uint8Array(ciphertext));
107889
+ let ivb64 = base64.encode(new Uint8Array(iv.buffer));
108317
107890
  return `${ctb64}?iv=${ivb64}`;
108318
107891
  }
108319
107892
  function decrypt2(secretKey, pubkey, data) {
@@ -108321,8 +107894,8 @@ function decrypt2(secretKey, pubkey, data) {
108321
107894
  let [ctb64, ivb64] = data.split("?iv=");
108322
107895
  let key = secp256k1.getSharedSecret(privkey, hexToBytes2("02" + pubkey));
108323
107896
  let normalizedKey = getNormalizedX(key);
108324
- let iv = base642.decode(ivb64);
108325
- let ciphertext = base642.decode(ctb64);
107897
+ let iv = base64.decode(ivb64);
107898
+ let ciphertext = base64.decode(ctb64);
108326
107899
  let plaintext = cbc(normalizedKey, iv).decrypt(ciphertext);
108327
107900
  return utf8Decoder.decode(plaintext);
108328
107901
  }
@@ -108642,7 +108215,7 @@ function decodePayload(payload) {
108642
108215
  throw new Error("unknown encryption version");
108643
108216
  let data;
108644
108217
  try {
108645
- data = base642.decode(payload);
108218
+ data = base64.decode(payload);
108646
108219
  } catch (error) {
108647
108220
  throw new Error("invalid base64: " + error.message);
108648
108221
  }
@@ -108663,7 +108236,7 @@ function encrypt22(plaintext, conversationKey, nonce = randomBytes2(32)) {
108663
108236
  const padded = pad(plaintext);
108664
108237
  const ciphertext = chacha20(chacha_key, chacha_nonce, padded);
108665
108238
  const mac = hmacAad(hmac_key, ciphertext, nonce);
108666
- return base642.encode(concatBytes2(new Uint8Array([2]), nonce, ciphertext, mac));
108239
+ return base64.encode(concatBytes2(new Uint8Array([2]), nonce, ciphertext, mac));
108667
108240
  }
108668
108241
  function decrypt22(payload, conversationKey) {
108669
108242
  const { nonce, ciphertext, mac } = decodePayload(payload);
@@ -109938,7 +109511,7 @@ async function getToken(loginUrl, httpMethod, sign, includeAuthorizationScheme =
109938
109511
  }
109939
109512
  const signedEvent = await sign(event);
109940
109513
  const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : "";
109941
- return authorizationScheme + base642.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
109514
+ return authorizationScheme + base64.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
109942
109515
  }
109943
109516
  async function validateToken(token, url, method) {
109944
109517
  const event = await unpackEventFromToken(token).catch((error) => {
@@ -109954,7 +109527,7 @@ async function unpackEventFromToken(token) {
109954
109527
  throw new Error("Missing token");
109955
109528
  }
109956
109529
  token = token.replace(_authorizationScheme, "");
109957
- const eventB64 = utf8Decoder.decode(base642.decode(token));
109530
+ const eventB64 = utf8Decoder.decode(base64.decode(token));
109958
109531
  if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith("{")) {
109959
109532
  throw new Error("Invalid token");
109960
109533
  }
@@ -111421,6 +110994,120 @@ var TransportFactory = class {
111421
110994
  }
111422
110995
  };
111423
110996
 
110997
+ // src/core/aggregation/transport/in-memory.ts
110998
+ init_shim();
110999
+ init_utils();
111000
+ var InMemoryBus = class {
111001
+ #transports = /* @__PURE__ */ new Set();
111002
+ /** Attach a transport to this bus. Called by the transport's constructor. */
111003
+ register(transport) {
111004
+ this.#transports.add(transport);
111005
+ }
111006
+ /** Detach a transport from this bus. */
111007
+ unregister(transport) {
111008
+ this.#transports.delete(transport);
111009
+ }
111010
+ /**
111011
+ * Deliver a message. With no `recipient` the message is broadcast to every
111012
+ * actor on the bus; otherwise it is routed to the single transport that owns
111013
+ * the recipient DID.
111014
+ */
111015
+ async deliver(message2, _sender, recipient) {
111016
+ const type = message2.type;
111017
+ if (!type) return;
111018
+ const replacer = (_k, v) => v instanceof Uint8Array ? { __bytes: bytesToHex(v) } : v;
111019
+ const reviver = (_k, v) => v && typeof v === "object" && "__bytes" in v ? hexToBytes(v.__bytes) : v;
111020
+ const raw = JSON.parse(JSON.stringify(message2, replacer), reviver);
111021
+ const serialized = { ...raw, ...raw.body ?? {} };
111022
+ if (!recipient) {
111023
+ for (const t2 of this.#transports) {
111024
+ await t2.dispatchBroadcast(type, serialized);
111025
+ }
111026
+ return;
111027
+ }
111028
+ for (const t2 of this.#transports) {
111029
+ if (t2.hasActor(recipient)) {
111030
+ await t2.dispatchDirected(recipient, type, serialized);
111031
+ return;
111032
+ }
111033
+ }
111034
+ }
111035
+ };
111036
+ var InMemoryTransport = class {
111037
+ name = "in-memory";
111038
+ bus;
111039
+ #actors = /* @__PURE__ */ new Map();
111040
+ #peers = /* @__PURE__ */ new Map();
111041
+ /** @param bus Shared bus. Pass the same bus to connect multiple transports. */
111042
+ constructor(bus = new InMemoryBus()) {
111043
+ this.bus = bus;
111044
+ this.bus.register(this);
111045
+ }
111046
+ start() {
111047
+ }
111048
+ registerActor(did, keys) {
111049
+ this.#actors.set(did, { keys, handlers: /* @__PURE__ */ new Map() });
111050
+ }
111051
+ getActorPk(did) {
111052
+ return this.#actors.get(did)?.keys.publicKey.compressed;
111053
+ }
111054
+ /** True if `did` is registered on this transport. Used by the bus for routing. */
111055
+ hasActor(did) {
111056
+ return this.#actors.has(did);
111057
+ }
111058
+ registerPeer(did, communicationPk) {
111059
+ this.#peers.set(did, communicationPk);
111060
+ }
111061
+ getPeerPk(did) {
111062
+ return this.#peers.get(did);
111063
+ }
111064
+ registerMessageHandler(actorDid, messageType, handler) {
111065
+ const actor = this.#actors.get(actorDid);
111066
+ if (actor) actor.handlers.set(messageType, handler);
111067
+ }
111068
+ unregisterMessageHandler(actorDid, messageType) {
111069
+ const actor = this.#actors.get(actorDid);
111070
+ if (actor) actor.handlers.delete(messageType);
111071
+ }
111072
+ unregisterActor(did) {
111073
+ const actor = this.#actors.get(did);
111074
+ if (!actor) return;
111075
+ actor.handlers.clear();
111076
+ this.#actors.delete(did);
111077
+ this.#peers.delete(did);
111078
+ }
111079
+ async sendMessage(message2, sender, recipient) {
111080
+ await this.bus.deliver(message2, sender, recipient);
111081
+ }
111082
+ publishRepeating(message2, sender, intervalMs, recipient) {
111083
+ let stopped = false;
111084
+ void this.sendMessage(message2, sender, recipient).catch(() => {
111085
+ });
111086
+ const timer = setInterval(() => {
111087
+ if (stopped) return;
111088
+ void this.sendMessage(message2, sender, recipient).catch(() => {
111089
+ });
111090
+ }, intervalMs);
111091
+ return () => {
111092
+ if (stopped) return;
111093
+ stopped = true;
111094
+ clearInterval(timer);
111095
+ };
111096
+ }
111097
+ /** Deliver a broadcast message to every actor on this transport that handles `type`. */
111098
+ async dispatchBroadcast(type, message2) {
111099
+ for (const actor of this.#actors.values()) {
111100
+ const handler = actor.handlers.get(type);
111101
+ if (handler) await handler(message2);
111102
+ }
111103
+ }
111104
+ /** Deliver a directed message to the recipient actor's handler for `type`. */
111105
+ async dispatchDirected(recipientDid, type, message2) {
111106
+ const handler = this.#actors.get(recipientDid)?.handlers.get(type);
111107
+ if (handler) await handler(message2);
111108
+ }
111109
+ };
111110
+
111424
111111
  // src/core/aggregation/transport/didcomm.ts
111425
111112
  init_shim();
111426
111113
  var DidCommTransport = class {
@@ -112161,6 +111848,63 @@ var AggregationParticipantRunner = class _AggregationParticipantRunner extends T
112161
111848
  }
112162
111849
  };
112163
111850
 
111851
+ // src/core/aggregation/runner/aggregation-runner.ts
111852
+ init_shim();
111853
+ var AggregationRunner = class {
111854
+ /**
111855
+ * Run a cohort of ONE participant entirely in-process and return the
111856
+ * aggregated MuSig2 result.
111857
+ *
111858
+ * One party plays both the coordinating service and the lone participant,
111859
+ * connected over an {@link InMemoryTransport} (no relay or HTTP server). This
111860
+ * makes the single-participant aggregate-beacon path — the N=1 corner of the
111861
+ * two-axis beacon matrix (see ADR 037) — first-class, useful for generating
111862
+ * and reproducing single-participant aggregate test vectors.
111863
+ *
111864
+ * The service advertises a cohort with `minParticipants: 1`; the participant
111865
+ * joins, submits its update, and the two complete keygen, data distribution,
111866
+ * validation, and a one-signer MuSig2 P2TR key-path signing round.
111867
+ *
111868
+ * @param options Service + participant identities, cohort config, and the
111869
+ * update / tx-data callbacks.
111870
+ * @returns The {@link AggregationResult} (cohort id, aggregated signature, signed tx).
111871
+ */
111872
+ static async solo(options2) {
111873
+ const transport = new InMemoryTransport(new InMemoryBus());
111874
+ transport.registerActor(options2.service.did, options2.service.keys);
111875
+ transport.registerActor(options2.participant.did, options2.participant.keys);
111876
+ transport.registerPeer(options2.participant.did, options2.participant.keys.publicKey.compressed);
111877
+ transport.registerPeer(options2.service.did, options2.service.keys.publicKey.compressed);
111878
+ transport.start();
111879
+ const service = new AggregationServiceRunner({
111880
+ transport,
111881
+ did: options2.service.did,
111882
+ keys: options2.service.keys,
111883
+ config: { minParticipants: 1, network: options2.config.network, beaconType: options2.config.beaconType },
111884
+ onProvideTxData: options2.onProvideTxData,
111885
+ cohortTtlMs: options2.cohortTtlMs,
111886
+ phaseTimeoutMs: options2.phaseTimeoutMs,
111887
+ // In-process bus with the participant already listening: a single advert
111888
+ // suffices, so disable the republish loop (no dangling interval).
111889
+ advertRepeatIntervalMs: 0
111890
+ });
111891
+ const participant = new AggregationParticipantRunner({
111892
+ transport,
111893
+ did: options2.participant.did,
111894
+ keys: options2.participant.keys,
111895
+ shouldJoin: async () => true,
111896
+ onProvideUpdate: options2.onProvideUpdate
111897
+ });
111898
+ await participant.start();
111899
+ try {
111900
+ return await service.run();
111901
+ } finally {
111902
+ participant.stop();
111903
+ service.stop();
111904
+ }
111905
+ }
111906
+ };
111907
+
112164
111908
  // src/core/beacon/beacon.ts
112165
111909
  init_shim();
112166
111910
  init_utils();
@@ -112331,7 +112075,7 @@ async function signSingletonInput(tx, inputIdx, kind, signer, prevOutScript, amo
112331
112075
  tx.finalize();
112332
112076
  return tx.hex;
112333
112077
  }
112334
- var Beacon = class {
112078
+ var SinglePartyBeacon = class {
112335
112079
  /**
112336
112080
  * The Beacon service configuration parsed from the DID Document.
112337
112081
  */
@@ -112468,7 +112212,7 @@ var Beacon = class {
112468
112212
 
112469
112213
  // src/core/beacon/cas-beacon.ts
112470
112214
  init_shim();
112471
- var CASBeacon = class extends Beacon {
112215
+ var CASBeacon = class extends SinglePartyBeacon {
112472
112216
  /**
112473
112217
  * Creates an instance of CASBeacon.
112474
112218
  * @param {BeaconService} service The service of the Beacon.
@@ -112528,7 +112272,7 @@ var CASBeacon = class extends Beacon {
112528
112272
  * Creates a CAS Announcement mapping the DID to the update hash, broadcasts the hash of the
112529
112273
  * announcement via OP_RETURN, and optionally publishes the announcement off-chain via the
112530
112274
  * supplied `casPublish` callback. UTXO selection, PSBT construction, fee estimation, signing,
112531
- * and broadcast are delegated to {@link Beacon.buildSignAndBroadcast}.
112275
+ * and broadcast are delegated to {@link SinglePartyBeacon.buildSignAndBroadcast}.
112532
112276
  *
112533
112277
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112534
112278
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112556,7 +112300,7 @@ init_shim();
112556
112300
 
112557
112301
  // src/core/beacon/singleton-beacon.ts
112558
112302
  init_shim();
112559
- var SingletonBeacon = class extends Beacon {
112303
+ var SingletonBeacon = class extends SinglePartyBeacon {
112560
112304
  /**
112561
112305
  * Creates an instance of SingletonBeacon.
112562
112306
  * @param {BeaconService} service The BeaconService object representing the funded beacon to announce the update to.
@@ -112593,7 +112337,7 @@ var SingletonBeacon = class extends Beacon {
112593
112337
  *
112594
112338
  * The signal bytes embedded in OP_RETURN are the SHA-256 canonical hash of the signed update.
112595
112339
  * UTXO selection, PSBT construction, fee estimation, signing, and broadcast are delegated to
112596
- * {@link Beacon.buildSignAndBroadcast}.
112340
+ * {@link SinglePartyBeacon.buildSignAndBroadcast}.
112597
112341
  *
112598
112342
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112599
112343
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112612,7 +112356,7 @@ var SingletonBeacon = class extends Beacon {
112612
112356
  // src/core/beacon/smt-beacon.ts
112613
112357
  init_shim();
112614
112358
  init_utils();
112615
- var SMTBeacon = class extends Beacon {
112359
+ var SMTBeacon = class extends SinglePartyBeacon {
112616
112360
  /**
112617
112361
  * Creates an instance of SMTBeacon.
112618
112362
  * @param {BeaconService} service The Beacon service.
@@ -112647,9 +112391,6 @@ var SMTBeacon = class extends Beacon {
112647
112391
  });
112648
112392
  continue;
112649
112393
  }
112650
- if (!smtProof.updateId) {
112651
- continue;
112652
- }
112653
112394
  if (!smtProof.nonce) {
112654
112395
  throw new SMTBeaconError(
112655
112396
  "SMT proof missing required nonce field.",
@@ -112658,7 +112399,8 @@ var SMTBeacon = class extends Beacon {
112658
112399
  );
112659
112400
  }
112660
112401
  const index = didToIndex(did);
112661
- const candidateHash = blockHash(blockHash(hexToHash(smtProof.nonce)), hexToHash(smtProof.updateId));
112402
+ const nonceHash2 = base64UrlToHash(smtProof.nonce);
112403
+ const candidateHash = smtProof.updateId ? blockHash(blockHash(nonceHash2), base64UrlToHash(smtProof.updateId)) : blockHash(blockHash(nonceHash2));
112662
112404
  const valid = verifySerializedProof(smtProof, index, candidateHash);
112663
112405
  if (!valid) {
112664
112406
  throw new SMTBeaconError(
@@ -112667,11 +112409,15 @@ var SMTBeacon = class extends Beacon {
112667
112409
  { smtProof, did }
112668
112410
  );
112669
112411
  }
112670
- const signedUpdate = sidecar.updateMap.get(smtProof.updateId);
112412
+ if (!smtProof.updateId) {
112413
+ continue;
112414
+ }
112415
+ const updateHashHex = hashToHex(base64UrlToHash(smtProof.updateId));
112416
+ const signedUpdate = sidecar.updateMap.get(updateHashHex);
112671
112417
  if (!signedUpdate) {
112672
112418
  needs.push({
112673
112419
  kind: "NeedSignedUpdate",
112674
- updateHash: smtProof.updateId,
112420
+ updateHash: updateHashHex,
112675
112421
  beaconServiceId: this.service.id
112676
112422
  });
112677
112423
  continue;
@@ -112686,7 +112432,7 @@ var SMTBeacon = class extends Beacon {
112686
112432
  * Builds a single-entry Sparse Merkle Tree from the signed update, then broadcasts the tree's
112687
112433
  * root hash via OP_RETURN. For multi-party aggregation, use the {@link AggregationService}
112688
112434
  * subsystem directly instead of this method. UTXO selection, PSBT construction, fee estimation,
112689
- * signing, and broadcast are delegated to {@link Beacon.buildSignAndBroadcast}.
112435
+ * signing, and broadcast are delegated to {@link SinglePartyBeacon.buildSignAndBroadcast}.
112690
112436
  *
112691
112437
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112692
112438
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112712,7 +112458,7 @@ var BeaconFactory = class {
112712
112458
  /**
112713
112459
  * Establish a Beacon instance based on the provided service and optional sidecar data.
112714
112460
  * @param {BeaconService} service The beacon service configuration.
112715
- * @returns {Beacon} The established Beacon instance.
112461
+ * @returns {SinglePartyBeacon} The established Beacon instance.
112716
112462
  */
112717
112463
  static establish(service) {
112718
112464
  switch (service.type) {
@@ -128861,7 +128607,7 @@ var Resolver = class _Resolver {
128861
128607
  const smtMap = /* @__PURE__ */ new Map();
128862
128608
  if (sidecar.smtProofs?.length)
128863
128609
  for (const proof of sidecar.smtProofs) {
128864
- smtMap.set(proof.id, proof);
128610
+ smtMap.set(encode(decode(proof.id, "base64urlnopad"), "hex"), proof);
128865
128611
  }
128866
128612
  return { updateMap, casMap, smtMap };
128867
128613
  }
@@ -129149,11 +128895,12 @@ var Resolver = class _Resolver {
129149
128895
  case "NeedSMTProof": {
129150
128896
  const smtNeed = need;
129151
128897
  const proof = data;
129152
- if (proof.id !== smtNeed.smtRootHash) {
128898
+ const proofIdHex = encode(decode(proof.id, "base64urlnopad"), "hex");
128899
+ if (proofIdHex !== smtNeed.smtRootHash) {
129153
128900
  throw new ResolveError(
129154
- `SMT proof root hash mismatch: expected ${smtNeed.smtRootHash}, got ${proof.id}`,
128901
+ `SMT proof root hash mismatch: expected ${smtNeed.smtRootHash}, got ${proofIdHex}`,
129155
128902
  INVALID_DID_UPDATE,
129156
- { expected: smtNeed.smtRootHash, actual: proof.id }
128903
+ { expected: smtNeed.smtRootHash, actual: proofIdHex }
129157
128904
  );
129158
128905
  }
129159
128906
  this.#sidecarData.smtMap.set(smtNeed.smtRootHash, proof);
@@ -129231,6 +128978,7 @@ export {
129231
128978
  AggregationParticipant,
129232
128979
  AggregationParticipantError,
129233
128980
  AggregationParticipantRunner,
128981
+ AggregationRunner,
129234
128982
  AggregationService,
129235
128983
  AggregationServiceError,
129236
128984
  AggregationServiceRunner,
@@ -129238,7 +128986,6 @@ export {
129238
128986
  BECH32M_CHARS,
129239
128987
  BTCR2_DID_DOCUMENT_CONTEXT,
129240
128988
  BaseMessage,
129241
- Beacon,
129242
128989
  BeaconError,
129243
128990
  BeaconFactory,
129244
128991
  BeaconSignalDiscovery,
@@ -129273,7 +129020,9 @@ export {
129273
129020
  HttpTransportError,
129274
129021
  ID_PLACEHOLDER_VALUE,
129275
129022
  Identifier,
129023
+ InMemoryBus,
129276
129024
  InMemoryRateLimitStore,
129025
+ InMemoryTransport,
129277
129026
  InboxBuffer,
129278
129027
  NONCE_CONTRIBUTION,
129279
129028
  NonceCache,
@@ -129295,6 +129044,7 @@ export {
129295
129044
  ServiceCohortPhase,
129296
129045
  SigningSessionError,
129297
129046
  SigningSessionPhase,
129047
+ SinglePartyBeacon,
129298
129048
  SingletonBeacon,
129299
129049
  SingletonBeaconError,
129300
129050
  StaticFeeEstimator,