@waku/core 0.0.38 → 0.0.39-3e66a33.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 (50) hide show
  1. package/bundle/index.js +606 -1117
  2. package/bundle/lib/message/version_0.js +1 -1
  3. package/bundle/{version_0-CGLjyYN6.js → version_0-DQUncDnb.js} +810 -5
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/connection_manager/connection_limiter.js +4 -5
  9. package/dist/lib/connection_manager/connection_limiter.js.map +1 -1
  10. package/dist/lib/connection_manager/network_monitor.js +2 -1
  11. package/dist/lib/connection_manager/network_monitor.js.map +1 -1
  12. package/dist/lib/filter/filter.d.ts +8 -5
  13. package/dist/lib/filter/filter.js +32 -19
  14. package/dist/lib/filter/filter.js.map +1 -1
  15. package/dist/lib/light_push/constants.d.ts +6 -0
  16. package/dist/lib/light_push/constants.js +7 -0
  17. package/dist/lib/light_push/constants.js.map +1 -0
  18. package/dist/lib/light_push/index.d.ts +2 -1
  19. package/dist/lib/light_push/index.js +2 -1
  20. package/dist/lib/light_push/index.js.map +1 -1
  21. package/dist/lib/light_push/light_push.d.ts +7 -7
  22. package/dist/lib/light_push/light_push.js +56 -82
  23. package/dist/lib/light_push/light_push.js.map +1 -1
  24. package/dist/lib/light_push/protocol_handler.d.ts +30 -0
  25. package/dist/lib/light_push/protocol_handler.js +140 -0
  26. package/dist/lib/light_push/protocol_handler.js.map +1 -0
  27. package/dist/lib/light_push/push_rpc.d.ts +3 -3
  28. package/dist/lib/light_push/push_rpc.js +3 -3
  29. package/dist/lib/light_push/push_rpc.js.map +1 -1
  30. package/dist/lib/light_push/push_rpc_v3.d.ts +73 -0
  31. package/dist/lib/light_push/push_rpc_v3.js +136 -0
  32. package/dist/lib/light_push/push_rpc_v3.js.map +1 -0
  33. package/dist/lib/message/version_0.d.ts +4 -0
  34. package/dist/lib/message/version_0.js +16 -0
  35. package/dist/lib/message/version_0.js.map +1 -1
  36. package/dist/lib/stream_manager/stream_manager.d.ts +1 -1
  37. package/dist/lib/stream_manager/stream_manager.js.map +1 -1
  38. package/package.json +1 -125
  39. package/src/index.ts +5 -1
  40. package/src/lib/connection_manager/connection_limiter.ts +8 -6
  41. package/src/lib/connection_manager/network_monitor.ts +2 -2
  42. package/src/lib/filter/filter.ts +34 -24
  43. package/src/lib/light_push/constants.ts +7 -0
  44. package/src/lib/light_push/index.ts +2 -1
  45. package/src/lib/light_push/light_push.ts +72 -98
  46. package/src/lib/light_push/protocol_handler.ts +191 -0
  47. package/src/lib/light_push/push_rpc.ts +5 -5
  48. package/src/lib/light_push/push_rpc_v3.ts +162 -0
  49. package/src/lib/message/version_0.ts +20 -0
  50. package/src/lib/stream_manager/stream_manager.ts +1 -1
package/bundle/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { e as equals$2, c as coerce, b as base32, a as base58btc, d as base36, B as BASES, f as fromString, v as version_0, g as allocUnsafe, h as alloc, i as encodingLength$1, j as encode$3, k as decode$4, L as Logger, F as FilterSubscribeRequest, l as FilterSubscribeResponse$1, M as MessagePush, P as PushRpc$1, m as PushResponse, S as StoreQueryRequest$1, n as StoreQueryResponse$1, o as createEncoder, p as enumeration, q as message, r as encodeMessage, s as decodeMessage, t as bases, u as base64url, w as encodeUint8Array, W as WakuMetadataRequest, x as WakuMetadataResponse } from './version_0-CGLjyYN6.js';
2
- export { y as createDecoder } from './version_0-CGLjyYN6.js';
1
+ import { e as equals$2, c as coerce, b as base32, a as base58btc, d as base36, s as sha256$1, f as concat$1, u as utf8ToBytes, v as version_0, g as allocUnsafe, h as alloc, i as encodingLength$1, j as encode$3, k as decode$4, L as Logger, F as FilterSubscribeRequest, l as FilterSubscribeResponse$1, M as MessagePush, P as PushRpc$1, m as LightPushRequestV3, n as LightPushResponseV3, S as StoreQueryRequest$1, o as StoreQueryResponse$1, p as createEncoder, t as toString, q as fromString, r as hexToBytes, w as isBytes, x as abytes, y as bytesToHex, z as concatBytes, A as anumber, B as randomBytes, C as sha512, D as enumeration, E as message, G as encodeMessage, H as decodeMessage, I as Hash, J as ahash, K as toBytes, N as clean, O as aexists, Q as sha256$2, R as bases, T as base64url, U as encodeUint8Array, V as bytesToUtf8, W as WakuMetadataRequest, X as WakuMetadataResponse } from './version_0-DQUncDnb.js';
2
+ export { Y as createDecoder, Z as messageHash, _ as messageHashStr } from './version_0-DQUncDnb.js';
3
3
 
4
4
  /* eslint-disable */
5
5
  var encode_1 = encode$2;
@@ -191,7 +191,7 @@ class Hasher {
191
191
  function sha(name) {
192
192
  return async (data) => new Uint8Array(await crypto.subtle.digest(name, data));
193
193
  }
194
- const sha256$2 = from({
194
+ const sha256 = from({
195
195
  name: 'sha2-256',
196
196
  code: 0x12,
197
197
  encode: sha('SHA-256')
@@ -560,10 +560,6 @@ function encodeCID(version, code, multihash) {
560
560
  }
561
561
  const cidSymbol = Symbol.for('@ipld/js-cid/CID');
562
562
 
563
- function isDefined(value) {
564
- return Boolean(value);
565
- }
566
-
567
563
  const MB = 1024 ** 2;
568
564
  const SIZE_CAP_IN_MB = 1;
569
565
  /**
@@ -581,714 +577,88 @@ async function isMessageSizeUnderCap(encoder, message) {
581
577
  }
582
578
  const isWireSizeUnderCap = (buf) => buf.length / MB <= SIZE_CAP_IN_MB;
583
579
 
584
- const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
585
-
586
- /**
587
- * Utilities for hex, bytes, CSPRNG.
588
- * @module
589
- */
590
- /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
591
- // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
592
- // node.js versions earlier than v19 don't declare it in global scope.
593
- // For node.js, package.json#exports field mapping rewrites import
594
- // from `crypto` to `cryptoNode`, which imports native module.
595
- // Makes the utils un-importable in browsers without a bundler.
596
- // Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
597
- /** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
598
- function isBytes(a) {
599
- return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
600
- }
601
- /** Asserts something is positive integer. */
602
- function anumber(n) {
603
- if (!Number.isSafeInteger(n) || n < 0)
604
- throw new Error('positive integer expected, got ' + n);
605
- }
606
- /** Asserts something is Uint8Array. */
607
- function abytes(b, ...lengths) {
608
- if (!isBytes(b))
609
- throw new Error('Uint8Array expected');
610
- if (lengths.length > 0 && !lengths.includes(b.length))
611
- throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
612
- }
613
- /** Asserts something is hash */
614
- function ahash(h) {
615
- if (typeof h !== 'function' || typeof h.create !== 'function')
616
- throw new Error('Hash should be wrapped by utils.createHasher');
617
- anumber(h.outputLen);
618
- anumber(h.blockLen);
619
- }
620
- /** Asserts a hash instance has not been destroyed / finished */
621
- function aexists(instance, checkFinished = true) {
622
- if (instance.destroyed)
623
- throw new Error('Hash instance has been destroyed');
624
- if (checkFinished && instance.finished)
625
- throw new Error('Hash#digest() has already been called');
626
- }
627
- /** Asserts output is properly-sized byte array */
628
- function aoutput(out, instance) {
629
- abytes(out);
630
- const min = instance.outputLen;
631
- if (out.length < min) {
632
- throw new Error('digestInto() expects output buffer of length at least ' + min);
633
- }
634
- }
635
- /** Zeroize a byte array. Warning: JS provides no guarantees. */
636
- function clean(...arrays) {
637
- for (let i = 0; i < arrays.length; i++) {
638
- arrays[i].fill(0);
639
- }
640
- }
641
- /** Create DataView of an array for easy byte-level manipulation. */
642
- function createView(arr) {
643
- return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
644
- }
645
- /** The rotate right (circular right shift) operation for uint32 */
646
- function rotr(word, shift) {
647
- return (word << (32 - shift)) | (word >>> shift);
648
- }
649
- // Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
650
- const hasHexBuiltin = /* @__PURE__ */ (() =>
651
- // @ts-ignore
652
- typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();
653
- // Array where index 0xf0 (240) is mapped to string 'f0'
654
- const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
655
- /**
656
- * Convert byte array to hex string. Uses built-in function, when available.
657
- * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
658
- */
659
- function bytesToHex$1(bytes) {
660
- abytes(bytes);
661
- // @ts-ignore
662
- if (hasHexBuiltin)
663
- return bytes.toHex();
664
- // pre-caching improves the speed 6x
665
- let hex = '';
666
- for (let i = 0; i < bytes.length; i++) {
667
- hex += hexes[bytes[i]];
668
- }
669
- return hex;
670
- }
671
- // We use optimized technique to convert hex string to byte array
672
- const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
673
- function asciiToBase16(ch) {
674
- if (ch >= asciis._0 && ch <= asciis._9)
675
- return ch - asciis._0; // '2' => 50-48
676
- if (ch >= asciis.A && ch <= asciis.F)
677
- return ch - (asciis.A - 10); // 'B' => 66-(65-10)
678
- if (ch >= asciis.a && ch <= asciis.f)
679
- return ch - (asciis.a - 10); // 'b' => 98-(97-10)
680
- return;
681
- }
682
- /**
683
- * Convert hex string to byte array. Uses built-in function, when available.
684
- * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
685
- */
686
- function hexToBytes(hex) {
687
- if (typeof hex !== 'string')
688
- throw new Error('hex string expected, got ' + typeof hex);
689
- // @ts-ignore
690
- if (hasHexBuiltin)
691
- return Uint8Array.fromHex(hex);
692
- const hl = hex.length;
693
- const al = hl / 2;
694
- if (hl % 2)
695
- throw new Error('hex string expected, got unpadded hex of length ' + hl);
696
- const array = new Uint8Array(al);
697
- for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
698
- const n1 = asciiToBase16(hex.charCodeAt(hi));
699
- const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
700
- if (n1 === undefined || n2 === undefined) {
701
- const char = hex[hi] + hex[hi + 1];
702
- throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
703
- }
704
- array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
705
- }
706
- return array;
707
- }
708
- /**
709
- * Converts string to bytes using UTF8 encoding.
710
- * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
711
- */
712
- function utf8ToBytes$1(str) {
713
- if (typeof str !== 'string')
714
- throw new Error('string expected');
715
- return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
716
- }
717
- /**
718
- * Normalizes (non-hex) string or Uint8Array to Uint8Array.
719
- * Warning: when Uint8Array is passed, it would NOT get copied.
720
- * Keep in mind for future mutable operations.
721
- */
722
- function toBytes(data) {
723
- if (typeof data === 'string')
724
- data = utf8ToBytes$1(data);
725
- abytes(data);
726
- return data;
727
- }
728
- /** Copies several Uint8Arrays into one. */
729
- function concatBytes(...arrays) {
730
- let sum = 0;
731
- for (let i = 0; i < arrays.length; i++) {
732
- const a = arrays[i];
733
- abytes(a);
734
- sum += a.length;
735
- }
736
- const res = new Uint8Array(sum);
737
- for (let i = 0, pad = 0; i < arrays.length; i++) {
738
- const a = arrays[i];
739
- res.set(a, pad);
740
- pad += a.length;
741
- }
742
- return res;
743
- }
744
- /** For runtime check if class implements interface */
745
- class Hash {
746
- }
747
- /** Wraps hash function, creating an interface on top of it */
748
- function createHasher(hashCons) {
749
- const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
750
- const tmp = hashCons();
751
- hashC.outputLen = tmp.outputLen;
752
- hashC.blockLen = tmp.blockLen;
753
- hashC.create = () => hashCons();
754
- return hashC;
755
- }
756
- /** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
757
- function randomBytes(bytesLength = 32) {
758
- if (crypto$1 && typeof crypto$1.getRandomValues === 'function') {
759
- return crypto$1.getRandomValues(new Uint8Array(bytesLength));
760
- }
761
- // Legacy Node.js compatibility
762
- if (crypto$1 && typeof crypto$1.randomBytes === 'function') {
763
- return Uint8Array.from(crypto$1.randomBytes(bytesLength));
764
- }
765
- throw new Error('crypto.getRandomValues must be defined');
766
- }
767
-
768
- /**
769
- * Internal Merkle-Damgard hash utils.
770
- * @module
771
- */
772
- /** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
773
- function setBigUint64(view, byteOffset, value, isLE) {
774
- if (typeof view.setBigUint64 === 'function')
775
- return view.setBigUint64(byteOffset, value, isLE);
776
- const _32n = BigInt(32);
777
- const _u32_max = BigInt(0xffffffff);
778
- const wh = Number((value >> _32n) & _u32_max);
779
- const wl = Number(value & _u32_max);
780
- const h = isLE ? 4 : 0;
781
- const l = isLE ? 0 : 4;
782
- view.setUint32(byteOffset + h, wh, isLE);
783
- view.setUint32(byteOffset + l, wl, isLE);
784
- }
785
- /** Choice: a ? b : c */
786
- function Chi(a, b, c) {
787
- return (a & b) ^ (~a & c);
788
- }
789
- /** Majority function, true if any two inputs is true. */
790
- function Maj(a, b, c) {
791
- return (a & b) ^ (a & c) ^ (b & c);
792
- }
793
- /**
794
- * Merkle-Damgard hash construction base class.
795
- * Could be used to create MD5, RIPEMD, SHA1, SHA2.
796
- */
797
- class HashMD extends Hash {
798
- constructor(blockLen, outputLen, padOffset, isLE) {
799
- super();
800
- this.finished = false;
801
- this.length = 0;
802
- this.pos = 0;
803
- this.destroyed = false;
804
- this.blockLen = blockLen;
805
- this.outputLen = outputLen;
806
- this.padOffset = padOffset;
807
- this.isLE = isLE;
808
- this.buffer = new Uint8Array(blockLen);
809
- this.view = createView(this.buffer);
810
- }
811
- update(data) {
812
- aexists(this);
813
- data = toBytes(data);
814
- abytes(data);
815
- const { view, buffer, blockLen } = this;
816
- const len = data.length;
817
- for (let pos = 0; pos < len;) {
818
- const take = Math.min(blockLen - this.pos, len - pos);
819
- // Fast path: we have at least one block in input, cast it to view and process
820
- if (take === blockLen) {
821
- const dataView = createView(data);
822
- for (; blockLen <= len - pos; pos += blockLen)
823
- this.process(dataView, pos);
824
- continue;
825
- }
826
- buffer.set(data.subarray(pos, pos + take), this.pos);
827
- this.pos += take;
828
- pos += take;
829
- if (this.pos === blockLen) {
830
- this.process(view, 0);
831
- this.pos = 0;
832
- }
833
- }
834
- this.length += data.length;
835
- this.roundClean();
836
- return this;
837
- }
838
- digestInto(out) {
839
- aexists(this);
840
- aoutput(out, this);
841
- this.finished = true;
842
- // Padding
843
- // We can avoid allocation of buffer for padding completely if it
844
- // was previously not allocated here. But it won't change performance.
845
- const { buffer, view, blockLen, isLE } = this;
846
- let { pos } = this;
847
- // append the bit '1' to the message
848
- buffer[pos++] = 0b10000000;
849
- clean(this.buffer.subarray(pos));
850
- // we have less than padOffset left in buffer, so we cannot put length in
851
- // current block, need process it and pad again
852
- if (this.padOffset > blockLen - pos) {
853
- this.process(view, 0);
854
- pos = 0;
855
- }
856
- // Pad until full block byte with zeros
857
- for (let i = pos; i < blockLen; i++)
858
- buffer[i] = 0;
859
- // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
860
- // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
861
- // So we just write lowest 64 bits of that value.
862
- setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
863
- this.process(view, 0);
864
- const oview = createView(out);
865
- const len = this.outputLen;
866
- // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
867
- if (len % 4)
868
- throw new Error('_sha2: outputLen should be aligned to 32bit');
869
- const outLen = len / 4;
870
- const state = this.get();
871
- if (outLen > state.length)
872
- throw new Error('_sha2: outputLen bigger than state');
873
- for (let i = 0; i < outLen; i++)
874
- oview.setUint32(4 * i, state[i], isLE);
875
- }
876
- digest() {
877
- const { buffer, outputLen } = this;
878
- this.digestInto(buffer);
879
- const res = buffer.slice(0, outputLen);
880
- this.destroy();
881
- return res;
882
- }
883
- _cloneInto(to) {
884
- to || (to = new this.constructor());
885
- to.set(...this.get());
886
- const { blockLen, buffer, length, finished, destroyed, pos } = this;
887
- to.destroyed = destroyed;
888
- to.finished = finished;
889
- to.length = length;
890
- to.pos = pos;
891
- if (length % blockLen)
892
- to.buffer.set(buffer);
893
- return to;
894
- }
895
- clone() {
896
- return this._cloneInto();
897
- }
580
+ function isAutoSharding(config) {
581
+ return "clusterId" in config && "numShardsInCluster" in config;
898
582
  }
899
- /**
900
- * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
901
- * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
902
- */
903
- /** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
904
- const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
905
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
906
- ]);
907
- /** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */
908
- const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
909
- 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
910
- 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
911
- ]);
912
-
913
- /**
914
- * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
915
- * @todo re-check https://issues.chromium.org/issues/42212588
916
- * @module
917
- */
918
- const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
919
- const _32n = /* @__PURE__ */ BigInt(32);
920
- function fromBig(n, le = false) {
921
- if (le)
922
- return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
923
- return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
924
- }
925
- function split(lst, le = false) {
926
- const len = lst.length;
927
- let Ah = new Uint32Array(len);
928
- let Al = new Uint32Array(len);
929
- for (let i = 0; i < len; i++) {
930
- const { h, l } = fromBig(lst[i], le);
931
- [Ah[i], Al[i]] = [h, l];
932
- }
933
- return [Ah, Al];
934
- }
935
- // for Shift in [0, 32)
936
- const shrSH = (h, _l, s) => h >>> s;
937
- const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
938
- // Right rotate for Shift in [1, 32)
939
- const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
940
- const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
941
- // Right rotate for Shift in (32, 64), NOTE: 32 is special case.
942
- const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
943
- const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
944
- // JS uses 32-bit signed integers for bitwise operations which means we cannot
945
- // simple take carry out of low bit sum by shift, we need to use division.
946
- function add(Ah, Al, Bh, Bl) {
947
- const l = (Al >>> 0) + (Bl >>> 0);
948
- return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
949
- }
950
- // Addition with more than 2 elements
951
- const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
952
- const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
953
- const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
954
- const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
955
- const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
956
- const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
957
583
 
584
+ const formatPubsubTopic = (clusterId, shard) => {
585
+ return `/waku/2/rs/${clusterId}/${shard}`;
586
+ };
958
587
  /**
959
- * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
960
- * SHA256 is the fastest hash implementable in JS, even faster than Blake3.
961
- * Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
962
- * [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
963
- * @module
588
+ * @deprecated will be removed
964
589
  */
590
+ const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
591
+ const parts = pubsubTopics.split("/");
592
+ if (parts.length != 6 ||
593
+ parts[1] !== "waku" ||
594
+ parts[2] !== "2" ||
595
+ parts[3] !== "rs")
596
+ throw new Error("Invalid pubsub topic");
597
+ const clusterId = parseInt(parts[4]);
598
+ const shard = parseInt(parts[5]);
599
+ if (isNaN(clusterId) || isNaN(shard))
600
+ throw new Error("Invalid clusterId or shard");
601
+ return {
602
+ clusterId,
603
+ shard
604
+ };
605
+ };
965
606
  /**
966
- * Round constants:
967
- * First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
607
+ * Given a string, will throw an error if it is not formatted as a valid content topic for autosharding based on https://rfc.vac.dev/spec/51/
608
+ * @param contentTopic String to validate
609
+ * @returns Object with each content topic field as an attribute
968
610
  */
969
- // prettier-ignore
970
- const SHA256_K = /* @__PURE__ */ Uint32Array.from([
971
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
972
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
973
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
974
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
975
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
976
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
977
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
978
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
979
- ]);
980
- /** Reusable temporary buffer. "W" comes straight from spec. */
981
- const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
982
- class SHA256 extends HashMD {
983
- constructor(outputLen = 32) {
984
- super(64, outputLen, 8, false);
985
- // We cannot use array here since array allows indexing by variable
986
- // which means optimizer/compiler cannot use registers.
987
- this.A = SHA256_IV[0] | 0;
988
- this.B = SHA256_IV[1] | 0;
989
- this.C = SHA256_IV[2] | 0;
990
- this.D = SHA256_IV[3] | 0;
991
- this.E = SHA256_IV[4] | 0;
992
- this.F = SHA256_IV[5] | 0;
993
- this.G = SHA256_IV[6] | 0;
994
- this.H = SHA256_IV[7] | 0;
995
- }
996
- get() {
997
- const { A, B, C, D, E, F, G, H } = this;
998
- return [A, B, C, D, E, F, G, H];
999
- }
1000
- // prettier-ignore
1001
- set(A, B, C, D, E, F, G, H) {
1002
- this.A = A | 0;
1003
- this.B = B | 0;
1004
- this.C = C | 0;
1005
- this.D = D | 0;
1006
- this.E = E | 0;
1007
- this.F = F | 0;
1008
- this.G = G | 0;
1009
- this.H = H | 0;
1010
- }
1011
- process(view, offset) {
1012
- // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
1013
- for (let i = 0; i < 16; i++, offset += 4)
1014
- SHA256_W[i] = view.getUint32(offset, false);
1015
- for (let i = 16; i < 64; i++) {
1016
- const W15 = SHA256_W[i - 15];
1017
- const W2 = SHA256_W[i - 2];
1018
- const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
1019
- const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
1020
- SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
1021
- }
1022
- // Compression function main loop, 64 rounds
1023
- let { A, B, C, D, E, F, G, H } = this;
1024
- for (let i = 0; i < 64; i++) {
1025
- const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
1026
- const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
1027
- const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
1028
- const T2 = (sigma0 + Maj(A, B, C)) | 0;
1029
- H = G;
1030
- G = F;
1031
- F = E;
1032
- E = (D + T1) | 0;
1033
- D = C;
1034
- C = B;
1035
- B = A;
1036
- A = (T1 + T2) | 0;
1037
- }
1038
- // Add the compressed chunk to the current hash value
1039
- A = (A + this.A) | 0;
1040
- B = (B + this.B) | 0;
1041
- C = (C + this.C) | 0;
1042
- D = (D + this.D) | 0;
1043
- E = (E + this.E) | 0;
1044
- F = (F + this.F) | 0;
1045
- G = (G + this.G) | 0;
1046
- H = (H + this.H) | 0;
1047
- this.set(A, B, C, D, E, F, G, H);
1048
- }
1049
- roundClean() {
1050
- clean(SHA256_W);
1051
- }
1052
- destroy() {
1053
- this.set(0, 0, 0, 0, 0, 0, 0, 0);
1054
- clean(this.buffer);
1055
- }
1056
- }
1057
- // SHA2-512 is slower than sha256 in js because u64 operations are slow.
1058
- // Round contants
1059
- // First 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409
1060
- // prettier-ignore
1061
- const K512 = /* @__PURE__ */ (() => split([
1062
- '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
1063
- '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
1064
- '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
1065
- '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
1066
- '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
1067
- '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
1068
- '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
1069
- '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
1070
- '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
1071
- '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
1072
- '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
1073
- '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
1074
- '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
1075
- '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
1076
- '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
1077
- '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
1078
- '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
1079
- '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
1080
- '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
1081
- '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
1082
- ].map(n => BigInt(n))))();
1083
- const SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
1084
- const SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
1085
- // Reusable temporary buffers
1086
- const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
1087
- const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
1088
- class SHA512 extends HashMD {
1089
- constructor(outputLen = 64) {
1090
- super(128, outputLen, 16, false);
1091
- // We cannot use array here since array allows indexing by variable
1092
- // which means optimizer/compiler cannot use registers.
1093
- // h -- high 32 bits, l -- low 32 bits
1094
- this.Ah = SHA512_IV[0] | 0;
1095
- this.Al = SHA512_IV[1] | 0;
1096
- this.Bh = SHA512_IV[2] | 0;
1097
- this.Bl = SHA512_IV[3] | 0;
1098
- this.Ch = SHA512_IV[4] | 0;
1099
- this.Cl = SHA512_IV[5] | 0;
1100
- this.Dh = SHA512_IV[6] | 0;
1101
- this.Dl = SHA512_IV[7] | 0;
1102
- this.Eh = SHA512_IV[8] | 0;
1103
- this.El = SHA512_IV[9] | 0;
1104
- this.Fh = SHA512_IV[10] | 0;
1105
- this.Fl = SHA512_IV[11] | 0;
1106
- this.Gh = SHA512_IV[12] | 0;
1107
- this.Gl = SHA512_IV[13] | 0;
1108
- this.Hh = SHA512_IV[14] | 0;
1109
- this.Hl = SHA512_IV[15] | 0;
1110
- }
1111
- // prettier-ignore
1112
- get() {
1113
- const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
1114
- return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
611
+ function ensureValidContentTopic(contentTopic) {
612
+ const parts = contentTopic.split("/");
613
+ if (parts.length < 5 || parts.length > 6) {
614
+ throw Error(`Content topic format is invalid: ${contentTopic}`);
1115
615
  }
1116
- // prettier-ignore
1117
- set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
1118
- this.Ah = Ah | 0;
1119
- this.Al = Al | 0;
1120
- this.Bh = Bh | 0;
1121
- this.Bl = Bl | 0;
1122
- this.Ch = Ch | 0;
1123
- this.Cl = Cl | 0;
1124
- this.Dh = Dh | 0;
1125
- this.Dl = Dl | 0;
1126
- this.Eh = Eh | 0;
1127
- this.El = El | 0;
1128
- this.Fh = Fh | 0;
1129
- this.Fl = Fl | 0;
1130
- this.Gh = Gh | 0;
1131
- this.Gl = Gl | 0;
1132
- this.Hh = Hh | 0;
1133
- this.Hl = Hl | 0;
1134
- }
1135
- process(view, offset) {
1136
- // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
1137
- for (let i = 0; i < 16; i++, offset += 4) {
1138
- SHA512_W_H[i] = view.getUint32(offset);
1139
- SHA512_W_L[i] = view.getUint32((offset += 4));
1140
- }
1141
- for (let i = 16; i < 80; i++) {
1142
- // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
1143
- const W15h = SHA512_W_H[i - 15] | 0;
1144
- const W15l = SHA512_W_L[i - 15] | 0;
1145
- const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
1146
- const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
1147
- // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
1148
- const W2h = SHA512_W_H[i - 2] | 0;
1149
- const W2l = SHA512_W_L[i - 2] | 0;
1150
- const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
1151
- const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
1152
- // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
1153
- const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
1154
- const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
1155
- SHA512_W_H[i] = SUMh | 0;
1156
- SHA512_W_L[i] = SUMl | 0;
1157
- }
1158
- let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
1159
- // Compression function main loop, 80 rounds
1160
- for (let i = 0; i < 80; i++) {
1161
- // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
1162
- const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
1163
- const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
1164
- //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
1165
- const CHIh = (Eh & Fh) ^ (~Eh & Gh);
1166
- const CHIl = (El & Fl) ^ (~El & Gl);
1167
- // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
1168
- // prettier-ignore
1169
- const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
1170
- const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
1171
- const T1l = T1ll | 0;
1172
- // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
1173
- const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
1174
- const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
1175
- const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
1176
- const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
1177
- Hh = Gh | 0;
1178
- Hl = Gl | 0;
1179
- Gh = Fh | 0;
1180
- Gl = Fl | 0;
1181
- Fh = Eh | 0;
1182
- Fl = El | 0;
1183
- ({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
1184
- Dh = Ch | 0;
1185
- Dl = Cl | 0;
1186
- Ch = Bh | 0;
1187
- Cl = Bl | 0;
1188
- Bh = Ah | 0;
1189
- Bl = Al | 0;
1190
- const All = add3L(T1l, sigma0l, MAJl);
1191
- Ah = add3H(All, T1h, sigma0h, MAJh);
1192
- Al = All | 0;
1193
- }
1194
- // Add the compressed chunk to the current hash value
1195
- ({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
1196
- ({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
1197
- ({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
1198
- ({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
1199
- ({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
1200
- ({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
1201
- ({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
1202
- ({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
1203
- this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
1204
- }
1205
- roundClean() {
1206
- clean(SHA512_W_H, SHA512_W_L);
616
+ // Validate generation field if present
617
+ let generation = 0;
618
+ if (parts.length == 6) {
619
+ generation = parseInt(parts[1]);
620
+ if (isNaN(generation)) {
621
+ throw new Error(`Invalid generation field in content topic: ${contentTopic}`);
622
+ }
623
+ if (generation > 0) {
624
+ throw new Error(`Generation greater than 0 is not supported: ${contentTopic}`);
625
+ }
1207
626
  }
1208
- destroy() {
1209
- clean(this.buffer);
1210
- this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
627
+ // Validate remaining fields
628
+ const fields = parts.splice(-4);
629
+ // Validate application field
630
+ if (fields[0].length == 0) {
631
+ throw new Error(`Application field cannot be empty: ${contentTopic}`);
1211
632
  }
1212
- }
1213
- /**
1214
- * SHA2-256 hash function from RFC 4634.
1215
- *
1216
- * It is the fastest JS hash, even faster than Blake3.
1217
- * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
1218
- * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
1219
- */
1220
- const sha256$1 = /* @__PURE__ */ createHasher(() => new SHA256());
1221
- /** SHA2-512 hash function from RFC 4634. */
1222
- const sha512 = /* @__PURE__ */ createHasher(() => new SHA512());
1223
-
1224
- /**
1225
- * SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
1226
- *
1227
- * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
1228
- * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
1229
- *
1230
- * Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
1231
- * @module
1232
- * @deprecated
1233
- */
1234
- /** @deprecated Use import from `noble/hashes/sha2` module */
1235
- const sha256 = sha256$1;
1236
-
1237
- /**
1238
- * Turns a `Uint8Array` into a string.
1239
- *
1240
- * Supports `utf8`, `utf-8` and any encoding supported by the multibase module.
1241
- *
1242
- * Also `ascii` which is similar to node's 'binary' encoding.
1243
- */
1244
- function toString(array, encoding = 'utf8') {
1245
- const base = BASES[encoding];
1246
- if (base == null) {
1247
- throw new Error(`Unsupported encoding "${encoding}"`);
633
+ // Validate version field
634
+ if (fields[1].length == 0) {
635
+ throw new Error(`Version field cannot be empty: ${contentTopic}`);
1248
636
  }
1249
- // strip multibase prefix
1250
- return base.encoder.encode(array).substring(1);
1251
- }
1252
-
1253
- function numberToBytes(value) {
1254
- const buffer = new ArrayBuffer(8);
1255
- const view = new DataView(buffer);
1256
- if (typeof value === "number") {
1257
- view.setFloat64(0, value, false);
637
+ // Validate topic name field
638
+ if (fields[2].length == 0) {
639
+ throw new Error(`Topic name field cannot be empty: ${contentTopic}`);
1258
640
  }
1259
- else {
1260
- view.setBigInt64(0, value, false);
641
+ // Validate encoding field
642
+ if (fields[3].length == 0) {
643
+ throw new Error(`Encoding field cannot be empty: ${contentTopic}`);
1261
644
  }
1262
- return new Uint8Array(buffer);
645
+ return {
646
+ generation,
647
+ application: fields[0],
648
+ version: fields[1],
649
+ topicName: fields[2],
650
+ encoding: fields[3]
651
+ };
1263
652
  }
1264
653
  /**
1265
- * Convert byte array to hex string (no `0x` prefix).
1266
- */
1267
- const bytesToHex = (bytes) => toString(bytes, "base16");
1268
- /**
1269
- * Decode byte array to utf-8 string.
1270
- */
1271
- const bytesToUtf8 = (b) => toString(b, "utf8");
1272
- /**
1273
- * Encode utf-8 string to byte array.
1274
- */
1275
- const utf8ToBytes = (s) => fromString(s, "utf8");
1276
- /**
1277
- * Concatenate using Uint8Arrays as `Buffer` has a different behavior with `DataView`
654
+ * Given a string, determines which autoshard index to use for its pubsub topic.
655
+ * Based on the algorithm described in the RFC: https://rfc.vac.dev/spec/51//#algorithm
1278
656
  */
1279
- function concat$1(byteArrays, totalLength) {
1280
- const len = byteArrays.reduce((acc, curr) => acc + curr.length, 0);
1281
- const res = new Uint8Array(len);
1282
- let offset = 0;
1283
- for (const bytes of byteArrays) {
1284
- res.set(bytes, offset);
1285
- offset += bytes.length;
1286
- }
1287
- return res;
1288
- }
1289
-
1290
- function isAutoSharding(config) {
1291
- return "clusterId" in config && "numShardsInCluster" in config;
657
+ function contentTopicToShardIndex(contentTopic, numShardsInCluster) {
658
+ const { application, version } = ensureValidContentTopic(contentTopic);
659
+ const digest = sha256$1(concat$1([utf8ToBytes(application), utf8ToBytes(version)]));
660
+ const dataview = new DataView(digest.buffer.slice(-8));
661
+ return Number(dataview.getBigUint64(0, false) % BigInt(numShardsInCluster));
1292
662
  }
1293
663
 
1294
664
  class BaseRoutingInfo {
@@ -1401,86 +771,6 @@ function createRoutingInfo(networkConfig, options) {
1401
771
  }
1402
772
  }
1403
773
 
1404
- const formatPubsubTopic = (clusterId, shard) => {
1405
- return `/waku/2/rs/${clusterId}/${shard}`;
1406
- };
1407
- /**
1408
- * @deprecated will be removed
1409
- */
1410
- const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
1411
- const parts = pubsubTopics.split("/");
1412
- if (parts.length != 6 ||
1413
- parts[1] !== "waku" ||
1414
- parts[2] !== "2" ||
1415
- parts[3] !== "rs")
1416
- throw new Error("Invalid pubsub topic");
1417
- const clusterId = parseInt(parts[4]);
1418
- const shard = parseInt(parts[5]);
1419
- if (isNaN(clusterId) || isNaN(shard))
1420
- throw new Error("Invalid clusterId or shard");
1421
- return {
1422
- clusterId,
1423
- shard
1424
- };
1425
- };
1426
- /**
1427
- * Given a string, will throw an error if it is not formatted as a valid content topic for autosharding based on https://rfc.vac.dev/spec/51/
1428
- * @param contentTopic String to validate
1429
- * @returns Object with each content topic field as an attribute
1430
- */
1431
- function ensureValidContentTopic(contentTopic) {
1432
- const parts = contentTopic.split("/");
1433
- if (parts.length < 5 || parts.length > 6) {
1434
- throw Error(`Content topic format is invalid: ${contentTopic}`);
1435
- }
1436
- // Validate generation field if present
1437
- let generation = 0;
1438
- if (parts.length == 6) {
1439
- generation = parseInt(parts[1]);
1440
- if (isNaN(generation)) {
1441
- throw new Error(`Invalid generation field in content topic: ${contentTopic}`);
1442
- }
1443
- if (generation > 0) {
1444
- throw new Error(`Generation greater than 0 is not supported: ${contentTopic}`);
1445
- }
1446
- }
1447
- // Validate remaining fields
1448
- const fields = parts.splice(-4);
1449
- // Validate application field
1450
- if (fields[0].length == 0) {
1451
- throw new Error(`Application field cannot be empty: ${contentTopic}`);
1452
- }
1453
- // Validate version field
1454
- if (fields[1].length == 0) {
1455
- throw new Error(`Version field cannot be empty: ${contentTopic}`);
1456
- }
1457
- // Validate topic name field
1458
- if (fields[2].length == 0) {
1459
- throw new Error(`Topic name field cannot be empty: ${contentTopic}`);
1460
- }
1461
- // Validate encoding field
1462
- if (fields[3].length == 0) {
1463
- throw new Error(`Encoding field cannot be empty: ${contentTopic}`);
1464
- }
1465
- return {
1466
- generation,
1467
- application: fields[0],
1468
- version: fields[1],
1469
- topicName: fields[2],
1470
- encoding: fields[3]
1471
- };
1472
- }
1473
- /**
1474
- * Given a string, determines which autoshard index to use for its pubsub topic.
1475
- * Based on the algorithm described in the RFC: https://rfc.vac.dev/spec/51//#algorithm
1476
- */
1477
- function contentTopicToShardIndex(contentTopic, numShardsInCluster) {
1478
- const { application, version } = ensureValidContentTopic(contentTopic);
1479
- const digest = sha256(concat$1([utf8ToBytes(application), utf8ToBytes(version)]));
1480
- const dataview = new DataView(digest.buffer.slice(-8));
1481
- return Number(dataview.getBigUint64(0, false) % BigInt(numShardsInCluster));
1482
- }
1483
-
1484
774
  const decodeRelayShard = (bytes) => {
1485
775
  // explicitly converting to Uint8Array to avoid Buffer
1486
776
  // https://github.com/libp2p/js-libp2p/issues/2146
@@ -1535,11 +825,105 @@ const encodeRelayShard = (shardInfo) => {
1535
825
  return new Uint8Array(buffer);
1536
826
  };
1537
827
 
828
+ /**
829
+ * All PeerId implementations must use this symbol as the name of a property
830
+ * with a boolean `true` value
831
+ */
832
+ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
833
+ /**
834
+ * Returns true if the passed argument is a PeerId implementation
835
+ */
836
+ function isPeerId(other) {
837
+ return Boolean(other?.[peerIdSymbol]);
838
+ }
839
+
840
+ /**
841
+ * When this error is thrown it means an operation was aborted,
842
+ * usually in response to the `abort` event being emitted by an
843
+ * AbortSignal.
844
+ */
845
+ /**
846
+ * Thrown when invalid parameters are passed to a function or method call
847
+ */
848
+ let InvalidParametersError$1 = class InvalidParametersError extends Error {
849
+ static name = 'InvalidParametersError';
850
+ constructor(message = 'Invalid parameters') {
851
+ super(message);
852
+ this.name = 'InvalidParametersError';
853
+ }
854
+ };
855
+ /**
856
+ * Thrown when a public key is invalid
857
+ */
858
+ class InvalidPublicKeyError extends Error {
859
+ static name = 'InvalidPublicKeyError';
860
+ constructor(message = 'Invalid public key') {
861
+ super(message);
862
+ this.name = 'InvalidPublicKeyError';
863
+ }
864
+ }
865
+ /**
866
+ * Thrown when an invalid CID is encountered
867
+ */
868
+ class InvalidCIDError extends Error {
869
+ static name = 'InvalidCIDError';
870
+ constructor(message = 'Invalid CID') {
871
+ super(message);
872
+ this.name = 'InvalidCIDError';
873
+ }
874
+ }
875
+ /**
876
+ * Thrown when an invalid multihash is encountered
877
+ */
878
+ class InvalidMultihashError extends Error {
879
+ static name = 'InvalidMultihashError';
880
+ constructor(message = 'Invalid Multihash') {
881
+ super(message);
882
+ this.name = 'InvalidMultihashError';
883
+ }
884
+ }
885
+ /**
886
+ * Thrown when an attempt to operate on an unsupported key was made
887
+ */
888
+ class UnsupportedKeyTypeError extends Error {
889
+ static name = 'UnsupportedKeyTypeError';
890
+ constructor(message = 'Unsupported key type') {
891
+ super(message);
892
+ this.name = 'UnsupportedKeyTypeError';
893
+ }
894
+ }
895
+
1538
896
  var index$3 = /*#__PURE__*/Object.freeze({
1539
897
  __proto__: null,
1540
898
  version_0: version_0
1541
899
  });
1542
900
 
901
+ var LightPushStatusCode;
902
+ (function (LightPushStatusCode) {
903
+ LightPushStatusCode[LightPushStatusCode["SUCCESS"] = 200] = "SUCCESS";
904
+ LightPushStatusCode[LightPushStatusCode["BAD_REQUEST"] = 400] = "BAD_REQUEST";
905
+ LightPushStatusCode[LightPushStatusCode["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
906
+ LightPushStatusCode[LightPushStatusCode["INVALID_MESSAGE"] = 420] = "INVALID_MESSAGE";
907
+ LightPushStatusCode[LightPushStatusCode["UNSUPPORTED_TOPIC"] = 421] = "UNSUPPORTED_TOPIC";
908
+ LightPushStatusCode[LightPushStatusCode["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
909
+ LightPushStatusCode[LightPushStatusCode["INTERNAL_ERROR"] = 500] = "INTERNAL_ERROR";
910
+ LightPushStatusCode[LightPushStatusCode["UNAVAILABLE"] = 503] = "UNAVAILABLE";
911
+ LightPushStatusCode[LightPushStatusCode["NO_RLN_PROOF"] = 504] = "NO_RLN_PROOF";
912
+ LightPushStatusCode[LightPushStatusCode["NO_PEERS"] = 505] = "NO_PEERS";
913
+ })(LightPushStatusCode || (LightPushStatusCode = {}));
914
+ ({
915
+ [LightPushStatusCode.SUCCESS]: "Message sent successfully",
916
+ [LightPushStatusCode.BAD_REQUEST]: "Bad request format",
917
+ [LightPushStatusCode.PAYLOAD_TOO_LARGE]: "Message payload exceeds maximum size",
918
+ [LightPushStatusCode.INVALID_MESSAGE]: "Message validation failed",
919
+ [LightPushStatusCode.UNSUPPORTED_TOPIC]: "Unsupported pubsub topic",
920
+ [LightPushStatusCode.TOO_MANY_REQUESTS]: "Rate limit exceeded",
921
+ [LightPushStatusCode.INTERNAL_ERROR]: "Internal server error",
922
+ [LightPushStatusCode.UNAVAILABLE]: "Service temporarily unavailable",
923
+ [LightPushStatusCode.NO_RLN_PROOF]: "RLN proof generation failed",
924
+ [LightPushStatusCode.NO_PEERS]: "No relay peers available"
925
+ });
926
+
1543
927
  var Protocols;
1544
928
  (function (Protocols) {
1545
929
  Protocols["Relay"] = "relay";
@@ -1547,90 +931,80 @@ var Protocols;
1547
931
  Protocols["LightPush"] = "lightpush";
1548
932
  Protocols["Filter"] = "filter";
1549
933
  })(Protocols || (Protocols = {}));
934
+ var LightPushError;
935
+ (function (LightPushError) {
936
+ LightPushError["GENERIC_FAIL"] = "Generic error";
937
+ LightPushError["DECODE_FAILED"] = "Failed to decode";
938
+ LightPushError["NO_PEER_AVAILABLE"] = "No peer available";
939
+ LightPushError["NO_STREAM_AVAILABLE"] = "No stream available";
940
+ LightPushError["NO_RESPONSE"] = "No response received";
941
+ LightPushError["STREAM_ABORTED"] = "Stream aborted";
942
+ LightPushError["ENCODE_FAILED"] = "Failed to encode";
943
+ LightPushError["EMPTY_PAYLOAD"] = "Payload is empty";
944
+ LightPushError["SIZE_TOO_BIG"] = "Size is too big";
945
+ LightPushError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
946
+ LightPushError["RLN_PROOF_GENERATION"] = "Proof generation failed";
947
+ LightPushError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
948
+ LightPushError["BAD_REQUEST"] = "Bad request format";
949
+ LightPushError["PAYLOAD_TOO_LARGE"] = "Message payload exceeds maximum size";
950
+ LightPushError["INVALID_MESSAGE"] = "Message validation failed";
951
+ LightPushError["UNSUPPORTED_TOPIC"] = "Unsupported pubsub topic";
952
+ LightPushError["TOO_MANY_REQUESTS"] = "Rate limit exceeded";
953
+ LightPushError["INTERNAL_ERROR"] = "Internal server error";
954
+ LightPushError["UNAVAILABLE"] = "Service temporarily unavailable";
955
+ LightPushError["NO_RLN_PROOF"] = "RLN proof generation failed";
956
+ LightPushError["NO_PEERS"] = "No relay peers available";
957
+ })(LightPushError || (LightPushError = {}));
958
+ var FilterError;
959
+ (function (FilterError) {
960
+ // General errors
961
+ FilterError["GENERIC_FAIL"] = "Generic error";
962
+ FilterError["DECODE_FAILED"] = "Failed to decode";
963
+ FilterError["NO_PEER_AVAILABLE"] = "No peer available";
964
+ FilterError["NO_STREAM_AVAILABLE"] = "No stream available";
965
+ FilterError["NO_RESPONSE"] = "No response received";
966
+ FilterError["STREAM_ABORTED"] = "Stream aborted";
967
+ // Filter specific errors
968
+ FilterError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
969
+ FilterError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
970
+ FilterError["SUBSCRIPTION_FAILED"] = "Subscription failed";
971
+ FilterError["UNSUBSCRIBE_FAILED"] = "Unsubscribe failed";
972
+ FilterError["PING_FAILED"] = "Ping failed";
973
+ FilterError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
974
+ FilterError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
975
+ FilterError["SUBSCRIPTION_LIMIT_EXCEEDED"] = "Subscription limit exceeded";
976
+ FilterError["INVALID_CONTENT_TOPIC"] = "Invalid content topic";
977
+ FilterError["PUSH_MESSAGE_FAILED"] = "Push message failed";
978
+ FilterError["EMPTY_MESSAGE"] = "Empty message received";
979
+ FilterError["MISSING_PUBSUB_TOPIC"] = "Pubsub topic missing from push message";
980
+ })(FilterError || (FilterError = {}));
981
+ /**
982
+ * @deprecated replace usage by specific result types
983
+ */
1550
984
  var ProtocolError;
1551
985
  (function (ProtocolError) {
1552
- //
1553
- // GENERAL ERRORS SECTION
1554
- //
1555
- /**
1556
- * Could not determine the origin of the fault. Best to check connectivity and try again
1557
- * */
1558
986
  ProtocolError["GENERIC_FAIL"] = "Generic error";
1559
- /**
1560
- * The remote peer rejected the message. Information provided by the remote peer
1561
- * is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
1562
- * or `DECODE_FAILED` can be used.
1563
- */
1564
987
  ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
1565
- /**
1566
- * Failure to protobuf decode the message. May be due to a remote peer issue,
1567
- * ensuring that messages are sent via several peer enable mitigation of this error.
1568
- */
1569
988
  ProtocolError["DECODE_FAILED"] = "Failed to decode";
1570
- /**
1571
- * Failure to find a peer with suitable protocols. This may due to a connection issue.
1572
- * Mitigation can be: retrying after a given time period, display connectivity issue
1573
- * to user or listening for `peer:connected:bootstrap` or `peer:connected:peer-exchange`
1574
- * on the connection manager before retrying.
1575
- */
1576
989
  ProtocolError["NO_PEER_AVAILABLE"] = "No peer available";
1577
- /**
1578
- * Failure to find a stream to the peer. This may be because the connection with the peer is not still alive.
1579
- * Mitigation can be: retrying after a given time period, or mitigation for `NO_PEER_AVAILABLE` can be used.
1580
- */
1581
990
  ProtocolError["NO_STREAM_AVAILABLE"] = "No stream available";
1582
- /**
1583
- * The remote peer did not behave as expected. Mitigation for `NO_PEER_AVAILABLE`
1584
- * or `DECODE_FAILED` can be used.
1585
- */
1586
991
  ProtocolError["NO_RESPONSE"] = "No response received";
1587
- //
1588
- // SEND ERRORS SECTION
1589
- //
1590
- /**
1591
- * Failure to protobuf encode the message. This is not recoverable and needs
1592
- * further investigation.
1593
- */
1594
992
  ProtocolError["ENCODE_FAILED"] = "Failed to encode";
1595
- /**
1596
- * The message payload is empty, making the message invalid. Ensure that a non-empty
1597
- * payload is set on the outgoing message.
1598
- */
1599
993
  ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
1600
- /**
1601
- * The message size is above the maximum message size allowed on the Waku Network.
1602
- * Compressing the message or using an alternative strategy for large messages is recommended.
1603
- */
1604
994
  ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
1605
- /**
1606
- * The PubsubTopic passed to the send function is not configured on the Waku node.
1607
- * Please ensure that the PubsubTopic is used when initializing the Waku node.
1608
- */
1609
995
  ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
1610
- /**
1611
- * Fails when
1612
- */
1613
996
  ProtocolError["STREAM_ABORTED"] = "Stream aborted";
1614
- /**
1615
- * General proof generation error message.
1616
- * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
1617
- */
1618
997
  ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
1619
- //
1620
- // RECEIVE ERRORS SECTION
1621
- //
1622
- /**
1623
- * The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
1624
- * Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
1625
- */
1626
998
  ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
1627
- /**
1628
- * The topics passed in the decoders do not match each other, or don't exist at all.
1629
- * Ensure that all the pubsub topics used in the decoders are valid and match each other.
1630
- */
1631
999
  ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
1632
1000
  })(ProtocolError || (ProtocolError = {}));
1633
1001
 
1002
+ var WakuEvent;
1003
+ (function (WakuEvent) {
1004
+ WakuEvent["Connection"] = "waku:connection";
1005
+ WakuEvent["Health"] = "waku:health";
1006
+ })(WakuEvent || (WakuEvent = {}));
1007
+
1634
1008
  // Peer tags
1635
1009
  var Tags;
1636
1010
  (function (Tags) {
@@ -3505,25 +2879,38 @@ class FilterSubscribeResponse {
3505
2879
  }
3506
2880
  }
3507
2881
 
3508
- const log$9 = new Logger("filter-core");
2882
+ const log$a = new Logger("filter-core");
3509
2883
  const FilterCodecs = {
3510
2884
  SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
3511
2885
  PUSH: "/vac/waku/filter-push/2.0.0-beta1"
3512
2886
  };
3513
2887
  class FilterCore {
3514
2888
  handleIncomingMessage;
2889
+ libp2p;
3515
2890
  streamManager;
3516
2891
  multicodec = FilterCodecs.SUBSCRIBE;
3517
2892
  constructor(handleIncomingMessage, libp2p) {
3518
2893
  this.handleIncomingMessage = handleIncomingMessage;
2894
+ this.libp2p = libp2p;
3519
2895
  this.streamManager = new StreamManager(FilterCodecs.SUBSCRIBE, libp2p.components);
3520
- libp2p
3521
- .handle(FilterCodecs.PUSH, this.onRequest.bind(this), {
3522
- maxInboundStreams: 100
3523
- })
3524
- .catch((e) => {
3525
- log$9.error("Failed to register ", FilterCodecs.PUSH, e);
3526
- });
2896
+ }
2897
+ async start() {
2898
+ try {
2899
+ await this.libp2p.handle(FilterCodecs.PUSH, this.onRequest.bind(this), {
2900
+ maxInboundStreams: 100
2901
+ });
2902
+ }
2903
+ catch (e) {
2904
+ log$a.error("Failed to register ", FilterCodecs.PUSH, e);
2905
+ }
2906
+ }
2907
+ async stop() {
2908
+ try {
2909
+ await this.libp2p.unhandle(FilterCodecs.PUSH);
2910
+ }
2911
+ catch (e) {
2912
+ log$a.error("Failed to unregister ", FilterCodecs.PUSH, e);
2913
+ }
3527
2914
  }
3528
2915
  async subscribe(pubsubTopic, peerId, contentTopics) {
3529
2916
  const stream = await this.streamManager.getStream(peerId);
@@ -3531,7 +2918,7 @@ class FilterCore {
3531
2918
  return {
3532
2919
  success: null,
3533
2920
  failure: {
3534
- error: ProtocolError.NO_STREAM_AVAILABLE,
2921
+ error: FilterError.NO_STREAM_AVAILABLE,
3535
2922
  peerId: peerId
3536
2923
  }
3537
2924
  };
@@ -3545,21 +2932,21 @@ class FilterCore {
3545
2932
  }
3546
2933
  }
3547
2934
  catch (error) {
3548
- log$9.error("Failed to send subscribe request", error);
2935
+ log$a.error("Failed to send subscribe request", error);
3549
2936
  return {
3550
2937
  success: null,
3551
2938
  failure: {
3552
- error: ProtocolError.GENERIC_FAIL,
2939
+ error: FilterError.GENERIC_FAIL,
3553
2940
  peerId: peerId
3554
2941
  }
3555
2942
  };
3556
2943
  }
3557
2944
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
3558
2945
  if (statusCode < 200 || statusCode >= 300) {
3559
- log$9.error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
2946
+ log$a.error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
3560
2947
  return {
3561
2948
  failure: {
3562
- error: ProtocolError.REMOTE_PEER_REJECTED,
2949
+ error: FilterError.REMOTE_PEER_REJECTED,
3563
2950
  peerId: peerId
3564
2951
  },
3565
2952
  success: null
@@ -3573,11 +2960,11 @@ class FilterCore {
3573
2960
  async unsubscribe(pubsubTopic, peerId, contentTopics) {
3574
2961
  const stream = await this.streamManager.getStream(peerId);
3575
2962
  if (!stream) {
3576
- log$9.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
2963
+ log$a.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
3577
2964
  return {
3578
2965
  success: null,
3579
2966
  failure: {
3580
- error: ProtocolError.NO_STREAM_AVAILABLE,
2967
+ error: FilterError.NO_STREAM_AVAILABLE,
3581
2968
  peerId: peerId
3582
2969
  }
3583
2970
  };
@@ -3587,11 +2974,11 @@ class FilterCore {
3587
2974
  await pipe([unsubscribeRequest.encode()], encode, stream.sink);
3588
2975
  }
3589
2976
  catch (error) {
3590
- log$9.error("Failed to send unsubscribe request", error);
2977
+ log$a.error("Failed to send unsubscribe request", error);
3591
2978
  return {
3592
2979
  success: null,
3593
2980
  failure: {
3594
- error: ProtocolError.GENERIC_FAIL,
2981
+ error: FilterError.GENERIC_FAIL,
3595
2982
  peerId: peerId
3596
2983
  }
3597
2984
  };
@@ -3604,11 +2991,11 @@ class FilterCore {
3604
2991
  async unsubscribeAll(pubsubTopic, peerId) {
3605
2992
  const stream = await this.streamManager.getStream(peerId);
3606
2993
  if (!stream) {
3607
- log$9.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
2994
+ log$a.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
3608
2995
  return {
3609
2996
  success: null,
3610
2997
  failure: {
3611
- error: ProtocolError.NO_STREAM_AVAILABLE,
2998
+ error: FilterError.NO_STREAM_AVAILABLE,
3612
2999
  peerId: peerId
3613
3000
  }
3614
3001
  };
@@ -3618,7 +3005,7 @@ class FilterCore {
3618
3005
  if (!res || !res.length) {
3619
3006
  return {
3620
3007
  failure: {
3621
- error: ProtocolError.NO_RESPONSE,
3008
+ error: FilterError.NO_RESPONSE,
3622
3009
  peerId: peerId
3623
3010
  },
3624
3011
  success: null
@@ -3626,10 +3013,10 @@ class FilterCore {
3626
3013
  }
3627
3014
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
3628
3015
  if (statusCode < 200 || statusCode >= 300) {
3629
- log$9.error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
3016
+ log$a.error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
3630
3017
  return {
3631
3018
  failure: {
3632
- error: ProtocolError.REMOTE_PEER_REJECTED,
3019
+ error: FilterError.REMOTE_PEER_REJECTED,
3633
3020
  peerId: peerId
3634
3021
  },
3635
3022
  success: null
@@ -3643,11 +3030,11 @@ class FilterCore {
3643
3030
  async ping(peerId) {
3644
3031
  const stream = await this.streamManager.getStream(peerId);
3645
3032
  if (!stream) {
3646
- log$9.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
3033
+ log$a.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
3647
3034
  return {
3648
3035
  success: null,
3649
3036
  failure: {
3650
- error: ProtocolError.NO_STREAM_AVAILABLE,
3037
+ error: FilterError.NO_STREAM_AVAILABLE,
3651
3038
  peerId: peerId
3652
3039
  }
3653
3040
  };
@@ -3658,11 +3045,11 @@ class FilterCore {
3658
3045
  res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
3659
3046
  }
3660
3047
  catch (error) {
3661
- log$9.error("Failed to send ping request", error);
3048
+ log$a.error("Failed to send ping request", error);
3662
3049
  return {
3663
3050
  success: null,
3664
3051
  failure: {
3665
- error: ProtocolError.GENERIC_FAIL,
3052
+ error: FilterError.GENERIC_FAIL,
3666
3053
  peerId: peerId
3667
3054
  }
3668
3055
  };
@@ -3671,18 +3058,18 @@ class FilterCore {
3671
3058
  return {
3672
3059
  success: null,
3673
3060
  failure: {
3674
- error: ProtocolError.NO_RESPONSE,
3061
+ error: FilterError.NO_RESPONSE,
3675
3062
  peerId: peerId
3676
3063
  }
3677
3064
  };
3678
3065
  }
3679
3066
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
3680
3067
  if (statusCode < 200 || statusCode >= 300) {
3681
- log$9.error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
3068
+ log$a.error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
3682
3069
  return {
3683
3070
  success: null,
3684
3071
  failure: {
3685
- error: ProtocolError.REMOTE_PEER_REJECTED,
3072
+ error: FilterError.REMOTE_PEER_REJECTED,
3686
3073
  peerId: peerId
3687
3074
  }
3688
3075
  };
@@ -3695,30 +3082,30 @@ class FilterCore {
3695
3082
  onRequest(streamData) {
3696
3083
  const { connection, stream } = streamData;
3697
3084
  const { remotePeer } = connection;
3698
- log$9.info(`Received message from ${remotePeer.toString()}`);
3085
+ log$a.info(`Received message from ${remotePeer.toString()}`);
3699
3086
  try {
3700
3087
  pipe(stream, decode, async (source) => {
3701
3088
  for await (const bytes of source) {
3702
3089
  const response = FilterPushRpc.decode(bytes.slice());
3703
3090
  const { pubsubTopic, wakuMessage } = response;
3704
3091
  if (!wakuMessage) {
3705
- log$9.error("Received empty message");
3092
+ log$a.error("Received empty message");
3706
3093
  return;
3707
3094
  }
3708
3095
  if (!pubsubTopic) {
3709
- log$9.error("Pubsub topic missing from push message");
3096
+ log$a.error("Pubsub topic missing from push message");
3710
3097
  return;
3711
3098
  }
3712
3099
  await this.handleIncomingMessage(pubsubTopic, wakuMessage, connection.remotePeer.toString());
3713
3100
  }
3714
3101
  }).then(() => {
3715
- log$9.info("Receiving pipe closed.");
3102
+ log$a.info("Receiving pipe closed.");
3716
3103
  }, async (e) => {
3717
- log$9.error(`Error with receiving pipe on peer:${connection.remotePeer.toString()} -- stream:${stream.id} -- protocol:${stream.protocol}: `, e);
3104
+ log$a.error(`Error with receiving pipe on peer:${connection.remotePeer.toString()} -- stream:${stream.id} -- protocol:${stream.protocol}: `, e);
3718
3105
  });
3719
3106
  }
3720
3107
  catch (e) {
3721
- log$9.error("Error decoding message", e);
3108
+ log$a.error("Error decoding message", e);
3722
3109
  }
3723
3110
  }
3724
3111
  }
@@ -3729,13 +3116,20 @@ var index$2 = /*#__PURE__*/Object.freeze({
3729
3116
  FilterCore: FilterCore
3730
3117
  });
3731
3118
 
3732
- class PushRpc {
3119
+ const CODECS = {
3120
+ v2: "/vac/waku/lightpush/2.0.0-beta1",
3121
+ v3: "/vac/waku/lightpush/3.0.0"
3122
+ };
3123
+ const LightPushCodecV2 = CODECS.v2;
3124
+ const LightPushCodec = CODECS.v3;
3125
+
3126
+ class PushRpcV2 {
3733
3127
  proto;
3734
3128
  constructor(proto) {
3735
3129
  this.proto = proto;
3736
3130
  }
3737
3131
  static createRequest(message, pubsubTopic) {
3738
- return new PushRpc({
3132
+ return new PushRpcV2({
3739
3133
  requestId: v4(),
3740
3134
  request: {
3741
3135
  message: message,
@@ -3744,18 +3138,152 @@ class PushRpc {
3744
3138
  response: undefined
3745
3139
  });
3746
3140
  }
3747
- static decode(bytes) {
3748
- const res = PushRpc$1.decode(bytes);
3141
+ static decode(bytes) {
3142
+ const res = PushRpc$1.decode(bytes);
3143
+ return new PushRpcV2(res);
3144
+ }
3145
+ encode() {
3146
+ return PushRpc$1.encode(this.proto);
3147
+ }
3148
+ get query() {
3149
+ return this.proto.request;
3150
+ }
3151
+ get response() {
3152
+ return this.proto.response;
3153
+ }
3154
+ }
3155
+
3156
+ /**
3157
+ * LightPush v3 protocol RPC handler.
3158
+ * Implements the v3 message format with correct field numbers:
3159
+ * - requestId: 1
3160
+ * - pubsubTopic: 20
3161
+ * - message: 21
3162
+ */
3163
+ class PushRpc {
3164
+ proto;
3165
+ constructor(proto) {
3166
+ this.proto = proto;
3167
+ }
3168
+ /**
3169
+ * Create a v3 request message with proper field numbering
3170
+ */
3171
+ static createRequest(message, pubsubTopic) {
3172
+ return new PushRpc({
3173
+ requestId: v4(),
3174
+ pubsubTopic: pubsubTopic,
3175
+ message: message
3176
+ });
3177
+ }
3178
+ /**
3179
+ * Create a v3 response message with status code handling
3180
+ */
3181
+ static createResponse(requestId, statusCode, statusDesc, relayPeerCount) {
3182
+ return new PushRpc({
3183
+ requestId,
3184
+ statusCode,
3185
+ statusDesc,
3186
+ relayPeerCount
3187
+ });
3188
+ }
3189
+ /**
3190
+ * Decode v3 request message
3191
+ */
3192
+ static decodeRequest(bytes) {
3193
+ const res = LightPushRequestV3.decode(bytes);
3194
+ return new PushRpc(res);
3195
+ }
3196
+ /**
3197
+ * Decode v3 response message
3198
+ */
3199
+ static decodeResponse(bytes) {
3200
+ const res = LightPushResponseV3.decode(bytes);
3749
3201
  return new PushRpc(res);
3750
3202
  }
3203
+ /**
3204
+ * Encode message to bytes
3205
+ */
3751
3206
  encode() {
3752
- return PushRpc$1.encode(this.proto);
3207
+ if (this.isRequest()) {
3208
+ return LightPushRequestV3.encode(this.proto);
3209
+ }
3210
+ else {
3211
+ return LightPushResponseV3.encode(this.proto);
3212
+ }
3753
3213
  }
3754
- get query() {
3755
- return this.proto.request;
3214
+ /**
3215
+ * Get request data (if this is a request message)
3216
+ */
3217
+ get request() {
3218
+ return this.isRequest()
3219
+ ? this.proto
3220
+ : undefined;
3756
3221
  }
3222
+ /**
3223
+ * Get response data (if this is a response message)
3224
+ */
3757
3225
  get response() {
3758
- return this.proto.response;
3226
+ return this.isResponse()
3227
+ ? this.proto
3228
+ : undefined;
3229
+ }
3230
+ /**
3231
+ * Get the request ID
3232
+ */
3233
+ get requestId() {
3234
+ return this.proto.requestId;
3235
+ }
3236
+ /**
3237
+ * Get the pubsub topic (only available in requests)
3238
+ */
3239
+ get pubsubTopic() {
3240
+ return this.isRequest()
3241
+ ? this.proto.pubsubTopic
3242
+ : undefined;
3243
+ }
3244
+ /**
3245
+ * Get the message (only available in requests)
3246
+ */
3247
+ get message() {
3248
+ return this.isRequest()
3249
+ ? this.proto.message
3250
+ : undefined;
3251
+ }
3252
+ /**
3253
+ * Get the status code (only available in responses)
3254
+ */
3255
+ get statusCode() {
3256
+ return this.isResponse()
3257
+ ? this.proto.statusCode
3258
+ : undefined;
3259
+ }
3260
+ /**
3261
+ * Get the status description (only available in responses)
3262
+ */
3263
+ get statusDesc() {
3264
+ return this.isResponse()
3265
+ ? this.proto.statusDesc
3266
+ : undefined;
3267
+ }
3268
+ /**
3269
+ * Get the relay peer count (only available in responses)
3270
+ */
3271
+ get relayPeerCount() {
3272
+ return this.isResponse()
3273
+ ? this.proto.relayPeerCount
3274
+ : undefined;
3275
+ }
3276
+ /**
3277
+ * Check if this is a request message
3278
+ */
3279
+ isRequest() {
3280
+ return "pubsubTopic" in this.proto && "message" in this.proto;
3281
+ }
3282
+ /**
3283
+ * Check if this is a response message
3284
+ */
3285
+ isResponse() {
3286
+ return "statusCode" in this.proto;
3759
3287
  }
3760
3288
  }
3761
3289
 
@@ -3777,140 +3305,251 @@ const isRLNResponseError = (info) => {
3777
3305
  info.includes(RLN_REMOTE_VALIDATION));
3778
3306
  };
3779
3307
 
3780
- const log$8 = new Logger("light-push");
3781
- const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
3782
- /**
3783
- * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
3784
- */
3785
- class LightPushCore {
3786
- streamManager;
3787
- multicodec = LightPushCodec;
3788
- constructor(libp2p) {
3789
- this.streamManager = new StreamManager(LightPushCodec, libp2p.components);
3790
- }
3791
- async preparePushMessage(encoder, message) {
3308
+ const log$9 = new Logger("light-push:protocol-handler");
3309
+ class ProtocolHandler {
3310
+ static async preparePushMessage(encoder, message, protocol) {
3792
3311
  try {
3793
3312
  if (!message.payload || message.payload.length === 0) {
3794
- log$8.error("Failed to send waku light push: payload is empty");
3795
- return { query: null, error: ProtocolError.EMPTY_PAYLOAD };
3313
+ log$9.error("Failed to send waku light push: payload is empty");
3314
+ return { rpc: null, error: LightPushError.EMPTY_PAYLOAD };
3796
3315
  }
3797
3316
  if (!(await isMessageSizeUnderCap(encoder, message))) {
3798
- log$8.error("Failed to send waku light push: message is bigger than 1MB");
3799
- return { query: null, error: ProtocolError.SIZE_TOO_BIG };
3317
+ log$9.error("Failed to send waku light push: message is bigger than 1MB");
3318
+ return { rpc: null, error: LightPushError.SIZE_TOO_BIG };
3800
3319
  }
3801
3320
  const protoMessage = await encoder.toProtoObj(message);
3802
3321
  if (!protoMessage) {
3803
- log$8.error("Failed to encode to protoMessage, aborting push");
3322
+ log$9.error("Failed to encode to protoMessage, aborting push");
3323
+ return { rpc: null, error: LightPushError.ENCODE_FAILED };
3324
+ }
3325
+ if (protocol === CODECS.v3) {
3326
+ log$9.info("Creating v3 RPC message");
3327
+ return {
3328
+ rpc: ProtocolHandler.createV3Rpc(protoMessage, encoder.pubsubTopic),
3329
+ error: null
3330
+ };
3331
+ }
3332
+ log$9.info("Creating v2 RPC message");
3333
+ return {
3334
+ rpc: ProtocolHandler.createV2Rpc(protoMessage, encoder.pubsubTopic),
3335
+ error: null
3336
+ };
3337
+ }
3338
+ catch (err) {
3339
+ log$9.error("Failed to prepare push message", err);
3340
+ return { rpc: null, error: LightPushError.GENERIC_FAIL };
3341
+ }
3342
+ }
3343
+ /**
3344
+ * Decode and evaluate a LightPush response according to the protocol version
3345
+ */
3346
+ static handleResponse(bytes, protocol, peerId) {
3347
+ if (protocol === CODECS.v3) {
3348
+ return ProtocolHandler.handleV3Response(bytes, peerId);
3349
+ }
3350
+ return ProtocolHandler.handleV2Response(bytes, peerId);
3351
+ }
3352
+ static handleV3Response(bytes, peerId) {
3353
+ try {
3354
+ const decodedRpcV3 = PushRpc.decodeResponse(bytes);
3355
+ const statusCode = decodedRpcV3.statusCode;
3356
+ const statusDesc = decodedRpcV3.statusDesc;
3357
+ if (statusCode !== LightPushStatusCode.SUCCESS) {
3358
+ const error = LightPushError.REMOTE_PEER_REJECTED;
3359
+ log$9.error(`Remote peer rejected with v3 status code ${statusCode}: ${statusDesc}`);
3804
3360
  return {
3805
- query: null,
3806
- error: ProtocolError.ENCODE_FAILED
3361
+ success: null,
3362
+ failure: {
3363
+ error,
3364
+ peerId: peerId
3365
+ }
3807
3366
  };
3808
3367
  }
3809
- const query = PushRpc.createRequest(protoMessage, encoder.pubsubTopic);
3810
- return { query, error: null };
3368
+ if (decodedRpcV3.relayPeerCount !== undefined) {
3369
+ log$9.info(`Message relayed to ${decodedRpcV3.relayPeerCount} peers`);
3370
+ }
3371
+ return { success: peerId, failure: null };
3811
3372
  }
3812
- catch (error) {
3813
- log$8.error("Failed to prepare push message", error);
3373
+ catch (err) {
3814
3374
  return {
3815
- query: null,
3816
- error: ProtocolError.GENERIC_FAIL
3375
+ success: null,
3376
+ failure: {
3377
+ error: LightPushError.DECODE_FAILED,
3378
+ peerId: peerId
3379
+ }
3817
3380
  };
3818
3381
  }
3819
3382
  }
3820
- async send(encoder, message, peerId) {
3821
- const { query, error: preparationError } = await this.preparePushMessage(encoder, message);
3822
- if (preparationError || !query) {
3383
+ static handleV2Response(bytes, peerId) {
3384
+ let response;
3385
+ try {
3386
+ const decodedRpc = PushRpcV2.decode(bytes);
3387
+ response = decodedRpc.response;
3388
+ }
3389
+ catch (err) {
3823
3390
  return {
3824
3391
  success: null,
3825
3392
  failure: {
3826
- error: preparationError,
3827
- peerId
3393
+ error: LightPushError.DECODE_FAILED,
3394
+ peerId: peerId
3828
3395
  }
3829
3396
  };
3830
3397
  }
3831
- const stream = await this.streamManager.getStream(peerId);
3832
- if (!stream) {
3833
- log$8.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
3398
+ if (!response) {
3834
3399
  return {
3835
3400
  success: null,
3836
3401
  failure: {
3837
- error: ProtocolError.NO_STREAM_AVAILABLE,
3402
+ error: LightPushError.NO_RESPONSE,
3838
3403
  peerId: peerId
3839
3404
  }
3840
3405
  };
3841
3406
  }
3842
- let res;
3843
- try {
3844
- res = await pipe([query.encode()], encode, stream, decode, async (source) => await all(source));
3407
+ if (isRLNResponseError(response.info)) {
3408
+ log$9.error("Remote peer fault: RLN generation");
3409
+ return {
3410
+ success: null,
3411
+ failure: {
3412
+ error: LightPushError.RLN_PROOF_GENERATION,
3413
+ peerId: peerId
3414
+ }
3415
+ };
3845
3416
  }
3846
- catch (err) {
3847
- // can fail only because of `stream` abortion
3848
- log$8.error("Failed to send waku light push request", err);
3417
+ if (!response.isSuccess) {
3418
+ log$9.error("Remote peer rejected the message: ", response.info);
3849
3419
  return {
3850
3420
  success: null,
3851
3421
  failure: {
3852
- error: ProtocolError.STREAM_ABORTED,
3422
+ error: LightPushError.REMOTE_PEER_REJECTED,
3853
3423
  peerId: peerId
3854
3424
  }
3855
3425
  };
3856
3426
  }
3857
- const bytes = new Uint8ArrayList();
3858
- res.forEach((chunk) => {
3859
- bytes.append(chunk);
3860
- });
3861
- let response;
3862
- try {
3863
- response = PushRpc.decode(bytes).response;
3427
+ return { success: peerId, failure: null };
3428
+ }
3429
+ static createV2Rpc(message, pubsubTopic) {
3430
+ const v2Rpc = PushRpcV2.createRequest(message, pubsubTopic);
3431
+ return Object.assign(v2Rpc, { version: "v2" });
3432
+ }
3433
+ static createV3Rpc(message, pubsubTopic) {
3434
+ if (!message.timestamp) {
3435
+ message.timestamp = BigInt(Date.now()) * BigInt(1_000_000);
3864
3436
  }
3865
- catch (err) {
3866
- log$8.error("Failed to decode push reply", err);
3437
+ const v3Rpc = PushRpc.createRequest(message, pubsubTopic);
3438
+ return Object.assign(v3Rpc, { version: "v3" });
3439
+ }
3440
+ }
3441
+
3442
+ const log$8 = new Logger("light-push");
3443
+ /**
3444
+ * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
3445
+ */
3446
+ class LightPushCore {
3447
+ libp2p;
3448
+ streamManager;
3449
+ streamManagerV2;
3450
+ multicodec = [CODECS.v3, CODECS.v2];
3451
+ constructor(libp2p) {
3452
+ this.libp2p = libp2p;
3453
+ this.streamManagerV2 = new StreamManager(CODECS.v2, libp2p.components);
3454
+ this.streamManager = new StreamManager(CODECS.v3, libp2p.components);
3455
+ }
3456
+ async send(encoder, message, peerId, useLegacy = false) {
3457
+ const protocol = await this.getProtocol(peerId, useLegacy);
3458
+ log$8.info(`Sending light push request to peer:${peerId.toString()}, protocol:${protocol}`);
3459
+ if (!protocol) {
3867
3460
  return {
3868
3461
  success: null,
3869
3462
  failure: {
3870
- error: ProtocolError.DECODE_FAILED,
3871
- peerId: peerId
3463
+ error: LightPushError.GENERIC_FAIL,
3464
+ peerId
3872
3465
  }
3873
3466
  };
3874
3467
  }
3875
- if (!response) {
3876
- log$8.error("Remote peer fault: No response in PushRPC");
3468
+ const { rpc, error: prepError } = await ProtocolHandler.preparePushMessage(encoder, message, protocol);
3469
+ if (prepError) {
3470
+ return {
3471
+ success: null,
3472
+ failure: {
3473
+ error: prepError,
3474
+ peerId
3475
+ }
3476
+ };
3477
+ }
3478
+ const stream = await this.getStream(peerId, protocol);
3479
+ if (!stream) {
3480
+ log$8.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
3877
3481
  return {
3878
3482
  success: null,
3879
3483
  failure: {
3880
- error: ProtocolError.NO_RESPONSE,
3484
+ error: LightPushError.NO_STREAM_AVAILABLE,
3881
3485
  peerId: peerId
3882
3486
  }
3883
3487
  };
3884
3488
  }
3885
- if (isRLNResponseError(response.info)) {
3886
- log$8.error("Remote peer fault: RLN generation");
3489
+ let res;
3490
+ try {
3491
+ res = await pipe([rpc.encode()], encode, stream, decode, async (source) => await all(source));
3492
+ }
3493
+ catch (err) {
3494
+ log$8.error("Failed to send waku light push request", err);
3887
3495
  return {
3888
3496
  success: null,
3889
3497
  failure: {
3890
- error: ProtocolError.RLN_PROOF_GENERATION,
3498
+ error: LightPushError.STREAM_ABORTED,
3891
3499
  peerId: peerId
3892
3500
  }
3893
3501
  };
3894
3502
  }
3895
- if (!response.isSuccess) {
3896
- log$8.error("Remote peer rejected the message: ", response.info);
3503
+ const bytes = new Uint8ArrayList();
3504
+ res.forEach((chunk) => bytes.append(chunk));
3505
+ if (bytes.length === 0) {
3897
3506
  return {
3898
3507
  success: null,
3899
3508
  failure: {
3900
- error: ProtocolError.REMOTE_PEER_REJECTED,
3509
+ error: LightPushError.NO_RESPONSE,
3901
3510
  peerId: peerId
3902
3511
  }
3903
3512
  };
3904
3513
  }
3905
- return { success: peerId, failure: null };
3514
+ return ProtocolHandler.handleResponse(bytes, protocol, peerId);
3515
+ }
3516
+ async getProtocol(peerId, useLegacy) {
3517
+ try {
3518
+ const peer = await this.libp2p.peerStore.get(peerId);
3519
+ if (useLegacy ||
3520
+ (!peer.protocols.includes(CODECS.v3) &&
3521
+ peer.protocols.includes(CODECS.v2))) {
3522
+ return CODECS.v2;
3523
+ }
3524
+ else if (peer.protocols.includes(CODECS.v3)) {
3525
+ return CODECS.v3;
3526
+ }
3527
+ else {
3528
+ throw new Error("No supported protocol found");
3529
+ }
3530
+ }
3531
+ catch (error) {
3532
+ log$8.error("Failed to get protocol", error);
3533
+ return undefined;
3534
+ }
3535
+ }
3536
+ async getStream(peerId, protocol) {
3537
+ switch (protocol) {
3538
+ case CODECS.v2:
3539
+ return this.streamManagerV2.getStream(peerId);
3540
+ case CODECS.v3:
3541
+ return this.streamManager.getStream(peerId);
3542
+ default:
3543
+ return undefined;
3544
+ }
3906
3545
  }
3907
3546
  }
3908
3547
 
3909
3548
  var index$1 = /*#__PURE__*/Object.freeze({
3910
3549
  __proto__: null,
3911
3550
  LightPushCodec: LightPushCodec,
3912
- LightPushCore: LightPushCore,
3913
- get PushResponse () { return PushResponse; }
3551
+ LightPushCodecV2: LightPushCodecV2,
3552
+ LightPushCore: LightPushCore
3914
3553
  });
3915
3554
 
3916
3555
  const EmptyMessage = {
@@ -4132,7 +3771,7 @@ class ConnectionLimiter {
4132
3771
  this.connectionMonitorInterval === null) {
4133
3772
  this.connectionMonitorInterval = setInterval(() => void this.maintainConnections(), DEFAULT_CONNECTION_MONITOR_INTERVAL);
4134
3773
  }
4135
- this.events.addEventListener("waku:connection", this.onWakuConnectionEvent);
3774
+ this.events.addEventListener(WakuEvent.Connection, this.onWakuConnectionEvent);
4136
3775
  /**
4137
3776
  * NOTE: Event is not being emitted on closing nor losing a connection.
4138
3777
  * @see https://github.com/libp2p/js-libp2p/issues/939
@@ -4147,7 +3786,7 @@ class ConnectionLimiter {
4147
3786
  this.libp2p.addEventListener("peer:disconnect", this.onDisconnectedEvent);
4148
3787
  }
4149
3788
  stop() {
4150
- this.events.removeEventListener("waku:connection", this.onWakuConnectionEvent);
3789
+ this.events.removeEventListener(WakuEvent.Connection, this.onWakuConnectionEvent);
4151
3790
  this.libp2p.removeEventListener("peer:disconnect", this.onDisconnectedEvent);
4152
3791
  if (this.connectionMonitorInterval) {
4153
3792
  clearInterval(this.connectionMonitorInterval);
@@ -4263,8 +3902,7 @@ class ConnectionLimiter {
4263
3902
  .getConnections()
4264
3903
  .map((conn) => conn.remotePeer)
4265
3904
  .map((id) => this.getPeer(id)));
4266
- const bootstrapPeers = peers.filter((peer) => peer && peer.tags.has(Tags.BOOTSTRAP));
4267
- return bootstrapPeers;
3905
+ return peers.filter((peer) => peer && peer.tags.has(Tags.BOOTSTRAP));
4268
3906
  }
4269
3907
  async getPeer(peerId) {
4270
3908
  try {
@@ -4704,7 +4342,7 @@ class NetworkMonitor {
4704
4342
  }
4705
4343
  }
4706
4344
  dispatchNetworkEvent() {
4707
- this.events.dispatchEvent(new CustomEvent("waku:connection", {
4345
+ this.events.dispatchEvent(new CustomEvent(WakuEvent.Connection, {
4708
4346
  detail: this.isConnected()
4709
4347
  }));
4710
4348
  }
@@ -4770,74 +4408,6 @@ class ShardReader {
4770
4408
  }
4771
4409
  }
4772
4410
 
4773
- /**
4774
- * All PeerId implementations must use this symbol as the name of a property
4775
- * with a boolean `true` value
4776
- */
4777
- const peerIdSymbol = Symbol.for('@libp2p/peer-id');
4778
- /**
4779
- * Returns true if the passed argument is a PeerId implementation
4780
- */
4781
- function isPeerId(other) {
4782
- return Boolean(other?.[peerIdSymbol]);
4783
- }
4784
-
4785
- /**
4786
- * When this error is thrown it means an operation was aborted,
4787
- * usually in response to the `abort` event being emitted by an
4788
- * AbortSignal.
4789
- */
4790
- /**
4791
- * Thrown when invalid parameters are passed to a function or method call
4792
- */
4793
- let InvalidParametersError$1 = class InvalidParametersError extends Error {
4794
- static name = 'InvalidParametersError';
4795
- constructor(message = 'Invalid parameters') {
4796
- super(message);
4797
- this.name = 'InvalidParametersError';
4798
- }
4799
- };
4800
- /**
4801
- * Thrown when a public key is invalid
4802
- */
4803
- class InvalidPublicKeyError extends Error {
4804
- static name = 'InvalidPublicKeyError';
4805
- constructor(message = 'Invalid public key') {
4806
- super(message);
4807
- this.name = 'InvalidPublicKeyError';
4808
- }
4809
- }
4810
- /**
4811
- * Thrown when an invalid CID is encountered
4812
- */
4813
- class InvalidCIDError extends Error {
4814
- static name = 'InvalidCIDError';
4815
- constructor(message = 'Invalid CID') {
4816
- super(message);
4817
- this.name = 'InvalidCIDError';
4818
- }
4819
- }
4820
- /**
4821
- * Thrown when an invalid multihash is encountered
4822
- */
4823
- class InvalidMultihashError extends Error {
4824
- static name = 'InvalidMultihashError';
4825
- constructor(message = 'Invalid Multihash') {
4826
- super(message);
4827
- this.name = 'InvalidMultihashError';
4828
- }
4829
- }
4830
- /**
4831
- * Thrown when an attempt to operate on an unsupported key was made
4832
- */
4833
- class UnsupportedKeyTypeError extends Error {
4834
- static name = 'UnsupportedKeyTypeError';
4835
- constructor(message = 'Unsupported key type') {
4836
- super(message);
4837
- this.name = 'UnsupportedKeyTypeError';
4838
- }
4839
- }
4840
-
4841
4411
  const TAG_MASK = parseInt('11111', 2);
4842
4412
  const LONG_LENGTH_MASK = parseInt('10000000', 2);
4843
4413
  const LONG_LENGTH_BYTES_MASK = parseInt('01111111', 2);
@@ -5175,11 +4745,11 @@ function hexToNumber(hex) {
5175
4745
  }
5176
4746
  // BE: Big Endian, LE: Little Endian
5177
4747
  function bytesToNumberBE(bytes) {
5178
- return hexToNumber(bytesToHex$1(bytes));
4748
+ return hexToNumber(bytesToHex(bytes));
5179
4749
  }
5180
4750
  function bytesToNumberLE(bytes) {
5181
4751
  abytes(bytes);
5182
- return hexToNumber(bytesToHex$1(Uint8Array.from(bytes).reverse()));
4752
+ return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
5183
4753
  }
5184
4754
  function numberToBytesBE(n, len) {
5185
4755
  return hexToBytes(n.toString(16).padStart(len * 2, '0'));
@@ -6453,7 +6023,7 @@ function edwards(CURVE, curveOpts = {}) {
6453
6023
  return this.toBytes();
6454
6024
  }
6455
6025
  toHex() {
6456
- return bytesToHex$1(this.toBytes());
6026
+ return bytesToHex(this.toBytes());
6457
6027
  }
6458
6028
  toString() {
6459
6029
  return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;
@@ -7723,7 +7293,7 @@ function weierstrassN(CURVE, curveOpts = {}) {
7723
7293
  return this.toBytes(isCompressed);
7724
7294
  }
7725
7295
  toHex(isCompressed = true) {
7726
- return bytesToHex$1(this.toBytes(isCompressed));
7296
+ return bytesToHex(this.toBytes(isCompressed));
7727
7297
  }
7728
7298
  toString() {
7729
7299
  return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;
@@ -7853,14 +7423,14 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
7853
7423
  return this.toBytes('der');
7854
7424
  }
7855
7425
  toDERHex() {
7856
- return bytesToHex$1(this.toBytes('der'));
7426
+ return bytesToHex(this.toBytes('der'));
7857
7427
  }
7858
7428
  // padded bytes of r, then padded bytes of s
7859
7429
  toCompactRawBytes() {
7860
7430
  return this.toBytes('compact');
7861
7431
  }
7862
7432
  toCompactHex() {
7863
- return bytesToHex$1(this.toBytes('compact'));
7433
+ return bytesToHex(this.toBytes('compact'));
7864
7434
  }
7865
7435
  }
7866
7436
  const normPrivateKeyToScalar = _legacyHelperNormPriv(Fn, curveOpts.allowedPrivateKeyLengths, curveOpts.wrapPrivateKey);
@@ -8308,13 +7878,13 @@ const secp256k1 = createCurve({
8308
7878
  return { k1neg, k1, k2neg, k2 };
8309
7879
  },
8310
7880
  },
8311
- }, sha256$1);
7881
+ }, sha256$2);
8312
7882
 
8313
7883
  /**
8314
7884
  * Hash message and verify signature with public key
8315
7885
  */
8316
7886
  function hashAndVerify(key, sig, msg, options) {
8317
- const p = sha256$2.digest(msg instanceof Uint8Array ? msg : msg.subarray());
7887
+ const p = sha256.digest(msg instanceof Uint8Array ? msg : msg.subarray());
8318
7888
  if (isPromise(p)) {
8319
7889
  return p
8320
7890
  .then(({ digest }) => {
@@ -8645,7 +8215,7 @@ function isIdentityMultihash(multihash) {
8645
8215
  return multihash.code === identity.code;
8646
8216
  }
8647
8217
  function isSha256Multihash(multihash) {
8648
- return multihash.code === sha256$2.code;
8218
+ return multihash.code === sha256.code;
8649
8219
  }
8650
8220
 
8651
8221
  /**
@@ -10297,85 +9867,4 @@ function wakuMetadata(clusterId) {
10297
9867
  return (components) => new Metadata(clusterId, components);
10298
9868
  }
10299
9869
 
10300
- /**
10301
- * Deterministic Message Hashing as defined in
10302
- * [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/#deterministic-message-hashing)
10303
- *
10304
- * Computes a SHA-256 hash of the concatenation of pubsub topic, payload, content topic, meta, and timestamp.
10305
- *
10306
- * @param pubsubTopic - The pubsub topic string
10307
- * @param message - The message to be hashed
10308
- * @returns A Uint8Array containing the SHA-256 hash
10309
- *
10310
- * @example
10311
- * ```typescript
10312
- * import { messageHash } from "@waku/core";
10313
- *
10314
- * const pubsubTopic = "/waku/2/default-waku/proto";
10315
- * const message = {
10316
- * payload: new Uint8Array([1, 2, 3, 4]),
10317
- * contentTopic: "/waku/2/default-content/proto",
10318
- * meta: new Uint8Array([5, 6, 7, 8]),
10319
- * timestamp: new Date()
10320
- * };
10321
- *
10322
- * const hash = messageHash(pubsubTopic, message);
10323
- * ```
10324
- */
10325
- function messageHash(pubsubTopic, message) {
10326
- const pubsubTopicBytes = utf8ToBytes(pubsubTopic);
10327
- const contentTopicBytes = utf8ToBytes(message.contentTopic);
10328
- const timestampBytes = tryConvertTimestampToBytes(message.timestamp);
10329
- const bytes = concat$1([
10330
- pubsubTopicBytes,
10331
- message.payload,
10332
- contentTopicBytes,
10333
- message.meta,
10334
- timestampBytes
10335
- ].filter(isDefined));
10336
- return sha256(bytes);
10337
- }
10338
- function tryConvertTimestampToBytes(timestamp) {
10339
- if (!timestamp) {
10340
- return;
10341
- }
10342
- let bigIntTimestamp;
10343
- if (typeof timestamp === "bigint") {
10344
- bigIntTimestamp = timestamp;
10345
- }
10346
- else {
10347
- bigIntTimestamp = BigInt(timestamp.valueOf()) * 1000000n;
10348
- }
10349
- return numberToBytes(bigIntTimestamp);
10350
- }
10351
- /**
10352
- * Computes a deterministic message hash and returns it as a hexadecimal string.
10353
- * This is a convenience wrapper around messageHash that converts the result to a hex string.
10354
- *
10355
- * @param pubsubTopic - The pubsub topic string
10356
- * @param message - The message to be hashed
10357
- * @returns A string containing the hex representation of the SHA-256 hash
10358
- *
10359
- * @example
10360
- * ```typescript
10361
- * import { messageHashStr } from "@waku/core";
10362
- *
10363
- * const pubsubTopic = "/waku/2/default-waku/proto";
10364
- * const message = {
10365
- * payload: new Uint8Array([1, 2, 3, 4]),
10366
- * contentTopic: "/waku/2/default-content/proto",
10367
- * meta: new Uint8Array([5, 6, 7, 8]),
10368
- * timestamp: new Date()
10369
- * };
10370
- *
10371
- * const hashString = messageHashStr(pubsubTopic, message);
10372
- * console.log(hashString); // e.g. "a1b2c3d4..."
10373
- * ```
10374
- */
10375
- function messageHashStr(pubsubTopic, message) {
10376
- const hash = messageHash(pubsubTopic, message);
10377
- const hashStr = bytesToHex(hash);
10378
- return hashStr;
10379
- }
10380
-
10381
- export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCore, MetadataCodec, StoreCodec, StoreCore, StreamManager, createEncoder, index$3 as message, messageHash, messageHashStr, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
9870
+ export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCodecV2, LightPushCore, MetadataCodec, StoreCodec, StoreCore, StreamManager, createEncoder, index$3 as message, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };