@waku/discovery 0.0.4-ce62600.0 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundle/index.js CHANGED
@@ -26,7 +26,7 @@ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
26
26
  * usually in response to the `abort` event being emitted by an
27
27
  * AbortSignal.
28
28
  */
29
- let CodeError$1 = class CodeError extends Error {
29
+ class CodeError extends Error {
30
30
  code;
31
31
  props;
32
32
  constructor(message, code, props) {
@@ -35,7 +35,7 @@ let CodeError$1 = class CodeError extends Error {
35
35
  this.name = props?.name ?? 'CodeError';
36
36
  this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
37
37
  }
38
- };
38
+ }
39
39
  class AggregateCodeError extends AggregateError {
40
40
  code;
41
41
  props;
@@ -114,23 +114,7 @@ class TypedEventEmitter extends EventTarget {
114
114
  return this.dispatchEvent(new CustomEvent(type, detail));
115
115
  }
116
116
  }
117
- /**
118
- * CustomEvent is a standard event but it's not supported by node.
119
- *
120
- * Remove this when https://github.com/nodejs/node/issues/40678 is closed.
121
- *
122
- * Ref: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent
123
- */
124
- class CustomEventPolyfill extends Event {
125
- /** Returns any custom data event was created with. Typically used for synthetic events. */
126
- detail;
127
- constructor(message, data) {
128
- super(message, data);
129
- // @ts-expect-error could be undefined
130
- this.detail = data?.detail;
131
- }
132
- }
133
- const CustomEvent = globalThis.CustomEvent ?? CustomEventPolyfill;
117
+ const CustomEvent = globalThis.CustomEvent;
134
118
 
135
119
  function isDefined(value) {
136
120
  return Boolean(value);
@@ -537,6 +521,11 @@ var ProtocolError;
537
521
  * Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
538
522
  */
539
523
  ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
524
+ /**
525
+ * The topics passed in the decoders do not match each other, or don't exist at all.
526
+ * Ensure that all the pubsub topics used in the decoders are valid and match each other.
527
+ */
528
+ ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
540
529
  /**
541
530
  * Failure to find a peer with suitable protocols. This may due to a connection issue.
542
531
  * Mitigation can be: retrying after a given time period, display connectivity issue
@@ -553,7 +542,7 @@ var ProtocolError;
553
542
  * The remote peer did not behave as expected. Mitigation for `NO_PEER_AVAILABLE`
554
543
  * or `DECODE_FAILED` can be used.
555
544
  */
556
- ProtocolError["REMOTE_PEER_FAULT"] = "Remote peer fault";
545
+ ProtocolError["NO_RESPONSE"] = "No response received";
557
546
  /**
558
547
  * The remote peer rejected the message. Information provided by the remote peer
559
548
  * is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
@@ -565,14 +554,28 @@ var ProtocolError;
565
554
  * Mitigation can be: retrying after a given time period
566
555
  */
567
556
  ProtocolError["REQUEST_TIMEOUT"] = "Request timeout";
557
+ /**
558
+ * Missing credentials info message.
559
+ * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L186
560
+ */
561
+ ProtocolError["RLN_IDENTITY_MISSING"] = "Identity credentials are not set";
562
+ /**
563
+ * Membership index missing info message.
564
+ * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L188
565
+ */
566
+ ProtocolError["RLN_MEMBERSHIP_INDEX"] = "Membership index is not set";
567
+ /**
568
+ * Message limit is missing.
569
+ * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
570
+ */
571
+ ProtocolError["RLN_LIMIT_MISSING"] = "User message limit is not set";
572
+ /**
573
+ * General proof generation error message.
574
+ * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
575
+ */
576
+ ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
568
577
  })(ProtocolError || (ProtocolError = {}));
569
578
 
570
- var PageDirection;
571
- (function (PageDirection) {
572
- PageDirection["BACKWARD"] = "backward";
573
- PageDirection["FORWARD"] = "forward";
574
- })(PageDirection || (PageDirection = {}));
575
-
576
579
  var Tags;
577
580
  (function (Tags) {
578
581
  Tags["BOOTSTRAP"] = "bootstrap";
@@ -591,13 +594,12 @@ var EConnectionStateEvents;
591
594
  EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
592
595
  })(EConnectionStateEvents || (EConnectionStateEvents = {}));
593
596
 
594
- /**
595
- * DefaultPubsubTopic is the default gossipsub topic to use for Waku.
596
- */
597
- /**
598
- * The default cluster ID for The Waku Network
599
- */
600
- const DEFAULT_CLUSTER_ID = 1;
597
+ var HealthStatus;
598
+ (function (HealthStatus) {
599
+ HealthStatus["Unhealthy"] = "Unhealthy";
600
+ HealthStatus["MinimallyHealthy"] = "MinimallyHealthy";
601
+ HealthStatus["SufficientlyHealthy"] = "SufficientlyHealthy";
602
+ })(HealthStatus || (HealthStatus = {}));
601
603
 
602
604
  function equals$2(aa, bb) {
603
605
  if (aa === bb)
@@ -1908,41 +1910,7 @@ const bytesToUtf8 = (b) => toString$6(b, "utf8");
1908
1910
  * Encode utf-8 string to byte array.
1909
1911
  */
1910
1912
  const utf8ToBytes$1 = (s) => fromString(s, "utf8");
1911
- /**
1912
- * Concatenate using Uint8Arrays as `Buffer` has a different behavior with `DataView`
1913
- */
1914
- function concat$2(byteArrays, totalLength) {
1915
- const len = totalLength ?? byteArrays.reduce((acc, curr) => acc + curr.length, 0);
1916
- const res = new Uint8Array(len);
1917
- let offset = 0;
1918
- for (const bytes of byteArrays) {
1919
- res.set(bytes, offset);
1920
- offset += bytes.length;
1921
- }
1922
- return res;
1923
- }
1924
1913
 
1925
- const shardInfoToPubsubTopics = (shardInfo) => {
1926
- if ("contentTopics" in shardInfo && shardInfo.contentTopics) {
1927
- // Autosharding: explicitly defined content topics
1928
- return Array.from(new Set(shardInfo.contentTopics.map((contentTopic) => contentTopicToPubsubTopic(contentTopic, shardInfo.clusterId))));
1929
- }
1930
- else if ("shards" in shardInfo) {
1931
- // Static sharding
1932
- if (shardInfo.shards === undefined)
1933
- throw new Error("Invalid shard");
1934
- return Array.from(new Set(shardInfo.shards.map((index) => `/waku/2/rs/${shardInfo.clusterId ?? DEFAULT_CLUSTER_ID}/${index}`)));
1935
- }
1936
- else if ("application" in shardInfo && "version" in shardInfo) {
1937
- // Autosharding: single shard from application and version
1938
- return [
1939
- contentTopicToPubsubTopic(`/${shardInfo.application}/${shardInfo.version}/default/default`, shardInfo.clusterId)
1940
- ];
1941
- }
1942
- else {
1943
- throw new Error("Missing required configuration in shard parameters");
1944
- }
1945
- };
1946
1914
  const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
1947
1915
  const parts = pubsubTopics.split("/");
1948
1916
  if (parts.length != 6 ||
@@ -1959,112 +1927,26 @@ const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
1959
1927
  shard
1960
1928
  };
1961
1929
  };
1962
- /**
1963
- * 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/
1964
- * @param contentTopic String to validate
1965
- * @returns Object with each content topic field as an attribute
1966
- */
1967
- function ensureValidContentTopic(contentTopic) {
1968
- const parts = contentTopic.split("/");
1969
- if (parts.length < 5 || parts.length > 6) {
1970
- throw Error("Content topic format is invalid");
1971
- }
1972
- // Validate generation field if present
1973
- let generation = 0;
1974
- if (parts.length == 6) {
1975
- generation = parseInt(parts[1]);
1976
- if (isNaN(generation)) {
1977
- throw new Error("Invalid generation field in content topic");
1978
- }
1979
- if (generation > 0) {
1980
- throw new Error("Generation greater than 0 is not supported");
1981
- }
1982
- }
1983
- // Validate remaining fields
1984
- const fields = parts.splice(-4);
1985
- // Validate application field
1986
- if (fields[0].length == 0) {
1987
- throw new Error("Application field cannot be empty");
1988
- }
1989
- // Validate version field
1990
- if (fields[1].length == 0) {
1991
- throw new Error("Version field cannot be empty");
1992
- }
1993
- // Validate topic name field
1994
- if (fields[2].length == 0) {
1995
- throw new Error("Topic name field cannot be empty");
1996
- }
1997
- // Validate encoding field
1998
- if (fields[3].length == 0) {
1999
- throw new Error("Encoding field cannot be empty");
2000
- }
1930
+ const pubsubTopicsToShardInfo = (pubsubTopics) => {
1931
+ const shardInfoSet = new Set();
1932
+ const clusterIds = new Set();
1933
+ for (const topic of pubsubTopics) {
1934
+ const { clusterId, shard } = pubsubTopicToSingleShardInfo(topic);
1935
+ shardInfoSet.add(`${clusterId}:${shard}`);
1936
+ clusterIds.add(clusterId);
1937
+ }
1938
+ if (shardInfoSet.size === 0) {
1939
+ throw new Error("No valid pubsub topics provided");
1940
+ }
1941
+ if (clusterIds.size > 1) {
1942
+ throw new Error("Pubsub topics from multiple cluster IDs are not supported");
1943
+ }
1944
+ const clusterId = clusterIds.values().next().value;
1945
+ const shards = Array.from(shardInfoSet).map((info) => parseInt(info.split(":")[1]));
2001
1946
  return {
2002
- generation,
2003
- application: fields[0],
2004
- version: fields[1],
2005
- topicName: fields[2],
2006
- encoding: fields[3]
1947
+ clusterId,
1948
+ shards
2007
1949
  };
2008
- }
2009
- /**
2010
- * Given a string, determines which autoshard index to use for its pubsub topic.
2011
- * Based on the algorithm described in the RFC: https://rfc.vac.dev/spec/51//#algorithm
2012
- */
2013
- function contentTopicToShardIndex(contentTopic, networkShards = 8) {
2014
- const { application, version } = ensureValidContentTopic(contentTopic);
2015
- const digest = sha256$1(concat$2([utf8ToBytes$1(application), utf8ToBytes$1(version)]));
2016
- const dataview = new DataView(digest.buffer.slice(-8));
2017
- return Number(dataview.getBigUint64(0, false) % BigInt(networkShards));
2018
- }
2019
- function contentTopicToPubsubTopic(contentTopic, clusterId = DEFAULT_CLUSTER_ID, networkShards = 8) {
2020
- if (!contentTopic) {
2021
- throw Error("Content topic must be specified");
2022
- }
2023
- const shardIndex = contentTopicToShardIndex(contentTopic, networkShards);
2024
- return `/waku/2/rs/${clusterId}/${shardIndex}`;
2025
- }
2026
- /**
2027
- * Validates sharding configuration and sets defaults where possible.
2028
- * @returns Validated sharding parameters, with any missing values set to defaults
2029
- */
2030
- const ensureShardingConfigured = (shardInfo) => {
2031
- const clusterId = shardInfo.clusterId ?? DEFAULT_CLUSTER_ID;
2032
- const shards = "shards" in shardInfo ? shardInfo.shards : [];
2033
- const contentTopics = "contentTopics" in shardInfo ? shardInfo.contentTopics : [];
2034
- const [application, version] = "application" in shardInfo && "version" in shardInfo
2035
- ? [shardInfo.application, shardInfo.version]
2036
- : [undefined, undefined];
2037
- const isShardsConfigured = shards && shards.length > 0;
2038
- const isContentTopicsConfigured = contentTopics && contentTopics.length > 0;
2039
- const isApplicationVersionConfigured = application && version;
2040
- if (isShardsConfigured) {
2041
- return {
2042
- shardingParams: { clusterId, shards },
2043
- shardInfo: { clusterId, shards },
2044
- pubsubTopics: shardInfoToPubsubTopics({ clusterId, shards })
2045
- };
2046
- }
2047
- if (isContentTopicsConfigured) {
2048
- const pubsubTopics = Array.from(new Set(contentTopics.map((topic) => contentTopicToPubsubTopic(topic, clusterId))));
2049
- const shards = Array.from(new Set(contentTopics.map((topic) => contentTopicToShardIndex(topic))));
2050
- return {
2051
- shardingParams: { clusterId, contentTopics },
2052
- shardInfo: { clusterId, shards },
2053
- pubsubTopics
2054
- };
2055
- }
2056
- if (isApplicationVersionConfigured) {
2057
- const pubsubTopic = contentTopicToPubsubTopic(`/${application}/${version}/default/default`, clusterId);
2058
- return {
2059
- shardingParams: { clusterId, application, version },
2060
- shardInfo: {
2061
- clusterId,
2062
- shards: [pubsubTopicToSingleShardInfo(pubsubTopic).shard]
2063
- },
2064
- pubsubTopics: [pubsubTopic]
2065
- };
2066
- }
2067
- throw new Error("Missing minimum required configuration options for static sharding or autosharding.");
2068
1950
  };
2069
1951
 
2070
1952
  const decodeRelayShard = (bytes) => {
@@ -2710,6 +2592,8 @@ var common = setup;
2710
2592
  return false;
2711
2593
  }
2712
2594
 
2595
+ let m;
2596
+
2713
2597
  // Is webkit? http://stackoverflow.com/a/16459606/376773
2714
2598
  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
2715
2599
  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
@@ -2717,7 +2601,7 @@ var common = setup;
2717
2601
  (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
2718
2602
  // Is firefox >= v31?
2719
2603
  // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
2720
- (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
2604
+ (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
2721
2605
  // Double check webkit in userAgent just in case we are in a worker
2722
2606
  (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
2723
2607
  }
@@ -2888,12 +2772,10 @@ let Logger$1 = class Logger {
2888
2772
  /**
2889
2773
  * The ENR tree for the different fleets.
2890
2774
  * SANDBOX and TEST fleets are for The Waku Network.
2891
- * DEPRECATED_DEFAULT_PUBSUB is the fleet of nodes supporting the now deprecated DefaultPubsubTopic.
2892
2775
  */
2893
2776
  const enrTree = {
2894
2777
  SANDBOX: "enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im",
2895
- TEST: "enrtree://AOGYWMBYOUIMOENHXCHILPKY3ZRFEULMFI4DOM442QSZ73TT2A7VI@test.waku.nodes.status.im",
2896
- DEPRECATED_DEFAULT_PUBSUB: "enrtree://ANEDLO25QVUGJOUTQFRYKWX6P4Z4GKVESBMHML7DZ6YK4LGS5FC5O@prod.wakuv2.nodes.status.im"
2778
+ TEST: "enrtree://AOGYWMBYOUIMOENHXCHILPKY3ZRFEULMFI4DOM442QSZ73TT2A7VI@test.waku.nodes.status.im"
2897
2779
  };
2898
2780
  const DEFAULT_BOOTSTRAP_TAG_NAME = "bootstrap";
2899
2781
  const DEFAULT_BOOTSTRAP_TAG_VALUE = 50;
@@ -2922,7 +2804,7 @@ const _0n$5 = BigInt(0);
2922
2804
  const _1n$7 = BigInt(1);
2923
2805
  const _2n$5 = BigInt(2);
2924
2806
  const _3n$2 = BigInt(3);
2925
- const _8n$2 = BigInt(8);
2807
+ const _8n$3 = BigInt(8);
2926
2808
  const CURVE = Object.freeze({
2927
2809
  a: _0n$5,
2928
2810
  b: BigInt(7),
@@ -3026,7 +2908,7 @@ class JacobianPoint {
3026
2908
  const E = mod$1(_3n$2 * A);
3027
2909
  const F = mod$1(E * E);
3028
2910
  const X3 = mod$1(F - _2n$5 * D);
3029
- const Y3 = mod$1(E * (D - X3) - _8n$2 * C);
2911
+ const Y3 = mod$1(E * (D - X3) - _8n$3 * C);
3030
2912
  const Z3 = mod$1(_2n$5 * Y1 * Z1);
3031
2913
  return new JacobianPoint(X3, Y3, Z3);
3032
2914
  }
@@ -3126,12 +3008,12 @@ class JacobianPoint {
3126
3008
  if (256 % W) {
3127
3009
  throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
3128
3010
  }
3129
- let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
3011
+ let precomputes = affinePoint && pointPrecomputes$1.get(affinePoint);
3130
3012
  if (!precomputes) {
3131
3013
  precomputes = this.precomputeWindow(W);
3132
3014
  if (affinePoint && W !== 1) {
3133
3015
  precomputes = JacobianPoint.normalizeZ(precomputes);
3134
- pointPrecomputes.set(affinePoint, precomputes);
3016
+ pointPrecomputes$1.set(affinePoint, precomputes);
3135
3017
  }
3136
3018
  }
3137
3019
  let p = JacobianPoint.ZERO;
@@ -3187,7 +3069,7 @@ class JacobianPoint {
3187
3069
  const { x, y, z } = this;
3188
3070
  const is0 = this.equals(JacobianPoint.ZERO);
3189
3071
  if (invZ == null)
3190
- invZ = is0 ? _8n$2 : invert$1(z);
3072
+ invZ = is0 ? _8n$3 : invert$1(z);
3191
3073
  const iz1 = invZ;
3192
3074
  const iz2 = mod$1(iz1 * iz1);
3193
3075
  const iz3 = mod$1(iz2 * iz1);
@@ -3207,7 +3089,7 @@ function constTimeNegate(condition, item) {
3207
3089
  const neg = item.negate();
3208
3090
  return condition ? neg : item;
3209
3091
  }
3210
- const pointPrecomputes = new WeakMap();
3092
+ const pointPrecomputes$1 = new WeakMap();
3211
3093
  class Point {
3212
3094
  constructor(x, y) {
3213
3095
  this.x = x;
@@ -3215,7 +3097,7 @@ class Point {
3215
3097
  }
3216
3098
  _setWindowSize(windowSize) {
3217
3099
  this._WINDOW_SIZE = windowSize;
3218
- pointPrecomputes.delete(this);
3100
+ pointPrecomputes$1.delete(this);
3219
3101
  }
3220
3102
  hasEvenY() {
3221
3103
  return this.y % _2n$5 === _0n$5;
@@ -5273,6 +5155,7 @@ const table = [
5273
5155
  [478, 0, 'wss'],
5274
5156
  [479, 0, 'p2p-websocket-star'],
5275
5157
  [480, 0, 'http'],
5158
+ [481, V, 'http-path'],
5276
5159
  [777, V, 'memory']
5277
5160
  ];
5278
5161
  // populate tables
@@ -5358,6 +5241,8 @@ function convertToString(proto, buf) {
5358
5241
  return bytes2onion(buf);
5359
5242
  case 466: // certhash
5360
5243
  return bytes2mb(buf);
5244
+ case 481: // http-path
5245
+ return globalThis.encodeURIComponent(bytes2str(buf));
5361
5246
  default:
5362
5247
  return toString$6(buf, 'base16'); // no clue. convert to hex
5363
5248
  }
@@ -5392,6 +5277,8 @@ function convertToBytes(proto, str) {
5392
5277
  return onion32bytes(str);
5393
5278
  case 466: // certhash
5394
5279
  return mb2bytes(str);
5280
+ case 481: // http-path
5281
+ return str2bytes(globalThis.decodeURIComponent(str));
5395
5282
  default:
5396
5283
  return fromString(str, 'base16'); // no clue. convert from hex
5397
5284
  }
@@ -5853,7 +5740,7 @@ class Multiaddr {
5853
5740
  }
5854
5741
  const resolver = resolvers$1.get(resolvableProto.name);
5855
5742
  if (resolver == null) {
5856
- throw new CodeError$1(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
5743
+ throw new CodeError(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
5857
5744
  }
5858
5745
  const result = await resolver(this, options);
5859
5746
  return result.map(str => multiaddr(str));
@@ -6296,9 +6183,9 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
6296
6183
  // This is OK: `abstract` directory does not use noble-hashes.
6297
6184
  // User may opt-in into using different hashing library. This way, noble-hashes
6298
6185
  // won't be included into their bundle.
6299
- const _0n$4 = BigInt(0);
6300
- const _1n$6 = BigInt(1);
6301
- const _2n$4 = BigInt(2);
6186
+ const _0n$4 = /* @__PURE__ */ BigInt(0);
6187
+ const _1n$6 = /* @__PURE__ */ BigInt(1);
6188
+ const _2n$4 = /* @__PURE__ */ BigInt(2);
6302
6189
  function isBytes$1(a) {
6303
6190
  return (a instanceof Uint8Array ||
6304
6191
  (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
@@ -6307,6 +6194,10 @@ function abytes(item) {
6307
6194
  if (!isBytes$1(item))
6308
6195
  throw new Error('Uint8Array expected');
6309
6196
  }
6197
+ function abool(title, value) {
6198
+ if (typeof value !== 'boolean')
6199
+ throw new Error(`${title} must be valid boolean, got "${value}".`);
6200
+ }
6310
6201
  // Array where index 0xf0 (240) is mapped to string 'f0'
6311
6202
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
6312
6203
  /**
@@ -6449,6 +6340,25 @@ function utf8ToBytes(str) {
6449
6340
  throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
6450
6341
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
6451
6342
  }
6343
+ // Is positive bigint
6344
+ const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
6345
+ function inRange(n, min, max) {
6346
+ return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
6347
+ }
6348
+ /**
6349
+ * Asserts min <= n < max. NOTE: It's < max and not <= max.
6350
+ * @example
6351
+ * aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)
6352
+ */
6353
+ function aInRange(title, n, min, max) {
6354
+ // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?
6355
+ // consider P=256n, min=0n, max=P
6356
+ // - a for min=0 would require -1: `inRange('x', x, -1n, P)`
6357
+ // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
6358
+ // - our way is the cleanest: `inRange('x', x, 0n, P)
6359
+ if (!inRange(n, min, max))
6360
+ throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
6361
+ }
6452
6362
  // Bit operations
6453
6363
  /**
6454
6364
  * Calculates amount of bits in a bigint.
@@ -6579,9 +6489,32 @@ function validateObject(object, validators, optValidators = {}) {
6579
6489
  // const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
6580
6490
  // const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
6581
6491
  // const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
6492
+ /**
6493
+ * throws not implemented error
6494
+ */
6495
+ const notImplemented = () => {
6496
+ throw new Error('not implemented');
6497
+ };
6498
+ /**
6499
+ * Memoizes (caches) computation result.
6500
+ * Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
6501
+ */
6502
+ function memoized(fn) {
6503
+ const map = new WeakMap();
6504
+ return (arg, ...args) => {
6505
+ const val = map.get(arg);
6506
+ if (val !== undefined)
6507
+ return val;
6508
+ const computed = fn(arg, ...args);
6509
+ map.set(arg, computed);
6510
+ return computed;
6511
+ };
6512
+ }
6582
6513
 
6583
6514
  var ut = /*#__PURE__*/Object.freeze({
6584
6515
  __proto__: null,
6516
+ aInRange: aInRange,
6517
+ abool: abool,
6585
6518
  abytes: abytes,
6586
6519
  bitGet: bitGet,
6587
6520
  bitLen: bitLen,
@@ -6596,7 +6529,10 @@ var ut = /*#__PURE__*/Object.freeze({
6596
6529
  equalBytes: equalBytes,
6597
6530
  hexToBytes: hexToBytes,
6598
6531
  hexToNumber: hexToNumber,
6532
+ inRange: inRange,
6599
6533
  isBytes: isBytes$1,
6534
+ memoized: memoized,
6535
+ notImplemented: notImplemented,
6600
6536
  numberToBytesBE: numberToBytesBE,
6601
6537
  numberToBytesLE: numberToBytesLE,
6602
6538
  numberToHexUnpadded: numberToHexUnpadded,
@@ -6610,7 +6546,7 @@ var ut = /*#__PURE__*/Object.freeze({
6610
6546
  // prettier-ignore
6611
6547
  const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
6612
6548
  // prettier-ignore
6613
- const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$1 = BigInt(8);
6549
+ const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
6614
6550
  // prettier-ignore
6615
6551
  BigInt(9); BigInt(16);
6616
6552
  // Calculates a modulo b
@@ -6756,8 +6692,8 @@ function FpSqrt(P) {
6756
6692
  };
6757
6693
  }
6758
6694
  // Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
6759
- if (P % _8n$1 === _5n$1) {
6760
- const c1 = (P - _5n$1) / _8n$1;
6695
+ if (P % _8n$2 === _5n$1) {
6696
+ const c1 = (P - _5n$1) / _8n$2;
6761
6697
  return function sqrt5mod8(Fp, n) {
6762
6698
  const n2 = Fp.mul(n, _2n$3);
6763
6699
  const v = Fp.pow(n2, c1);
@@ -6855,6 +6791,9 @@ function nLength(n, nBitLength) {
6855
6791
  * * a) denormalized operations like mulN instead of mul
6856
6792
  * * b) same object shape: never add or remove keys
6857
6793
  * * c) Object.freeze
6794
+ * NOTE: operations don't check 'isValid' for all elements for performance reasons,
6795
+ * it is caller responsibility to check this.
6796
+ * This is low-level code, please make sure you know what you doing.
6858
6797
  * @param ORDER prime positive bigint
6859
6798
  * @param bitLen how many bits the field consumes
6860
6799
  * @param isLE (def: false) if encoding / decoding should be in little-endian
@@ -6910,12 +6849,6 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6910
6849
  });
6911
6850
  return Object.freeze(f);
6912
6851
  }
6913
- function FpSqrtEven(Fp, elm) {
6914
- if (!Fp.isOdd)
6915
- throw new Error(`Field doesn't have isOdd`);
6916
- const root = Fp.sqrt(elm);
6917
- return Fp.isOdd(root) ? Fp.neg(root) : root;
6918
- }
6919
6852
  /**
6920
6853
  * Returns total number of bytes consumed by the field element.
6921
6854
  * For example, 32 bytes for usual 256-bit weierstrass curve.
@@ -6969,6 +6902,10 @@ function mapHashToField(key, fieldOrder, isLE = false) {
6969
6902
  // Abelian group utilities
6970
6903
  const _0n$2 = BigInt(0);
6971
6904
  const _1n$4 = BigInt(1);
6905
+ // Since points in different groups cannot be equal (different object constructor),
6906
+ // we can have single place to store precomputes
6907
+ const pointPrecomputes = new WeakMap();
6908
+ const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
6972
6909
  // Elliptic curve multiplication of Point by scalar. Fragile.
6973
6910
  // Scalars should always be less than curve order: this should be checked inside of a curve itself.
6974
6911
  // Creates precomputation tables for fast multiplication:
@@ -6985,7 +6922,12 @@ function wNAF(c, bits) {
6985
6922
  const neg = item.negate();
6986
6923
  return condition ? neg : item;
6987
6924
  };
6925
+ const validateW = (W) => {
6926
+ if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
6927
+ throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
6928
+ };
6988
6929
  const opts = (W) => {
6930
+ validateW(W);
6989
6931
  const windows = Math.ceil(bits / W) + 1; // +1, because
6990
6932
  const windowSize = 2 ** (W - 1); // -1 because we skip zero
6991
6933
  return { windows, windowSize };
@@ -7085,19 +7027,25 @@ function wNAF(c, bits) {
7085
7027
  // which makes it less const-time: around 1 bigint multiply.
7086
7028
  return { p, f };
7087
7029
  },
7088
- wNAFCached(P, precomputesMap, n, transform) {
7089
- // @ts-ignore
7090
- const W = P._WINDOW_SIZE || 1;
7030
+ wNAFCached(P, n, transform) {
7031
+ const W = pointWindowSizes.get(P) || 1;
7091
7032
  // Calculate precomputes on a first run, reuse them after
7092
- let comp = precomputesMap.get(P);
7033
+ let comp = pointPrecomputes.get(P);
7093
7034
  if (!comp) {
7094
7035
  comp = this.precomputeWindow(P, W);
7095
- if (W !== 1) {
7096
- precomputesMap.set(P, transform(comp));
7097
- }
7036
+ if (W !== 1)
7037
+ pointPrecomputes.set(P, transform(comp));
7098
7038
  }
7099
7039
  return this.wNAF(W, comp, n);
7100
7040
  },
7041
+ // We calculate precomputes for elliptic curve point multiplication
7042
+ // using windowed method. This specifies window size and
7043
+ // stores precomputed values. Usually only base point would be precomputed.
7044
+ setWindowSize(P, W) {
7045
+ validateW(W);
7046
+ pointWindowSizes.set(P, W);
7047
+ pointPrecomputes.delete(P);
7048
+ },
7101
7049
  };
7102
7050
  }
7103
7051
  function validateBasic(curve) {
@@ -7123,7 +7071,7 @@ function validateBasic(curve) {
7123
7071
  // Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
7124
7072
  // Be friendly to bad ECMAScript parsers by not using bigint literals
7125
7073
  // prettier-ignore
7126
- const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n = BigInt(8);
7074
+ const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
7127
7075
  // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
7128
7076
  const VERIFY_DEFAULT = { zip215: true };
7129
7077
  function validateOpts$1(curve) {
@@ -7142,7 +7090,13 @@ function validateOpts$1(curve) {
7142
7090
  // Set defaults
7143
7091
  return Object.freeze({ ...opts });
7144
7092
  }
7145
- // It is not generic twisted curve for now, but ed25519/ed448 generic implementation
7093
+ /**
7094
+ * Creates Twisted Edwards curve with EdDSA signatures.
7095
+ * @example
7096
+ * import { Field } from '@noble/curves/abstract/modular';
7097
+ * // Before that, define BigInt-s: a, d, p, n, Gx, Gy, h
7098
+ * const curve = twistedEdwards({ a, d, Fp: Field(p), n, Gx, Gy, h })
7099
+ */
7146
7100
  function twistedEdwards(curveDef) {
7147
7101
  const CURVE = validateOpts$1(curveDef);
7148
7102
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
@@ -7161,28 +7115,59 @@ function twistedEdwards(curveDef) {
7161
7115
  const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
7162
7116
  const domain = CURVE.domain ||
7163
7117
  ((data, ctx, phflag) => {
7118
+ abool('phflag', phflag);
7164
7119
  if (ctx.length || phflag)
7165
7120
  throw new Error('Contexts/pre-hash are not supported');
7166
7121
  return data;
7167
7122
  }); // NOOP
7168
- const inBig = (n) => typeof n === 'bigint' && _0n$1 < n; // n in [1..]
7169
- const inRange = (n, max) => inBig(n) && inBig(max) && n < max; // n in [1..max-1]
7170
- const in0MaskRange = (n) => n === _0n$1 || inRange(n, MASK); // n in [0..MASK-1]
7171
- function assertInRange(n, max) {
7172
- // n in [1..max-1]
7173
- if (inRange(n, max))
7174
- return n;
7175
- throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
7176
- }
7177
- function assertGE0(n) {
7178
- // n in [0..CURVE_ORDER-1]
7179
- return n === _0n$1 ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
7180
- }
7181
- const pointPrecomputes = new Map();
7182
- function isPoint(other) {
7123
+ // 0 <= n < MASK
7124
+ // Coordinates larger than Fp.ORDER are allowed for zip215
7125
+ function aCoordinate(title, n) {
7126
+ aInRange('coordinate ' + title, n, _0n$1, MASK);
7127
+ }
7128
+ function assertPoint(other) {
7183
7129
  if (!(other instanceof Point))
7184
7130
  throw new Error('ExtendedPoint expected');
7185
7131
  }
7132
+ // Converts Extended point to default (x, y) coordinates.
7133
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
7134
+ const toAffineMemo = memoized((p, iz) => {
7135
+ const { ex: x, ey: y, ez: z } = p;
7136
+ const is0 = p.is0();
7137
+ if (iz == null)
7138
+ iz = is0 ? _8n$1 : Fp.inv(z); // 8 was chosen arbitrarily
7139
+ const ax = modP(x * iz);
7140
+ const ay = modP(y * iz);
7141
+ const zz = modP(z * iz);
7142
+ if (is0)
7143
+ return { x: _0n$1, y: _1n$3 };
7144
+ if (zz !== _1n$3)
7145
+ throw new Error('invZ was invalid');
7146
+ return { x: ax, y: ay };
7147
+ });
7148
+ const assertValidMemo = memoized((p) => {
7149
+ const { a, d } = CURVE;
7150
+ if (p.is0())
7151
+ throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
7152
+ // Equation in affine coordinates: ax² + y² = 1 + dx²y²
7153
+ // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
7154
+ const { ex: X, ey: Y, ez: Z, et: T } = p;
7155
+ const X2 = modP(X * X); // X²
7156
+ const Y2 = modP(Y * Y); // Y²
7157
+ const Z2 = modP(Z * Z); // Z²
7158
+ const Z4 = modP(Z2 * Z2); // Z⁴
7159
+ const aX2 = modP(X2 * a); // aX²
7160
+ const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
7161
+ const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
7162
+ if (left !== right)
7163
+ throw new Error('bad point: equation left != right (1)');
7164
+ // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
7165
+ const XY = modP(X * Y);
7166
+ const ZT = modP(Z * T);
7167
+ if (XY !== ZT)
7168
+ throw new Error('bad point: equation left != right (2)');
7169
+ return true;
7170
+ });
7186
7171
  // Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
7187
7172
  // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
7188
7173
  class Point {
@@ -7191,14 +7176,11 @@ function twistedEdwards(curveDef) {
7191
7176
  this.ey = ey;
7192
7177
  this.ez = ez;
7193
7178
  this.et = et;
7194
- if (!in0MaskRange(ex))
7195
- throw new Error('x required');
7196
- if (!in0MaskRange(ey))
7197
- throw new Error('y required');
7198
- if (!in0MaskRange(ez))
7199
- throw new Error('z required');
7200
- if (!in0MaskRange(et))
7201
- throw new Error('t required');
7179
+ aCoordinate('x', ex);
7180
+ aCoordinate('y', ey);
7181
+ aCoordinate('z', ez);
7182
+ aCoordinate('t', et);
7183
+ Object.freeze(this);
7202
7184
  }
7203
7185
  get x() {
7204
7186
  return this.toAffine().x;
@@ -7210,8 +7192,8 @@ function twistedEdwards(curveDef) {
7210
7192
  if (p instanceof Point)
7211
7193
  throw new Error('extended point not allowed');
7212
7194
  const { x, y } = p || {};
7213
- if (!in0MaskRange(x) || !in0MaskRange(y))
7214
- throw new Error('invalid affine point');
7195
+ aCoordinate('x', x);
7196
+ aCoordinate('y', y);
7215
7197
  return new Point(x, y, _1n$3, modP(x * y));
7216
7198
  }
7217
7199
  static normalizeZ(points) {
@@ -7220,36 +7202,16 @@ function twistedEdwards(curveDef) {
7220
7202
  }
7221
7203
  // "Private method", don't use it directly
7222
7204
  _setWindowSize(windowSize) {
7223
- this._WINDOW_SIZE = windowSize;
7224
- pointPrecomputes.delete(this);
7205
+ wnaf.setWindowSize(this, windowSize);
7225
7206
  }
7226
7207
  // Not required for fromHex(), which always creates valid points.
7227
7208
  // Could be useful for fromAffine().
7228
7209
  assertValidity() {
7229
- const { a, d } = CURVE;
7230
- if (this.is0())
7231
- throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
7232
- // Equation in affine coordinates: ax² + y² = 1 + dx²y²
7233
- // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
7234
- const { ex: X, ey: Y, ez: Z, et: T } = this;
7235
- const X2 = modP(X * X); // X²
7236
- const Y2 = modP(Y * Y); // Y²
7237
- const Z2 = modP(Z * Z); // Z²
7238
- const Z4 = modP(Z2 * Z2); // Z⁴
7239
- const aX2 = modP(X2 * a); // aX²
7240
- const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
7241
- const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
7242
- if (left !== right)
7243
- throw new Error('bad point: equation left != right (1)');
7244
- // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
7245
- const XY = modP(X * Y);
7246
- const ZT = modP(Z * T);
7247
- if (XY !== ZT)
7248
- throw new Error('bad point: equation left != right (2)');
7210
+ assertValidMemo(this);
7249
7211
  }
7250
7212
  // Compare one point to another.
7251
7213
  equals(other) {
7252
- isPoint(other);
7214
+ assertPoint(other);
7253
7215
  const { ex: X1, ey: Y1, ez: Z1 } = this;
7254
7216
  const { ex: X2, ey: Y2, ez: Z2 } = other;
7255
7217
  const X1Z2 = modP(X1 * Z2);
@@ -7290,7 +7252,7 @@ function twistedEdwards(curveDef) {
7290
7252
  // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
7291
7253
  // Cost: 9M + 1*a + 1*d + 7add.
7292
7254
  add(other) {
7293
- isPoint(other);
7255
+ assertPoint(other);
7294
7256
  const { a, d } = CURVE;
7295
7257
  const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
7296
7258
  const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
@@ -7333,11 +7295,13 @@ function twistedEdwards(curveDef) {
7333
7295
  return this.add(other.negate());
7334
7296
  }
7335
7297
  wNAF(n) {
7336
- return wnaf.wNAFCached(this, pointPrecomputes, n, Point.normalizeZ);
7298
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
7337
7299
  }
7338
7300
  // Constant-time multiplication.
7339
7301
  multiply(scalar) {
7340
- const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
7302
+ const n = scalar;
7303
+ aInRange('scalar', n, _1n$3, CURVE_ORDER); // 1 <= scalar < L
7304
+ const { p, f } = this.wNAF(n);
7341
7305
  return Point.normalizeZ([p, f])[0];
7342
7306
  }
7343
7307
  // Non-constant-time multiplication. Uses double-and-add algorithm.
@@ -7345,7 +7309,8 @@ function twistedEdwards(curveDef) {
7345
7309
  // an exposed private key e.g. sig verification.
7346
7310
  // Does NOT allow scalars higher than CURVE.n.
7347
7311
  multiplyUnsafe(scalar) {
7348
- let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
7312
+ const n = scalar;
7313
+ aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
7349
7314
  if (n === _0n$1)
7350
7315
  return I;
7351
7316
  if (this.equals(I) || n === _1n$3)
@@ -7369,18 +7334,7 @@ function twistedEdwards(curveDef) {
7369
7334
  // Converts Extended point to default (x, y) coordinates.
7370
7335
  // Can accept precomputed Z^-1 - for example, from invertBatch.
7371
7336
  toAffine(iz) {
7372
- const { ex: x, ey: y, ez: z } = this;
7373
- const is0 = this.is0();
7374
- if (iz == null)
7375
- iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
7376
- const ax = modP(x * iz);
7377
- const ay = modP(y * iz);
7378
- const zz = modP(z * iz);
7379
- if (is0)
7380
- return { x: _0n$1, y: _1n$3 };
7381
- if (zz !== _1n$3)
7382
- throw new Error('invZ was invalid');
7383
- return { x: ax, y: ay };
7337
+ return toAffineMemo(this, iz);
7384
7338
  }
7385
7339
  clearCofactor() {
7386
7340
  const { h: cofactor } = CURVE;
@@ -7394,18 +7348,16 @@ function twistedEdwards(curveDef) {
7394
7348
  const { d, a } = CURVE;
7395
7349
  const len = Fp.BYTES;
7396
7350
  hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
7351
+ abool('zip215', zip215);
7397
7352
  const normed = hex.slice(); // copy again, we'll manipulate it
7398
7353
  const lastByte = hex[len - 1]; // select last byte
7399
7354
  normed[len - 1] = lastByte & ~0x80; // clear last bit
7400
7355
  const y = bytesToNumberLE(normed);
7401
- if (y === _0n$1) ;
7402
- else {
7403
- // RFC8032 prohibits >= p, but ZIP215 doesn't
7404
- if (zip215)
7405
- assertInRange(y, MASK); // zip215=true [1..P-1] (2^255-19-1 for ed25519)
7406
- else
7407
- assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
7408
- }
7356
+ // RFC8032 prohibits >= p, but ZIP215 doesn't
7357
+ // zip215=true: 0 <= y < MASK (2^256 for ed25519)
7358
+ // zip215=false: 0 <= y < P (2^255-19 for ed25519)
7359
+ const max = zip215 ? MASK : Fp.ORDER;
7360
+ aInRange('pointHex.y', y, _0n$1, max);
7409
7361
  // Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
7410
7362
  // ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
7411
7363
  const y2 = modP(y * y); // denominator is always non-0 mod p.
@@ -7480,7 +7432,7 @@ function twistedEdwards(curveDef) {
7480
7432
  const R = G.multiply(r).toRawBytes(); // R = rG
7481
7433
  const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
7482
7434
  const s = modN(r + k * scalar); // S = (r + k * s) mod L
7483
- assertGE0(s); // 0 <= s < l
7435
+ aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
7484
7436
  const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
7485
7437
  return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
7486
7438
  }
@@ -7490,6 +7442,8 @@ function twistedEdwards(curveDef) {
7490
7442
  const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
7491
7443
  sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
7492
7444
  msg = ensureBytes('message', msg);
7445
+ if (zip215 !== undefined)
7446
+ abool('zip215', zip215);
7493
7447
  if (prehash)
7494
7448
  msg = prehash(msg); // for ed25519ph, etc
7495
7449
  const s = bytesToNumberLE(sig.slice(len, 2 * len));
@@ -7547,12 +7501,14 @@ function twistedEdwards(curveDef) {
7547
7501
  */
7548
7502
  const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
7549
7503
  // √(-1) aka √(a) aka 2^((p-1)/4)
7550
- const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
7504
+ const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
7551
7505
  // prettier-ignore
7552
- BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2), _5n = BigInt(5);
7506
+ BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
7553
7507
  // prettier-ignore
7554
- const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
7508
+ const _5n = BigInt(5), _8n = BigInt(8);
7555
7509
  function ed25519_pow_2_252_3(x) {
7510
+ // prettier-ignore
7511
+ const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
7556
7512
  const P = ED25519_P;
7557
7513
  const x2 = (x * x) % P;
7558
7514
  const b2 = (x2 * x) % P; // x^3, 11
@@ -7601,8 +7557,8 @@ function uvRatio(u, v) {
7601
7557
  x = mod(-x, P);
7602
7558
  return { isValid: useRoot1 || useRoot2, value: x };
7603
7559
  }
7604
- const Fp$1 = Field(ED25519_P, undefined, true);
7605
- const ed25519Defaults = {
7560
+ const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
7561
+ const ed25519Defaults = /* @__PURE__ */ (() => ({
7606
7562
  // Param: a
7607
7563
  a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
7608
7564
  // d is equal to -121665/121666 over finite field.
@@ -7614,7 +7570,7 @@ const ed25519Defaults = {
7614
7570
  // 2n**252n + 27742317777372353535851937790883648493n;
7615
7571
  n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
7616
7572
  // Cofactor
7617
- h: BigInt(8),
7573
+ h: _8n,
7618
7574
  // Base point (x, y) aka generator point
7619
7575
  Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
7620
7576
  Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
@@ -7625,40 +7581,11 @@ const ed25519Defaults = {
7625
7581
  // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
7626
7582
  // Constant-time, u/√v
7627
7583
  uvRatio,
7628
- };
7629
- const ed25519 = /* @__PURE__ */ twistedEdwards(ed25519Defaults);
7630
- function ed25519_domain(data, ctx, phflag) {
7631
- if (ctx.length > 255)
7632
- throw new Error('Context is too big');
7633
- return concatBytes$2(utf8ToBytes$2('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
7634
- }
7635
- /* @__PURE__ */ twistedEdwards({
7636
- ...ed25519Defaults,
7637
- domain: ed25519_domain,
7638
- });
7639
- /* @__PURE__ */ twistedEdwards({
7640
- ...ed25519Defaults,
7641
- domain: ed25519_domain,
7642
- prehash: sha512,
7643
- });
7644
- // Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
7645
- // NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
7646
- // SageMath returns different root first and everything falls apart
7647
- const ELL2_C1 = (Fp$1.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
7648
- Fp$1.pow(_2n$1, ELL2_C1); // 2. c2 = 2^c1
7649
- Fp$1.sqrt(Fp$1.neg(Fp$1.ONE)); // 3. c3 = sqrt(-1)
7650
- (Fp$1.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
7651
- BigInt(486662);
7652
- FpSqrtEven(Fp$1, Fp$1.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
7653
- // √(ad - 1)
7654
- BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
7655
- // 1 / √(a-d)
7656
- BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
7657
- // 1-d²
7658
- BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
7659
- // (d-1)²
7660
- BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
7661
- BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
7584
+ }))();
7585
+ /**
7586
+ * ed25519 curve with EdDSA signatures.
7587
+ */
7588
+ const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
7662
7589
 
7663
7590
  const PUBLIC_KEY_BYTE_LENGTH = 32;
7664
7591
  const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
@@ -7715,7 +7642,7 @@ function concatKeys(privateKeyRaw, publicKey) {
7715
7642
  var webcrypto = {
7716
7643
  get(win = globalThis) {
7717
7644
  const nativeCrypto = win.crypto;
7718
- if (nativeCrypto == null || nativeCrypto.subtle == null) {
7645
+ if (nativeCrypto?.subtle == null) {
7719
7646
  throw Object.assign(new Error('Missing Web Crypto API. ' +
7720
7647
  'The most likely cause of this error is that this page is being accessed ' +
7721
7648
  'from an insecure context (i.e. not HTTPS). For more information and ' +
@@ -7739,12 +7666,12 @@ var webcrypto = {
7739
7666
  const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
7740
7667
  // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
7741
7668
  function create(opts) {
7742
- const algorithm = opts?.algorithm ?? 'AES-GCM';
7743
- let keyLength = opts?.keyLength ?? 16;
7744
- const nonceLength = opts?.nonceLength ?? 12;
7745
- const digest = opts?.digest ?? 'SHA-256';
7746
- const saltLength = opts?.saltLength ?? 16;
7747
- const iterations = opts?.iterations ?? 32767;
7669
+ const algorithm = 'AES-GCM';
7670
+ let keyLength = 16;
7671
+ const nonceLength = 12;
7672
+ const digest = 'SHA-256';
7673
+ const saltLength = 16;
7674
+ const iterations = 32767;
7748
7675
  const crypto = webcrypto.get();
7749
7676
  keyLength *= 8; // Browser crypto uses bits instead of bytes
7750
7677
  /**
@@ -8528,7 +8455,7 @@ function decodeMessage(buf, codec, opts) {
8528
8455
  * A general purpose buffer pool
8529
8456
  */
8530
8457
  function pool(size) {
8531
- const SIZE = size ?? 8192;
8458
+ const SIZE = 8192;
8532
8459
  const MAX = SIZE >>> 1;
8533
8460
  let slab;
8534
8461
  let offset = SIZE;
@@ -9041,12 +8968,17 @@ function message(encode, decode) {
9041
8968
  * npm i protons-runtime
9042
8969
  * ```
9043
8970
  */
9044
- class CodeError extends Error {
9045
- code;
9046
- constructor(message, code, options) {
9047
- super(message, options);
9048
- this.code = code;
9049
- }
8971
+ /**
8972
+ * Thrown when a repeated field has too many elements
8973
+ */
8974
+ class MaxLengthError extends Error {
8975
+ /**
8976
+ * This will be removed in a future release
8977
+ *
8978
+ * @deprecated use the `.name` property instead
8979
+ */
8980
+ code = 'ERR_MAX_LENGTH';
8981
+ name = 'MaxLengthError';
9050
8982
  }
9051
8983
 
9052
8984
  /* eslint-disable import/export */
@@ -9257,7 +9189,7 @@ class Ed25519PrivateKey {
9257
9189
  return exporter(this.bytes, password);
9258
9190
  }
9259
9191
  else {
9260
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
9192
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
9261
9193
  }
9262
9194
  }
9263
9195
  }
@@ -9289,7 +9221,7 @@ async function generateKeyPairFromSeed(seed) {
9289
9221
  function ensureKey(key, length) {
9290
9222
  key = Uint8Array.from(key ?? []);
9291
9223
  if (key.length !== length) {
9292
- throw new CodeError$1(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
9224
+ throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
9293
9225
  }
9294
9226
  return key;
9295
9227
  }
@@ -9309,7 +9241,7 @@ var Ed25519 = /*#__PURE__*/Object.freeze({
9309
9241
  */
9310
9242
  function randomBytes(length) {
9311
9243
  if (isNaN(length) || length <= 0) {
9312
- throw new CodeError$1('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
9244
+ throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
9313
9245
  }
9314
9246
  return randomBytes$1(length);
9315
9247
  }
@@ -12718,7 +12650,7 @@ function pkcs1ToJwk(bytes) {
12718
12650
  */
12719
12651
  function jwkToPkcs1(jwk) {
12720
12652
  if (jwk.n == null || jwk.e == null || jwk.d == null || jwk.p == null || jwk.q == null || jwk.dp == null || jwk.dq == null || jwk.qi == null) {
12721
- throw new CodeError$1('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12653
+ throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12722
12654
  }
12723
12655
  const root = new Sequence({
12724
12656
  value: [
@@ -12755,7 +12687,7 @@ function pkixToJwk(bytes) {
12755
12687
  */
12756
12688
  function jwkToPkix(jwk) {
12757
12689
  if (jwk.n == null || jwk.e == null) {
12758
- throw new CodeError$1('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12690
+ throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12759
12691
  }
12760
12692
  const root = new Sequence({
12761
12693
  value: [
@@ -12967,7 +12899,7 @@ async function hashAndVerify$1(key, sig, msg) {
12967
12899
  }
12968
12900
  async function exportKey(pair) {
12969
12901
  if (pair.privateKey == null || pair.publicKey == null) {
12970
- throw new CodeError$1('Private and public key are required', 'ERR_INVALID_PARAMETERS');
12902
+ throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
12971
12903
  }
12972
12904
  return Promise.all([
12973
12905
  webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
@@ -12986,10 +12918,10 @@ async function derivePublicFromPrivate(jwKey) {
12986
12918
  }
12987
12919
  function keySize(jwk) {
12988
12920
  if (jwk.kty !== 'RSA') {
12989
- throw new CodeError$1('invalid key type', 'ERR_INVALID_KEY_TYPE');
12921
+ throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
12990
12922
  }
12991
12923
  else if (jwk.n == null) {
12992
- throw new CodeError$1('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
12924
+ throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
12993
12925
  }
12994
12926
  const bytes = fromString(jwk.n, 'base64url');
12995
12927
  return bytes.length * 8;
@@ -13039,7 +12971,7 @@ class RsaPrivateKey {
13039
12971
  }
13040
12972
  get public() {
13041
12973
  if (this._publicKey == null) {
13042
- throw new CodeError$1('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
12974
+ throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
13043
12975
  }
13044
12976
  return new RsaPublicKey(this._publicKey);
13045
12977
  }
@@ -13088,14 +13020,14 @@ class RsaPrivateKey {
13088
13020
  return exporter(this.bytes, password);
13089
13021
  }
13090
13022
  else {
13091
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
13023
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
13092
13024
  }
13093
13025
  }
13094
13026
  }
13095
13027
  async function unmarshalRsaPrivateKey(bytes) {
13096
13028
  const jwk = pkcs1ToJwk(bytes);
13097
13029
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13098
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13030
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13099
13031
  }
13100
13032
  const keys = await unmarshalPrivateKey$1(jwk);
13101
13033
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
@@ -13103,20 +13035,20 @@ async function unmarshalRsaPrivateKey(bytes) {
13103
13035
  function unmarshalRsaPublicKey(bytes) {
13104
13036
  const jwk = pkixToJwk(bytes);
13105
13037
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13106
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13038
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13107
13039
  }
13108
13040
  return new RsaPublicKey(jwk);
13109
13041
  }
13110
13042
  async function fromJwk(jwk) {
13111
13043
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13112
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13044
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13113
13045
  }
13114
13046
  const keys = await unmarshalPrivateKey$1(jwk);
13115
13047
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
13116
13048
  }
13117
13049
  async function generateKeyPair$1(bits) {
13118
13050
  if (bits > MAX_RSA_KEY_SIZE) {
13119
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13051
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13120
13052
  }
13121
13053
  const keys = await generateKey$1(bits);
13122
13054
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
@@ -13135,6 +13067,12 @@ var RSA = /*#__PURE__*/Object.freeze({
13135
13067
 
13136
13068
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
13137
13069
  // Short Weierstrass curve. The formula is: y² = x³ + ax + b
13070
+ function validateSigVerOpts(opts) {
13071
+ if (opts.lowS !== undefined)
13072
+ abool('lowS', opts.lowS);
13073
+ if (opts.prehash !== undefined)
13074
+ abool('prehash', opts.prehash);
13075
+ }
13138
13076
  function validatePointOpts(curve) {
13139
13077
  const opts = validateBasic(curve);
13140
13078
  validateObject(opts, {
@@ -13259,16 +13197,12 @@ function weierstrassPoints(opts) {
13259
13197
  throw new Error('bad generator point: equation left != right');
13260
13198
  // Valid group elements reside in range 1..n-1
13261
13199
  function isWithinCurveOrder(num) {
13262
- return typeof num === 'bigint' && _0n < num && num < CURVE.n;
13263
- }
13264
- function assertGE(num) {
13265
- if (!isWithinCurveOrder(num))
13266
- throw new Error('Expected valid bigint: 0 < bigint < curve.n');
13200
+ return inRange(num, _1n$1, CURVE.n);
13267
13201
  }
13268
13202
  // Validates if priv key is valid and converts it to bigint.
13269
13203
  // Supports options allowedPrivateKeyLengths and wrapPrivateKey.
13270
13204
  function normPrivateKeyToScalar(key) {
13271
- const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
13205
+ const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
13272
13206
  if (lengths && typeof key !== 'bigint') {
13273
13207
  if (isBytes$1(key))
13274
13208
  key = bytesToHex(key);
@@ -13288,15 +13222,61 @@ function weierstrassPoints(opts) {
13288
13222
  throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
13289
13223
  }
13290
13224
  if (wrapPrivateKey)
13291
- num = mod(num, n); // disabled by default, enabled for BLS
13292
- assertGE(num); // num in range [1..N-1]
13225
+ num = mod(num, N); // disabled by default, enabled for BLS
13226
+ aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
13293
13227
  return num;
13294
13228
  }
13295
- const pointPrecomputes = new Map();
13296
13229
  function assertPrjPoint(other) {
13297
13230
  if (!(other instanceof Point))
13298
13231
  throw new Error('ProjectivePoint expected');
13299
13232
  }
13233
+ // Memoized toAffine / validity check. They are heavy. Points are immutable.
13234
+ // Converts Projective point to affine (x, y) coordinates.
13235
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
13236
+ // (x, y, z) ∋ (x=x/z, y=y/z)
13237
+ const toAffineMemo = memoized((p, iz) => {
13238
+ const { px: x, py: y, pz: z } = p;
13239
+ // Fast-path for normalized points
13240
+ if (Fp.eql(z, Fp.ONE))
13241
+ return { x, y };
13242
+ const is0 = p.is0();
13243
+ // If invZ was 0, we return zero point. However we still want to execute
13244
+ // all operations, so we replace invZ with a random number, 1.
13245
+ if (iz == null)
13246
+ iz = is0 ? Fp.ONE : Fp.inv(z);
13247
+ const ax = Fp.mul(x, iz);
13248
+ const ay = Fp.mul(y, iz);
13249
+ const zz = Fp.mul(z, iz);
13250
+ if (is0)
13251
+ return { x: Fp.ZERO, y: Fp.ZERO };
13252
+ if (!Fp.eql(zz, Fp.ONE))
13253
+ throw new Error('invZ was invalid');
13254
+ return { x: ax, y: ay };
13255
+ });
13256
+ // NOTE: on exception this will crash 'cached' and no value will be set.
13257
+ // Otherwise true will be return
13258
+ const assertValidMemo = memoized((p) => {
13259
+ if (p.is0()) {
13260
+ // (0, 1, 0) aka ZERO is invalid in most contexts.
13261
+ // In BLS, ZERO can be serialized, so we allow it.
13262
+ // (0, 0, 0) is wrong representation of ZERO and is always invalid.
13263
+ if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
13264
+ return;
13265
+ throw new Error('bad point: ZERO');
13266
+ }
13267
+ // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
13268
+ const { x, y } = p.toAffine();
13269
+ // Check if x, y are valid field elements
13270
+ if (!Fp.isValid(x) || !Fp.isValid(y))
13271
+ throw new Error('bad point: x or y not FE');
13272
+ const left = Fp.sqr(y); // y²
13273
+ const right = weierstrassEquation(x); // x³ + ax + b
13274
+ if (!Fp.eql(left, right))
13275
+ throw new Error('bad point: equation left != right');
13276
+ if (!p.isTorsionFree())
13277
+ throw new Error('bad point: not in prime-order subgroup');
13278
+ return true;
13279
+ });
13300
13280
  /**
13301
13281
  * Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
13302
13282
  * Default Point works in 2d / affine coordinates: (x, y)
@@ -13313,6 +13293,7 @@ function weierstrassPoints(opts) {
13313
13293
  throw new Error('y required');
13314
13294
  if (pz == null || !Fp.isValid(pz))
13315
13295
  throw new Error('z required');
13296
+ Object.freeze(this);
13316
13297
  }
13317
13298
  // Does not validate if the point is on-curve.
13318
13299
  // Use fromHex instead, or call assertValidity() later.
@@ -13359,30 +13340,11 @@ function weierstrassPoints(opts) {
13359
13340
  }
13360
13341
  // "Private method", don't use it directly
13361
13342
  _setWindowSize(windowSize) {
13362
- this._WINDOW_SIZE = windowSize;
13363
- pointPrecomputes.delete(this);
13343
+ wnaf.setWindowSize(this, windowSize);
13364
13344
  }
13365
13345
  // A point on curve is valid if it conforms to equation.
13366
13346
  assertValidity() {
13367
- if (this.is0()) {
13368
- // (0, 1, 0) aka ZERO is invalid in most contexts.
13369
- // In BLS, ZERO can be serialized, so we allow it.
13370
- // (0, 0, 0) is wrong representation of ZERO and is always invalid.
13371
- if (CURVE.allowInfinityPoint && !Fp.is0(this.py))
13372
- return;
13373
- throw new Error('bad point: ZERO');
13374
- }
13375
- // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
13376
- const { x, y } = this.toAffine();
13377
- // Check if x, y are valid field elements
13378
- if (!Fp.isValid(x) || !Fp.isValid(y))
13379
- throw new Error('bad point: x or y not FE');
13380
- const left = Fp.sqr(y); // y²
13381
- const right = weierstrassEquation(x); // x³ + ax + b
13382
- if (!Fp.eql(left, right))
13383
- throw new Error('bad point: equation left != right');
13384
- if (!this.isTorsionFree())
13385
- throw new Error('bad point: not in prime-order subgroup');
13347
+ assertValidMemo(this);
13386
13348
  }
13387
13349
  hasEvenY() {
13388
13350
  const { y } = this.toAffine();
@@ -13509,28 +13471,25 @@ function weierstrassPoints(opts) {
13509
13471
  return this.equals(Point.ZERO);
13510
13472
  }
13511
13473
  wNAF(n) {
13512
- return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => {
13513
- const toInv = Fp.invertBatch(comp.map((p) => p.pz));
13514
- return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
13515
- });
13474
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
13516
13475
  }
13517
13476
  /**
13518
13477
  * Non-constant-time multiplication. Uses double-and-add algorithm.
13519
13478
  * It's faster, but should only be used when you don't care about
13520
13479
  * an exposed private key e.g. sig verification, which works over *public* keys.
13521
13480
  */
13522
- multiplyUnsafe(n) {
13481
+ multiplyUnsafe(sc) {
13482
+ aInRange('scalar', sc, _0n, CURVE.n);
13523
13483
  const I = Point.ZERO;
13524
- if (n === _0n)
13484
+ if (sc === _0n)
13525
13485
  return I;
13526
- assertGE(n); // Will throw on 0
13527
- if (n === _1n$1)
13486
+ if (sc === _1n$1)
13528
13487
  return this;
13529
13488
  const { endo } = CURVE;
13530
13489
  if (!endo)
13531
- return wnaf.unsafeLadder(this, n);
13490
+ return wnaf.unsafeLadder(this, sc);
13532
13491
  // Apply endomorphism
13533
- let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
13492
+ let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
13534
13493
  let k1p = I;
13535
13494
  let k2p = I;
13536
13495
  let d = this;
@@ -13560,12 +13519,11 @@ function weierstrassPoints(opts) {
13560
13519
  * @returns New point
13561
13520
  */
13562
13521
  multiply(scalar) {
13563
- assertGE(scalar);
13564
- let n = scalar;
13522
+ const { endo, n: N } = CURVE;
13523
+ aInRange('scalar', scalar, _1n$1, N);
13565
13524
  let point, fake; // Fake point is used to const-time mult
13566
- const { endo } = CURVE;
13567
13525
  if (endo) {
13568
- const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
13526
+ const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
13569
13527
  let { p: k1p, f: f1p } = this.wNAF(k1);
13570
13528
  let { p: k2p, f: f2p } = this.wNAF(k2);
13571
13529
  k1p = wnaf.constTimeNegate(k1neg, k1p);
@@ -13575,7 +13533,7 @@ function weierstrassPoints(opts) {
13575
13533
  fake = f1p.add(f2p);
13576
13534
  }
13577
13535
  else {
13578
- const { p, f } = this.wNAF(n);
13536
+ const { p, f } = this.wNAF(scalar);
13579
13537
  point = p;
13580
13538
  fake = f;
13581
13539
  }
@@ -13599,20 +13557,7 @@ function weierstrassPoints(opts) {
13599
13557
  // Can accept precomputed Z^-1 - for example, from invertBatch.
13600
13558
  // (x, y, z) ∋ (x=x/z, y=y/z)
13601
13559
  toAffine(iz) {
13602
- const { px: x, py: y, pz: z } = this;
13603
- const is0 = this.is0();
13604
- // If invZ was 0, we return zero point. However we still want to execute
13605
- // all operations, so we replace invZ with a random number, 1.
13606
- if (iz == null)
13607
- iz = is0 ? Fp.ONE : Fp.inv(z);
13608
- const ax = Fp.mul(x, iz);
13609
- const ay = Fp.mul(y, iz);
13610
- const zz = Fp.mul(z, iz);
13611
- if (is0)
13612
- return { x: Fp.ZERO, y: Fp.ZERO };
13613
- if (!Fp.eql(zz, Fp.ONE))
13614
- throw new Error('invZ was invalid');
13615
- return { x: ax, y: ay };
13560
+ return toAffineMemo(this, iz);
13616
13561
  }
13617
13562
  isTorsionFree() {
13618
13563
  const { h: cofactor, isTorsionFree } = CURVE;
@@ -13631,10 +13576,12 @@ function weierstrassPoints(opts) {
13631
13576
  return this.multiplyUnsafe(CURVE.h);
13632
13577
  }
13633
13578
  toRawBytes(isCompressed = true) {
13579
+ abool('isCompressed', isCompressed);
13634
13580
  this.assertValidity();
13635
13581
  return toBytes(Point, this, isCompressed);
13636
13582
  }
13637
13583
  toHex(isCompressed = true) {
13584
+ abool('isCompressed', isCompressed);
13638
13585
  return bytesToHex(this.toRawBytes(isCompressed));
13639
13586
  }
13640
13587
  }
@@ -13664,14 +13611,18 @@ function validateOpts(curve) {
13664
13611
  });
13665
13612
  return Object.freeze({ lowS: true, ...opts });
13666
13613
  }
13614
+ /**
13615
+ * Creates short weierstrass curve and ECDSA signature methods for it.
13616
+ * @example
13617
+ * import { Field } from '@noble/curves/abstract/modular';
13618
+ * // Before that, define BigInt-s: a, b, p, n, Gx, Gy
13619
+ * const curve = weierstrass({ a, b, Fp: Field(p), n, Gx, Gy, h: 1n })
13620
+ */
13667
13621
  function weierstrass(curveDef) {
13668
13622
  const CURVE = validateOpts(curveDef);
13669
13623
  const { Fp, n: CURVE_ORDER } = CURVE;
13670
13624
  const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
13671
13625
  const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
13672
- function isValidFieldElement(num) {
13673
- return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE
13674
- }
13675
13626
  function modN(a) {
13676
13627
  return mod(a, CURVE_ORDER);
13677
13628
  }
@@ -13684,6 +13635,7 @@ function weierstrass(curveDef) {
13684
13635
  const a = point.toAffine();
13685
13636
  const x = Fp.toBytes(a.x);
13686
13637
  const cat = concatBytes;
13638
+ abool('isCompressed', isCompressed);
13687
13639
  if (isCompressed) {
13688
13640
  return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
13689
13641
  }
@@ -13698,7 +13650,7 @@ function weierstrass(curveDef) {
13698
13650
  // this.assertValidity() is done inside of fromHex
13699
13651
  if (len === compressedLen && (head === 0x02 || head === 0x03)) {
13700
13652
  const x = bytesToNumberBE(tail);
13701
- if (!isValidFieldElement(x))
13653
+ if (!inRange(x, _1n$1, Fp.ORDER))
13702
13654
  throw new Error('Point is not on curve');
13703
13655
  const y2 = weierstrassEquation(x); // y² = x³ + ax + b
13704
13656
  let y;
@@ -13759,11 +13711,8 @@ function weierstrass(curveDef) {
13759
13711
  return new Signature(r, s);
13760
13712
  }
13761
13713
  assertValidity() {
13762
- // can use assertGE here
13763
- if (!isWithinCurveOrder(this.r))
13764
- throw new Error('r must be 0 < r < CURVE.n');
13765
- if (!isWithinCurveOrder(this.s))
13766
- throw new Error('s must be 0 < s < CURVE.n');
13714
+ aInRange('r', this.r, _1n$1, CURVE_ORDER); // r in [1..N]
13715
+ aInRange('s', this.s, _1n$1, CURVE_ORDER); // s in [1..N]
13767
13716
  }
13768
13717
  addRecoveryBit(recovery) {
13769
13718
  return new Signature(this.r, this.s, recovery);
@@ -13906,10 +13855,7 @@ function weierstrass(curveDef) {
13906
13855
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
13907
13856
  */
13908
13857
  function int2octets(num) {
13909
- if (typeof num !== 'bigint')
13910
- throw new Error('bigint expected');
13911
- if (!(_0n <= num && num < ORDER_MASK))
13912
- throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
13858
+ aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
13913
13859
  // works with order, can have different size than numToField!
13914
13860
  return numberToBytesBE(num, CURVE.nByteLength);
13915
13861
  }
@@ -13926,6 +13872,7 @@ function weierstrass(curveDef) {
13926
13872
  if (lowS == null)
13927
13873
  lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
13928
13874
  msgHash = ensureBytes('msgHash', msgHash);
13875
+ validateSigVerOpts(opts);
13929
13876
  if (prehash)
13930
13877
  msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
13931
13878
  // We can't later call bits2octets, since nested bits2int is broken for curves
@@ -14012,6 +13959,7 @@ function weierstrass(curveDef) {
14012
13959
  publicKey = ensureBytes('publicKey', publicKey);
14013
13960
  if ('strict' in opts)
14014
13961
  throw new Error('options.strict was renamed to lowS');
13962
+ validateSigVerOpts(opts);
14015
13963
  const { lowS, prehash } = opts;
14016
13964
  let _sig = undefined;
14017
13965
  let P;
@@ -14118,6 +14066,9 @@ function sqrtMod(y) {
14118
14066
  return root;
14119
14067
  }
14120
14068
  const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
14069
+ /**
14070
+ * secp256k1 short weierstrass curve and ECDSA signatures over it.
14071
+ */
14121
14072
  const secp256k1 = createCurve({
14122
14073
  a: BigInt(0), // equation params: a, b
14123
14074
  b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
@@ -14176,14 +14127,14 @@ function hashAndSign(key, msg) {
14176
14127
  if (isPromise$1(p)) {
14177
14128
  return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
14178
14129
  .catch(err => {
14179
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14130
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14180
14131
  });
14181
14132
  }
14182
14133
  try {
14183
14134
  return secp256k1.sign(p.digest, key).toDERRawBytes();
14184
14135
  }
14185
14136
  catch (err) {
14186
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14137
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14187
14138
  }
14188
14139
  }
14189
14140
  /**
@@ -14194,14 +14145,14 @@ function hashAndVerify(key, sig, msg) {
14194
14145
  if (isPromise$1(p)) {
14195
14146
  return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
14196
14147
  .catch(err => {
14197
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14148
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14198
14149
  });
14199
14150
  }
14200
14151
  try {
14201
14152
  return secp256k1.verify(sig, p.digest, key);
14202
14153
  }
14203
14154
  catch (err) {
14204
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14155
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14205
14156
  }
14206
14157
  }
14207
14158
  function compressPublicKey(key) {
@@ -14213,7 +14164,7 @@ function validatePrivateKey(key) {
14213
14164
  secp256k1.getPublicKey(key, true);
14214
14165
  }
14215
14166
  catch (err) {
14216
- throw new CodeError$1(String(err), 'ERR_INVALID_PRIVATE_KEY');
14167
+ throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
14217
14168
  }
14218
14169
  }
14219
14170
  function validatePublicKey(key) {
@@ -14221,7 +14172,7 @@ function validatePublicKey(key) {
14221
14172
  secp256k1.ProjectivePoint.fromHex(key);
14222
14173
  }
14223
14174
  catch (err) {
14224
- throw new CodeError$1(String(err), 'ERR_INVALID_PUBLIC_KEY');
14175
+ throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
14225
14176
  }
14226
14177
  }
14227
14178
  function computePublicKey(privateKey) {
@@ -14229,7 +14180,7 @@ function computePublicKey(privateKey) {
14229
14180
  return secp256k1.getPublicKey(privateKey, true);
14230
14181
  }
14231
14182
  catch (err) {
14232
- throw new CodeError$1(String(err), 'ERR_INVALID_PRIVATE_KEY');
14183
+ throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
14233
14184
  }
14234
14185
  }
14235
14186
 
@@ -14319,7 +14270,7 @@ class Secp256k1PrivateKey {
14319
14270
  return exporter(this.bytes, password);
14320
14271
  }
14321
14272
  else {
14322
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
14273
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
14323
14274
  }
14324
14275
  }
14325
14276
  }
@@ -14361,7 +14312,7 @@ const supportedKeys = {
14361
14312
  };
14362
14313
  function unsupportedKey(type) {
14363
14314
  const supported = Object.keys(supportedKeys).join(' / ');
14364
- return new CodeError$1(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
14315
+ return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
14365
14316
  }
14366
14317
  function typeToKey(type) {
14367
14318
  type = type.toLowerCase();
@@ -14546,6 +14497,41 @@ class Secp256k1PeerIdImpl extends PeerIdImpl {
14546
14497
  this.publicKey = init.multihash.digest;
14547
14498
  }
14548
14499
  }
14500
+ // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
14501
+ const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
14502
+ class URLPeerIdImpl {
14503
+ type = 'url';
14504
+ multihash;
14505
+ privateKey;
14506
+ publicKey;
14507
+ url;
14508
+ constructor(url) {
14509
+ this.url = url.toString();
14510
+ this.multihash = identity.digest(fromString(this.url));
14511
+ }
14512
+ [inspect]() {
14513
+ return `PeerId(${this.url})`;
14514
+ }
14515
+ [peerIdSymbol] = true;
14516
+ toString() {
14517
+ return this.toCID().toString();
14518
+ }
14519
+ toCID() {
14520
+ return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
14521
+ }
14522
+ toBytes() {
14523
+ return this.toCID().bytes;
14524
+ }
14525
+ equals(other) {
14526
+ if (other == null) {
14527
+ return false;
14528
+ }
14529
+ if (other instanceof Uint8Array) {
14530
+ other = toString$6(other);
14531
+ }
14532
+ return other.toString() === this.toString();
14533
+ }
14534
+ }
14549
14535
  function peerIdFromString(str, decoder) {
14550
14536
  if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
14551
14537
  // identity hash ed25519/secp256k1 key or sha2-256 hash of
@@ -14584,9 +14570,13 @@ function peerIdFromBytes(buf) {
14584
14570
  throw new Error('Supplied PeerID CID is invalid');
14585
14571
  }
14586
14572
  function peerIdFromCID(cid) {
14587
- if (cid == null || cid.multihash == null || cid.version == null || (cid.version === 1 && cid.code !== LIBP2P_KEY_CODE)) {
14573
+ if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
14588
14574
  throw new Error('Supplied PeerID CID is invalid');
14589
14575
  }
14576
+ if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
14577
+ const url = toString$6(cid.multihash.digest);
14578
+ return new URLPeerIdImpl(new URL(url));
14579
+ }
14590
14580
  const multihash = cid.multihash;
14591
14581
  if (multihash.code === sha256.code) {
14592
14582
  return new RSAPeerIdImpl({ multihash: cid.multihash });
@@ -15432,9 +15422,6 @@ function isHexString(value, length) {
15432
15422
  if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
15433
15423
  return false;
15434
15424
  }
15435
- if (length && value.length !== 2 + 2 * length) {
15436
- return false;
15437
- }
15438
15425
  return true;
15439
15426
  }
15440
15427
  const HexCharacters = "0123456789abcdef";
@@ -17858,7 +17845,7 @@ if (!AbortError$1) {
17858
17845
  AbortError$1.prototype.name = 'AbortError';
17859
17846
  AbortError$1.prototype.code = 'ABORT_ERR';
17860
17847
 
17861
- const URL = (typeof globalThis !== 'undefined' && globalThis.URL) || require('url').URL;
17848
+ const URL$1 = (typeof globalThis !== 'undefined' && globalThis.URL) || require('url').URL;
17862
17849
 
17863
17850
  class HTTPStatusError extends Error {
17864
17851
  constructor (uri, code, method) {
@@ -18107,7 +18094,7 @@ class HTTPEndpoint extends BaseEndpoint {
18107
18094
  }
18108
18095
  const url = `${this.protocol}//${safeHost(this.host)}:${this.port}${this.path}`;
18109
18096
  try {
18110
- this.url = new URL(url);
18097
+ this.url = new URL$1(url);
18111
18098
  } catch (err) {
18112
18099
  throw new Error(err.message + ` [${url}]`)
18113
18100
  }
@@ -18189,7 +18176,7 @@ async function loadJSON (url, cache, timeout, abortSignal) {
18189
18176
 
18190
18177
  function requestRaw (url, method, data, timeout, abortSignal) {
18191
18178
  return new Promise((resolve, reject) => {
18192
- const target = new URL(url);
18179
+ const target = new URL$1(url);
18193
18180
  if (method === 'GET' && data) {
18194
18181
  target.search = '?dns=' + base64URL.decode(data);
18195
18182
  }
@@ -19568,7 +19555,7 @@ function queryDoh (endpoint, query, timeout, abortSignal) {
19568
19555
  )
19569
19556
  }
19570
19557
 
19571
- const UPDATE_URL = new URL('https://martinheidegger.github.io/dns-query/resolvers.json');
19558
+ const UPDATE_URL = new URL$1('https://martinheidegger.github.io/dns-query/resolvers.json');
19572
19559
 
19573
19560
  function isNameString (entry) {
19574
19561
  return /^@/.test(entry)
@@ -20769,24 +20756,6 @@ async function getConnectedPeersForProtocolAndShard(connections, peerStore, prot
20769
20756
  const peersWithNulls = await Promise.all(peerPromises);
20770
20757
  return peersWithNulls.filter((peer) => peer !== null);
20771
20758
  }
20772
- function selectConnection(connections) {
20773
- if (!connections.length)
20774
- return;
20775
- if (connections.length === 1)
20776
- return connections[0];
20777
- let latestConnection;
20778
- connections.forEach((connection) => {
20779
- if (connection.status === "open") {
20780
- if (!latestConnection) {
20781
- latestConnection = connection;
20782
- }
20783
- else if (connection.timeline.open > latestConnection.timeline.open) {
20784
- latestConnection = connection;
20785
- }
20786
- }
20787
- });
20788
- return latestConnection;
20789
- }
20790
20759
 
20791
20760
  /**
20792
20761
  * Retrieves a list of peers based on the specified criteria:
@@ -20825,6 +20794,25 @@ function filterPeersByDiscovery(peers, numPeers, maxBootstrapPeers) {
20825
20794
  return selectedPeers;
20826
20795
  }
20827
20796
 
20797
+ function selectConnection(connections) {
20798
+ if (!connections.length)
20799
+ return;
20800
+ if (connections.length === 1)
20801
+ return connections[0];
20802
+ let latestConnection;
20803
+ connections.forEach((connection) => {
20804
+ if (connection.status === "open") {
20805
+ if (!latestConnection) {
20806
+ latestConnection = connection;
20807
+ }
20808
+ else if (connection.timeline.open > latestConnection.timeline.open) {
20809
+ latestConnection = connection;
20810
+ }
20811
+ }
20812
+ });
20813
+ return latestConnection;
20814
+ }
20815
+
20828
20816
  const CONNECTION_TIMEOUT = 5_000;
20829
20817
  const RETRY_BACKOFF_BASE = 1_000;
20830
20818
  const MAX_RETRIES = 3;
@@ -20922,16 +20910,14 @@ class BaseProtocol {
20922
20910
  components;
20923
20911
  log;
20924
20912
  pubsubTopics;
20925
- options;
20926
20913
  addLibp2pEventListener;
20927
20914
  removeLibp2pEventListener;
20928
20915
  streamManager;
20929
- constructor(multicodec, components, log, pubsubTopics, options) {
20916
+ constructor(multicodec, components, log, pubsubTopics) {
20930
20917
  this.multicodec = multicodec;
20931
20918
  this.components = components;
20932
20919
  this.log = log;
20933
20920
  this.pubsubTopics = pubsubTopics;
20934
- this.options = options;
20935
20921
  this.addLibp2pEventListener = components.events.addEventListener.bind(components.events);
20936
20922
  this.removeLibp2pEventListener = components.events.removeEventListener.bind(components.events);
20937
20923
  this.streamManager = new StreamManager(multicodec, components.connectionManager.getConnections.bind(components.connectionManager), this.addLibp2pEventListener);
@@ -20969,9 +20955,7 @@ class BaseProtocol {
20969
20955
  numPeers: 0
20970
20956
  }) {
20971
20957
  // Retrieve all connected peers that support the protocol & shard (if configured)
20972
- const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], this.options?.shardInfo
20973
- ? ensureShardingConfigured(this.options.shardInfo).shardInfo
20974
- : undefined);
20958
+ const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], pubsubTopicsToShardInfo(this.pubsubTopics));
20975
20959
  // Filter the peers based on discovery & number of peers requested
20976
20960
  const filteredPeers = filterPeersByDiscovery(connectedPeersForProtocolAndShard, numPeers, maxBootstrapPeers);
20977
20961
  // Sort the peers by latency
@@ -21661,74 +21645,35 @@ encode.single = (chunk, options) => {
21661
21645
  };
21662
21646
 
21663
21647
  /**
21664
- * @typedef {{ [key: string]: any }} Extensions
21665
- * @typedef {Error} Err
21666
- * @property {string} message
21648
+ * The reported length of the next data message was not a positive integer
21667
21649
  */
21668
-
21650
+ class InvalidMessageLengthError extends Error {
21651
+ name = 'InvalidMessageLengthError';
21652
+ code = 'ERR_INVALID_MSG_LENGTH';
21653
+ }
21669
21654
  /**
21670
- *
21671
- * @param {Error} obj
21672
- * @param {Extensions} props
21673
- * @returns {Error & Extensions}
21655
+ * The reported length of the next data message was larger than the configured
21656
+ * max allowable value
21674
21657
  */
21675
- function assign(obj, props) {
21676
- for (const key in props) {
21677
- Object.defineProperty(obj, key, {
21678
- value: props[key],
21679
- enumerable: true,
21680
- configurable: true,
21681
- });
21682
- }
21683
-
21684
- return obj;
21658
+ class InvalidDataLengthError extends Error {
21659
+ name = 'InvalidDataLengthError';
21660
+ code = 'ERR_MSG_DATA_TOO_LONG';
21685
21661
  }
21686
-
21687
21662
  /**
21688
- *
21689
- * @param {any} err - An Error
21690
- * @param {string|Extensions} code - A string code or props to set on the error
21691
- * @param {Extensions} [props] - Props to set on the error
21692
- * @returns {Error & Extensions}
21663
+ * The varint used to specify the length of the next data message contained more
21664
+ * bytes than the configured max allowable value
21693
21665
  */
21694
- function createError(err, code, props) {
21695
- if (!err || typeof err === 'string') {
21696
- throw new TypeError('Please pass an Error to err-code');
21697
- }
21698
-
21699
- if (!props) {
21700
- props = {};
21701
- }
21702
-
21703
- if (typeof code === 'object') {
21704
- props = code;
21705
- code = '';
21706
- }
21707
-
21708
- if (code) {
21709
- props.code = code;
21710
- }
21711
-
21712
- try {
21713
- return assign(err, props);
21714
- } catch (_) {
21715
- props.message = err.message;
21716
- props.stack = err.stack;
21717
-
21718
- const ErrClass = function () {};
21719
-
21720
- ErrClass.prototype = Object.create(Object.getPrototypeOf(err));
21721
-
21722
- // @ts-ignore
21723
- const output = assign(new ErrClass(), props);
21724
-
21725
- return output;
21726
- }
21666
+ class InvalidDataLengthLengthError extends Error {
21667
+ name = 'InvalidDataLengthLengthError';
21668
+ code = 'ERR_MSG_LENGTH_TOO_LONG';
21669
+ }
21670
+ /**
21671
+ * The incoming stream ended before the expected number of bytes were read
21672
+ */
21673
+ class UnexpectedEOFError extends Error {
21674
+ name = 'UnexpectedEOFError';
21675
+ code = 'ERR_UNEXPECTED_EOF';
21727
21676
  }
21728
-
21729
- var errCode = createError;
21730
-
21731
- var errCode$1 = /*@__PURE__*/getDefaultExportFromCjs(errCode);
21732
21677
 
21733
21678
  /* eslint max-depth: ["error", 6] */
21734
21679
  // Maximum length of the length section of the message
@@ -21760,10 +21705,10 @@ function decode(source, options) {
21760
21705
  try {
21761
21706
  dataLength = lengthDecoder(buffer);
21762
21707
  if (dataLength < 0) {
21763
- throw errCode$1(new Error('invalid message length'), 'ERR_INVALID_MSG_LENGTH');
21708
+ throw new InvalidMessageLengthError('Invalid message length');
21764
21709
  }
21765
21710
  if (dataLength > maxDataLength) {
21766
- throw errCode$1(new Error('message length too long'), 'ERR_MSG_DATA_TOO_LONG');
21711
+ throw new InvalidDataLengthError('Message length too long');
21767
21712
  }
21768
21713
  const dataLengthLength = lengthDecoder.bytes;
21769
21714
  buffer.consume(dataLengthLength);
@@ -21775,7 +21720,7 @@ function decode(source, options) {
21775
21720
  catch (err) {
21776
21721
  if (err instanceof RangeError) {
21777
21722
  if (buffer.byteLength > maxLengthLength) {
21778
- throw errCode$1(new Error('message length length too long'), 'ERR_MSG_LENGTH_TOO_LONG');
21723
+ throw new InvalidDataLengthLengthError('Message length length too long');
21779
21724
  }
21780
21725
  break;
21781
21726
  }
@@ -21804,7 +21749,7 @@ function decode(source, options) {
21804
21749
  yield* maybeYield();
21805
21750
  }
21806
21751
  if (buffer.byteLength > 0) {
21807
- throw errCode$1(new Error('unexpected end of input'), 'ERR_UNEXPECTED_EOF');
21752
+ throw new UnexpectedEOFError('Unexpected end of input');
21808
21753
  }
21809
21754
  })();
21810
21755
  }
@@ -21814,7 +21759,7 @@ function decode(source, options) {
21814
21759
  yield* maybeYield();
21815
21760
  }
21816
21761
  if (buffer.byteLength > 0) {
21817
- throw errCode$1(new Error('unexpected end of input'), 'ERR_UNEXPECTED_EOF');
21762
+ throw new UnexpectedEOFError('Unexpected end of input');
21818
21763
  }
21819
21764
  })();
21820
21765
  }
@@ -22649,7 +22594,7 @@ var FilterRequest;
22649
22594
  }
22650
22595
  case 3: {
22651
22596
  if (opts.limits?.contentFilters != null && obj.contentFilters.length === opts.limits.contentFilters) {
22652
- throw new CodeError('decode error - map field "contentFilters" had too many elements', 'ERR_MAX_LENGTH');
22597
+ throw new MaxLengthError('Decode error - map field "contentFilters" had too many elements');
22653
22598
  }
22654
22599
  obj.contentFilters.push(FilterRequest.ContentFilter.codec().decode(reader, reader.uint32(), {
22655
22600
  limits: opts.limits?.contentFilters$
@@ -22702,7 +22647,7 @@ var MessagePush$1;
22702
22647
  switch (tag >>> 3) {
22703
22648
  case 1: {
22704
22649
  if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
22705
- throw new CodeError('decode error - map field "messages" had too many elements', 'ERR_MAX_LENGTH');
22650
+ throw new MaxLengthError('Decode error - map field "messages" had too many elements');
22706
22651
  }
22707
22652
  obj.messages.push(WakuMessage$3.codec().decode(reader, reader.uint32(), {
22708
22653
  limits: opts.limits?.messages$
@@ -23121,7 +23066,7 @@ var FilterSubscribeRequest;
23121
23066
  }
23122
23067
  case 11: {
23123
23068
  if (opts.limits?.contentTopics != null && obj.contentTopics.length === opts.limits.contentTopics) {
23124
- throw new CodeError('decode error - map field "contentTopics" had too many elements', 'ERR_MAX_LENGTH');
23069
+ throw new MaxLengthError('Decode error - map field "contentTopics" had too many elements');
23125
23070
  }
23126
23071
  obj.contentTopics.push(reader.string());
23127
23072
  break;
@@ -23843,113 +23788,26 @@ var WakuMessage$1;
23843
23788
  /* eslint-disable @typescript-eslint/no-namespace */
23844
23789
  /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
23845
23790
  /* eslint-disable @typescript-eslint/no-empty-interface */
23846
- var Index;
23847
- (function (Index) {
23791
+ var WakuMessageKeyValue;
23792
+ (function (WakuMessageKeyValue) {
23848
23793
  let _codec;
23849
- Index.codec = () => {
23794
+ WakuMessageKeyValue.codec = () => {
23850
23795
  if (_codec == null) {
23851
23796
  _codec = message((obj, w, opts = {}) => {
23852
23797
  if (opts.lengthDelimited !== false) {
23853
23798
  w.fork();
23854
23799
  }
23855
- if ((obj.digest != null && obj.digest.byteLength > 0)) {
23800
+ if (obj.messageHash != null) {
23856
23801
  w.uint32(10);
23857
- w.bytes(obj.digest);
23858
- }
23859
- if ((obj.receiverTime != null && obj.receiverTime !== 0n)) {
23860
- w.uint32(16);
23861
- w.sint64(obj.receiverTime);
23802
+ w.bytes(obj.messageHash);
23862
23803
  }
23863
- if ((obj.senderTime != null && obj.senderTime !== 0n)) {
23864
- w.uint32(24);
23865
- w.sint64(obj.senderTime);
23866
- }
23867
- if ((obj.pubsubTopic != null && obj.pubsubTopic !== '')) {
23868
- w.uint32(34);
23869
- w.string(obj.pubsubTopic);
23870
- }
23871
- if (opts.lengthDelimited !== false) {
23872
- w.ldelim();
23873
- }
23874
- }, (reader, length, opts = {}) => {
23875
- const obj = {
23876
- digest: alloc$2(0),
23877
- receiverTime: 0n,
23878
- senderTime: 0n,
23879
- pubsubTopic: ''
23880
- };
23881
- const end = length == null ? reader.len : reader.pos + length;
23882
- while (reader.pos < end) {
23883
- const tag = reader.uint32();
23884
- switch (tag >>> 3) {
23885
- case 1: {
23886
- obj.digest = reader.bytes();
23887
- break;
23888
- }
23889
- case 2: {
23890
- obj.receiverTime = reader.sint64();
23891
- break;
23892
- }
23893
- case 3: {
23894
- obj.senderTime = reader.sint64();
23895
- break;
23896
- }
23897
- case 4: {
23898
- obj.pubsubTopic = reader.string();
23899
- break;
23900
- }
23901
- default: {
23902
- reader.skipType(tag & 7);
23903
- break;
23904
- }
23905
- }
23906
- }
23907
- return obj;
23908
- });
23909
- }
23910
- return _codec;
23911
- };
23912
- Index.encode = (obj) => {
23913
- return encodeMessage(obj, Index.codec());
23914
- };
23915
- Index.decode = (buf, opts) => {
23916
- return decodeMessage(buf, Index.codec(), opts);
23917
- };
23918
- })(Index || (Index = {}));
23919
- var PagingInfo;
23920
- (function (PagingInfo) {
23921
- (function (Direction) {
23922
- Direction["BACKWARD"] = "BACKWARD";
23923
- Direction["FORWARD"] = "FORWARD";
23924
- })(PagingInfo.Direction || (PagingInfo.Direction = {}));
23925
- let __DirectionValues;
23926
- (function (__DirectionValues) {
23927
- __DirectionValues[__DirectionValues["BACKWARD"] = 0] = "BACKWARD";
23928
- __DirectionValues[__DirectionValues["FORWARD"] = 1] = "FORWARD";
23929
- })(__DirectionValues || (__DirectionValues = {}));
23930
- (function (Direction) {
23931
- Direction.codec = () => {
23932
- return enumeration(__DirectionValues);
23933
- };
23934
- })(PagingInfo.Direction || (PagingInfo.Direction = {}));
23935
- let _codec;
23936
- PagingInfo.codec = () => {
23937
- if (_codec == null) {
23938
- _codec = message((obj, w, opts = {}) => {
23939
- if (opts.lengthDelimited !== false) {
23940
- w.fork();
23941
- }
23942
- if (obj.pageSize != null) {
23943
- w.uint32(8);
23944
- w.uint64(obj.pageSize);
23945
- }
23946
- if (obj.cursor != null) {
23804
+ if (obj.message != null) {
23947
23805
  w.uint32(18);
23948
- Index.codec().encode(obj.cursor, w);
23806
+ WakuMessage.codec().encode(obj.message, w);
23949
23807
  }
23950
- if (obj.direction != null) {
23951
- w.uint32(24);
23952
- PagingInfo.Direction.codec().encode(obj.direction, w);
23808
+ if (obj.pubsubTopic != null) {
23809
+ w.uint32(26);
23810
+ w.string(obj.pubsubTopic);
23953
23811
  }
23954
23812
  if (opts.lengthDelimited !== false) {
23955
23813
  w.ldelim();
@@ -23961,17 +23819,17 @@ var PagingInfo;
23961
23819
  const tag = reader.uint32();
23962
23820
  switch (tag >>> 3) {
23963
23821
  case 1: {
23964
- obj.pageSize = reader.uint64();
23822
+ obj.messageHash = reader.bytes();
23965
23823
  break;
23966
23824
  }
23967
23825
  case 2: {
23968
- obj.cursor = Index.codec().decode(reader, reader.uint32(), {
23969
- limits: opts.limits?.cursor
23826
+ obj.message = WakuMessage.codec().decode(reader, reader.uint32(), {
23827
+ limits: opts.limits?.message
23970
23828
  });
23971
23829
  break;
23972
23830
  }
23973
23831
  case 3: {
23974
- obj.direction = PagingInfo.Direction.codec().decode(reader);
23832
+ obj.pubsubTopic = reader.string();
23975
23833
  break;
23976
23834
  }
23977
23835
  default: {
@@ -23985,217 +23843,125 @@ var PagingInfo;
23985
23843
  }
23986
23844
  return _codec;
23987
23845
  };
23988
- PagingInfo.encode = (obj) => {
23989
- return encodeMessage(obj, PagingInfo.codec());
23846
+ WakuMessageKeyValue.encode = (obj) => {
23847
+ return encodeMessage(obj, WakuMessageKeyValue.codec());
23990
23848
  };
23991
- PagingInfo.decode = (buf, opts) => {
23992
- return decodeMessage(buf, PagingInfo.codec(), opts);
23849
+ WakuMessageKeyValue.decode = (buf, opts) => {
23850
+ return decodeMessage(buf, WakuMessageKeyValue.codec(), opts);
23993
23851
  };
23994
- })(PagingInfo || (PagingInfo = {}));
23995
- var ContentFilter;
23996
- (function (ContentFilter) {
23852
+ })(WakuMessageKeyValue || (WakuMessageKeyValue = {}));
23853
+ var StoreQueryRequest;
23854
+ (function (StoreQueryRequest) {
23997
23855
  let _codec;
23998
- ContentFilter.codec = () => {
23856
+ StoreQueryRequest.codec = () => {
23999
23857
  if (_codec == null) {
24000
23858
  _codec = message((obj, w, opts = {}) => {
24001
23859
  if (opts.lengthDelimited !== false) {
24002
23860
  w.fork();
24003
23861
  }
24004
- if ((obj.contentTopic != null && obj.contentTopic !== '')) {
23862
+ if ((obj.requestId != null && obj.requestId !== '')) {
24005
23863
  w.uint32(10);
24006
- w.string(obj.contentTopic);
23864
+ w.string(obj.requestId);
24007
23865
  }
24008
- if (opts.lengthDelimited !== false) {
24009
- w.ldelim();
23866
+ if ((obj.includeData != null && obj.includeData !== false)) {
23867
+ w.uint32(16);
23868
+ w.bool(obj.includeData);
24010
23869
  }
24011
- }, (reader, length, opts = {}) => {
24012
- const obj = {
24013
- contentTopic: ''
24014
- };
24015
- const end = length == null ? reader.len : reader.pos + length;
24016
- while (reader.pos < end) {
24017
- const tag = reader.uint32();
24018
- switch (tag >>> 3) {
24019
- case 1: {
24020
- obj.contentTopic = reader.string();
24021
- break;
24022
- }
24023
- default: {
24024
- reader.skipType(tag & 7);
24025
- break;
24026
- }
23870
+ if (obj.pubsubTopic != null) {
23871
+ w.uint32(82);
23872
+ w.string(obj.pubsubTopic);
23873
+ }
23874
+ if (obj.contentTopics != null) {
23875
+ for (const value of obj.contentTopics) {
23876
+ w.uint32(90);
23877
+ w.string(value);
24027
23878
  }
24028
23879
  }
24029
- return obj;
24030
- });
24031
- }
24032
- return _codec;
24033
- };
24034
- ContentFilter.encode = (obj) => {
24035
- return encodeMessage(obj, ContentFilter.codec());
24036
- };
24037
- ContentFilter.decode = (buf, opts) => {
24038
- return decodeMessage(buf, ContentFilter.codec(), opts);
24039
- };
24040
- })(ContentFilter || (ContentFilter = {}));
24041
- var HistoryQuery;
24042
- (function (HistoryQuery) {
24043
- let _codec;
24044
- HistoryQuery.codec = () => {
24045
- if (_codec == null) {
24046
- _codec = message((obj, w, opts = {}) => {
24047
- if (opts.lengthDelimited !== false) {
24048
- w.fork();
23880
+ if (obj.timeStart != null) {
23881
+ w.uint32(96);
23882
+ w.sint64(obj.timeStart);
24049
23883
  }
24050
- if (obj.pubsubTopic != null) {
24051
- w.uint32(18);
24052
- w.string(obj.pubsubTopic);
23884
+ if (obj.timeEnd != null) {
23885
+ w.uint32(104);
23886
+ w.sint64(obj.timeEnd);
24053
23887
  }
24054
- if (obj.contentFilters != null) {
24055
- for (const value of obj.contentFilters) {
24056
- w.uint32(26);
24057
- ContentFilter.codec().encode(value, w);
23888
+ if (obj.messageHashes != null) {
23889
+ for (const value of obj.messageHashes) {
23890
+ w.uint32(162);
23891
+ w.bytes(value);
24058
23892
  }
24059
23893
  }
24060
- if (obj.pagingInfo != null) {
24061
- w.uint32(34);
24062
- PagingInfo.codec().encode(obj.pagingInfo, w);
23894
+ if (obj.paginationCursor != null) {
23895
+ w.uint32(410);
23896
+ w.bytes(obj.paginationCursor);
24063
23897
  }
24064
- if (obj.startTime != null) {
24065
- w.uint32(40);
24066
- w.sint64(obj.startTime);
23898
+ if ((obj.paginationForward != null && obj.paginationForward !== false)) {
23899
+ w.uint32(416);
23900
+ w.bool(obj.paginationForward);
24067
23901
  }
24068
- if (obj.endTime != null) {
24069
- w.uint32(48);
24070
- w.sint64(obj.endTime);
23902
+ if (obj.paginationLimit != null) {
23903
+ w.uint32(424);
23904
+ w.uint64(obj.paginationLimit);
24071
23905
  }
24072
23906
  if (opts.lengthDelimited !== false) {
24073
23907
  w.ldelim();
24074
23908
  }
24075
23909
  }, (reader, length, opts = {}) => {
24076
23910
  const obj = {
24077
- contentFilters: []
23911
+ requestId: '',
23912
+ includeData: false,
23913
+ contentTopics: [],
23914
+ messageHashes: [],
23915
+ paginationForward: false
24078
23916
  };
24079
23917
  const end = length == null ? reader.len : reader.pos + length;
24080
23918
  while (reader.pos < end) {
24081
23919
  const tag = reader.uint32();
24082
23920
  switch (tag >>> 3) {
24083
- case 2: {
24084
- obj.pubsubTopic = reader.string();
23921
+ case 1: {
23922
+ obj.requestId = reader.string();
24085
23923
  break;
24086
23924
  }
24087
- case 3: {
24088
- if (opts.limits?.contentFilters != null && obj.contentFilters.length === opts.limits.contentFilters) {
24089
- throw new CodeError('decode error - map field "contentFilters" had too many elements', 'ERR_MAX_LENGTH');
24090
- }
24091
- obj.contentFilters.push(ContentFilter.codec().decode(reader, reader.uint32(), {
24092
- limits: opts.limits?.contentFilters$
24093
- }));
23925
+ case 2: {
23926
+ obj.includeData = reader.bool();
24094
23927
  break;
24095
23928
  }
24096
- case 4: {
24097
- obj.pagingInfo = PagingInfo.codec().decode(reader, reader.uint32(), {
24098
- limits: opts.limits?.pagingInfo
24099
- });
23929
+ case 10: {
23930
+ obj.pubsubTopic = reader.string();
24100
23931
  break;
24101
23932
  }
24102
- case 5: {
24103
- obj.startTime = reader.sint64();
23933
+ case 11: {
23934
+ if (opts.limits?.contentTopics != null && obj.contentTopics.length === opts.limits.contentTopics) {
23935
+ throw new MaxLengthError('Decode error - map field "contentTopics" had too many elements');
23936
+ }
23937
+ obj.contentTopics.push(reader.string());
24104
23938
  break;
24105
23939
  }
24106
- case 6: {
24107
- obj.endTime = reader.sint64();
23940
+ case 12: {
23941
+ obj.timeStart = reader.sint64();
24108
23942
  break;
24109
23943
  }
24110
- default: {
24111
- reader.skipType(tag & 7);
23944
+ case 13: {
23945
+ obj.timeEnd = reader.sint64();
24112
23946
  break;
24113
23947
  }
24114
- }
24115
- }
24116
- return obj;
24117
- });
24118
- }
24119
- return _codec;
24120
- };
24121
- HistoryQuery.encode = (obj) => {
24122
- return encodeMessage(obj, HistoryQuery.codec());
24123
- };
24124
- HistoryQuery.decode = (buf, opts) => {
24125
- return decodeMessage(buf, HistoryQuery.codec(), opts);
24126
- };
24127
- })(HistoryQuery || (HistoryQuery = {}));
24128
- var HistoryResponse;
24129
- (function (HistoryResponse) {
24130
- let HistoryError;
24131
- (function (HistoryError) {
24132
- HistoryError["NONE"] = "NONE";
24133
- HistoryError["INVALID_CURSOR"] = "INVALID_CURSOR";
24134
- HistoryError["TOO_MANY_REQUESTS"] = "TOO_MANY_REQUESTS";
24135
- HistoryError["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
24136
- })(HistoryError = HistoryResponse.HistoryError || (HistoryResponse.HistoryError = {}));
24137
- let __HistoryErrorValues;
24138
- (function (__HistoryErrorValues) {
24139
- __HistoryErrorValues[__HistoryErrorValues["NONE"] = 0] = "NONE";
24140
- __HistoryErrorValues[__HistoryErrorValues["INVALID_CURSOR"] = 1] = "INVALID_CURSOR";
24141
- __HistoryErrorValues[__HistoryErrorValues["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
24142
- __HistoryErrorValues[__HistoryErrorValues["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
24143
- })(__HistoryErrorValues || (__HistoryErrorValues = {}));
24144
- (function (HistoryError) {
24145
- HistoryError.codec = () => {
24146
- return enumeration(__HistoryErrorValues);
24147
- };
24148
- })(HistoryError = HistoryResponse.HistoryError || (HistoryResponse.HistoryError = {}));
24149
- let _codec;
24150
- HistoryResponse.codec = () => {
24151
- if (_codec == null) {
24152
- _codec = message((obj, w, opts = {}) => {
24153
- if (opts.lengthDelimited !== false) {
24154
- w.fork();
24155
- }
24156
- if (obj.messages != null) {
24157
- for (const value of obj.messages) {
24158
- w.uint32(18);
24159
- WakuMessage.codec().encode(value, w);
24160
- }
24161
- }
24162
- if (obj.pagingInfo != null) {
24163
- w.uint32(26);
24164
- PagingInfo.codec().encode(obj.pagingInfo, w);
24165
- }
24166
- if (obj.error != null && __HistoryErrorValues[obj.error] !== 0) {
24167
- w.uint32(32);
24168
- HistoryResponse.HistoryError.codec().encode(obj.error, w);
24169
- }
24170
- if (opts.lengthDelimited !== false) {
24171
- w.ldelim();
24172
- }
24173
- }, (reader, length, opts = {}) => {
24174
- const obj = {
24175
- messages: [],
24176
- error: HistoryError.NONE
24177
- };
24178
- const end = length == null ? reader.len : reader.pos + length;
24179
- while (reader.pos < end) {
24180
- const tag = reader.uint32();
24181
- switch (tag >>> 3) {
24182
- case 2: {
24183
- if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
24184
- throw new CodeError('decode error - map field "messages" had too many elements', 'ERR_MAX_LENGTH');
23948
+ case 20: {
23949
+ if (opts.limits?.messageHashes != null && obj.messageHashes.length === opts.limits.messageHashes) {
23950
+ throw new MaxLengthError('Decode error - map field "messageHashes" had too many elements');
24185
23951
  }
24186
- obj.messages.push(WakuMessage.codec().decode(reader, reader.uint32(), {
24187
- limits: opts.limits?.messages$
24188
- }));
23952
+ obj.messageHashes.push(reader.bytes());
24189
23953
  break;
24190
23954
  }
24191
- case 3: {
24192
- obj.pagingInfo = PagingInfo.codec().decode(reader, reader.uint32(), {
24193
- limits: opts.limits?.pagingInfo
24194
- });
23955
+ case 51: {
23956
+ obj.paginationCursor = reader.bytes();
24195
23957
  break;
24196
23958
  }
24197
- case 4: {
24198
- obj.error = HistoryResponse.HistoryError.codec().decode(reader);
23959
+ case 52: {
23960
+ obj.paginationForward = reader.bool();
23961
+ break;
23962
+ }
23963
+ case 53: {
23964
+ obj.paginationLimit = reader.uint64();
24199
23965
  break;
24200
23966
  }
24201
23967
  default: {
@@ -24209,17 +23975,17 @@ var HistoryResponse;
24209
23975
  }
24210
23976
  return _codec;
24211
23977
  };
24212
- HistoryResponse.encode = (obj) => {
24213
- return encodeMessage(obj, HistoryResponse.codec());
23978
+ StoreQueryRequest.encode = (obj) => {
23979
+ return encodeMessage(obj, StoreQueryRequest.codec());
24214
23980
  };
24215
- HistoryResponse.decode = (buf, opts) => {
24216
- return decodeMessage(buf, HistoryResponse.codec(), opts);
23981
+ StoreQueryRequest.decode = (buf, opts) => {
23982
+ return decodeMessage(buf, StoreQueryRequest.codec(), opts);
24217
23983
  };
24218
- })(HistoryResponse || (HistoryResponse = {}));
24219
- var HistoryRpc;
24220
- (function (HistoryRpc) {
23984
+ })(StoreQueryRequest || (StoreQueryRequest = {}));
23985
+ var StoreQueryResponse;
23986
+ (function (StoreQueryResponse) {
24221
23987
  let _codec;
24222
- HistoryRpc.codec = () => {
23988
+ StoreQueryResponse.codec = () => {
24223
23989
  if (_codec == null) {
24224
23990
  _codec = message((obj, w, opts = {}) => {
24225
23991
  if (opts.lengthDelimited !== false) {
@@ -24229,20 +23995,31 @@ var HistoryRpc;
24229
23995
  w.uint32(10);
24230
23996
  w.string(obj.requestId);
24231
23997
  }
24232
- if (obj.query != null) {
24233
- w.uint32(18);
24234
- HistoryQuery.codec().encode(obj.query, w);
23998
+ if (obj.statusCode != null) {
23999
+ w.uint32(80);
24000
+ w.uint32(obj.statusCode);
24235
24001
  }
24236
- if (obj.response != null) {
24237
- w.uint32(26);
24238
- HistoryResponse.codec().encode(obj.response, w);
24002
+ if (obj.statusDesc != null) {
24003
+ w.uint32(90);
24004
+ w.string(obj.statusDesc);
24005
+ }
24006
+ if (obj.messages != null) {
24007
+ for (const value of obj.messages) {
24008
+ w.uint32(162);
24009
+ WakuMessageKeyValue.codec().encode(value, w);
24010
+ }
24011
+ }
24012
+ if (obj.paginationCursor != null) {
24013
+ w.uint32(410);
24014
+ w.bytes(obj.paginationCursor);
24239
24015
  }
24240
24016
  if (opts.lengthDelimited !== false) {
24241
24017
  w.ldelim();
24242
24018
  }
24243
24019
  }, (reader, length, opts = {}) => {
24244
24020
  const obj = {
24245
- requestId: ''
24021
+ requestId: '',
24022
+ messages: []
24246
24023
  };
24247
24024
  const end = length == null ? reader.len : reader.pos + length;
24248
24025
  while (reader.pos < end) {
@@ -24252,16 +24029,25 @@ var HistoryRpc;
24252
24029
  obj.requestId = reader.string();
24253
24030
  break;
24254
24031
  }
24255
- case 2: {
24256
- obj.query = HistoryQuery.codec().decode(reader, reader.uint32(), {
24257
- limits: opts.limits?.query
24258
- });
24032
+ case 10: {
24033
+ obj.statusCode = reader.uint32();
24259
24034
  break;
24260
24035
  }
24261
- case 3: {
24262
- obj.response = HistoryResponse.codec().decode(reader, reader.uint32(), {
24263
- limits: opts.limits?.response
24264
- });
24036
+ case 11: {
24037
+ obj.statusDesc = reader.string();
24038
+ break;
24039
+ }
24040
+ case 20: {
24041
+ if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
24042
+ throw new MaxLengthError('Decode error - map field "messages" had too many elements');
24043
+ }
24044
+ obj.messages.push(WakuMessageKeyValue.codec().decode(reader, reader.uint32(), {
24045
+ limits: opts.limits?.messages$
24046
+ }));
24047
+ break;
24048
+ }
24049
+ case 51: {
24050
+ obj.paginationCursor = reader.bytes();
24265
24051
  break;
24266
24052
  }
24267
24053
  default: {
@@ -24275,13 +24061,13 @@ var HistoryRpc;
24275
24061
  }
24276
24062
  return _codec;
24277
24063
  };
24278
- HistoryRpc.encode = (obj) => {
24279
- return encodeMessage(obj, HistoryRpc.codec());
24064
+ StoreQueryResponse.encode = (obj) => {
24065
+ return encodeMessage(obj, StoreQueryResponse.codec());
24280
24066
  };
24281
- HistoryRpc.decode = (buf, opts) => {
24282
- return decodeMessage(buf, HistoryRpc.codec(), opts);
24067
+ StoreQueryResponse.decode = (buf, opts) => {
24068
+ return decodeMessage(buf, StoreQueryResponse.codec(), opts);
24283
24069
  };
24284
- })(HistoryRpc || (HistoryRpc = {}));
24070
+ })(StoreQueryResponse || (StoreQueryResponse = {}));
24285
24071
  var RateLimitProof;
24286
24072
  (function (RateLimitProof) {
24287
24073
  let _codec;
@@ -24601,7 +24387,7 @@ var PeerExchangeResponse;
24601
24387
  switch (tag >>> 3) {
24602
24388
  case 1: {
24603
24389
  if (opts.limits?.peerInfos != null && obj.peerInfos.length === opts.limits.peerInfos) {
24604
- throw new CodeError('decode error - map field "peerInfos" had too many elements', 'ERR_MAX_LENGTH');
24390
+ throw new MaxLengthError('Decode error - map field "peerInfos" had too many elements');
24605
24391
  }
24606
24392
  obj.peerInfos.push(PeerInfo.codec().decode(reader, reader.uint32(), {
24607
24393
  limits: opts.limits?.peerInfos$
@@ -24724,7 +24510,7 @@ var WakuMetadataRequest;
24724
24510
  }
24725
24511
  case 2: {
24726
24512
  if (opts.limits?.shards != null && obj.shards.length === opts.limits.shards) {
24727
- throw new CodeError('decode error - map field "shards" had too many elements', 'ERR_MAX_LENGTH');
24513
+ throw new MaxLengthError('Decode error - map field "shards" had too many elements');
24728
24514
  }
24729
24515
  obj.shards.push(reader.uint32());
24730
24516
  break;
@@ -24783,7 +24569,7 @@ var WakuMetadataResponse;
24783
24569
  }
24784
24570
  case 2: {
24785
24571
  if (opts.limits?.shards != null && obj.shards.length === opts.limits.shards) {
24786
- throw new CodeError('decode error - map field "shards" had too many elements', 'ERR_MAX_LENGTH');
24572
+ throw new MaxLengthError('Decode error - map field "shards" had too many elements');
24787
24573
  }
24788
24574
  obj.shards.push(reader.uint32());
24789
24575
  break;
@@ -24863,11 +24649,11 @@ class WakuPeerExchange extends BaseProtocol {
24863
24649
  * Make a peer exchange query to a peer
24864
24650
  */
24865
24651
  async query(params) {
24866
- const { numPeers } = params;
24652
+ const { numPeers, peerId } = params;
24867
24653
  const rpcQuery = PeerExchangeRPC.createRequest({
24868
24654
  numPeers: BigInt(numPeers)
24869
24655
  });
24870
- const peer = await this.peerStore.get(params.peerId);
24656
+ const peer = await this.peerStore.get(peerId);
24871
24657
  if (!peer) {
24872
24658
  return {
24873
24659
  peerInfos: null,
@@ -24963,6 +24749,7 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
24963
24749
  if (this.isStarted) {
24964
24750
  return;
24965
24751
  }
24752
+ this.dispatchEvent(new CustomEvent("waku:peer-exchange:started", { detail: true }));
24966
24753
  log$1.info("Starting peer exchange node discovery, discovering peers");
24967
24754
  // might be better to use "peer:identify" or "peer:update"
24968
24755
  this.components.events.addEventListener("peer:identify", this.handleDiscoveredPeer);
@@ -25022,7 +24809,31 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
25022
24809
  }
25023
24810
  const hasPeer = await this.components.peerStore.has(peerId);
25024
24811
  if (hasPeer) {
25025
- continue;
24812
+ const { hasMultiaddrDiff, hasShardDiff } = await this.checkPeerInfoDiff(peerInfo, shardInfo);
24813
+ if (hasMultiaddrDiff || hasShardDiff) {
24814
+ log$1.info(`Peer ${peerId.toString()} has updated multiaddrs or shardInfo, updating`);
24815
+ if (hasMultiaddrDiff) {
24816
+ log$1.info(`Peer ${peerId.toString()} has updated multiaddrs, updating`);
24817
+ await this.components.peerStore.patch(peerId, {
24818
+ multiaddrs: peerInfo.multiaddrs
24819
+ });
24820
+ }
24821
+ if (hasShardDiff && shardInfo) {
24822
+ log$1.info(`Peer ${peerId.toString()} has updated shardInfo, updating`);
24823
+ await this.components.peerStore.merge(peerId, {
24824
+ metadata: {
24825
+ shardInfo: encodeRelayShard(shardInfo)
24826
+ }
24827
+ });
24828
+ this.dispatchEvent(new CustomEvent("peer", {
24829
+ detail: {
24830
+ id: peerId,
24831
+ multiaddrs: peerInfo.multiaddrs
24832
+ }
24833
+ }));
24834
+ }
24835
+ continue;
24836
+ }
25026
24837
  }
25027
24838
  // update the tags for the peer
25028
24839
  await this.components.peerStore.save(peerId, {
@@ -25036,6 +24847,9 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
25036
24847
  metadata: {
25037
24848
  shardInfo: encodeRelayShard(shardInfo)
25038
24849
  }
24850
+ }),
24851
+ ...(peerInfo.multiaddrs && {
24852
+ multiaddrs: peerInfo.multiaddrs
25039
24853
  })
25040
24854
  });
25041
24855
  log$1.info(`Discovered peer: ${peerId.toString()}`);
@@ -25053,6 +24867,24 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
25053
24867
  this.queryingPeers.delete(peerIdStr);
25054
24868
  this.queryAttempts.delete(peerIdStr);
25055
24869
  }
24870
+ async checkPeerInfoDiff(peerInfo, shardInfo) {
24871
+ const { id: peerId } = peerInfo;
24872
+ const peer = await this.components.peerStore.get(peerId);
24873
+ const existingMultiaddrs = peer.addresses.map((a) => a.multiaddr.toString());
24874
+ const newMultiaddrs = peerInfo.multiaddrs.map((ma) => ma.toString());
24875
+ const hasMultiaddrDiff = existingMultiaddrs.some((ma) => !newMultiaddrs.includes(ma));
24876
+ let hasShardDiff = false;
24877
+ const existingShardInfoBytes = peer.metadata.get("shardInfo");
24878
+ if (existingShardInfoBytes) {
24879
+ const existingShardInfo = decodeRelayShard(existingShardInfoBytes);
24880
+ if (existingShardInfo || shardInfo) {
24881
+ hasShardDiff =
24882
+ existingShardInfo.clusterId !== shardInfo?.clusterId ||
24883
+ existingShardInfo.shards.some((shard) => !shardInfo?.shards.includes(shard));
24884
+ }
24885
+ }
24886
+ return { hasMultiaddrDiff, hasShardDiff };
24887
+ }
25056
24888
  }
25057
24889
  function wakuPeerExchangeDiscovery(pubsubTopics) {
25058
24890
  return (components) => new PeerExchangeDiscovery(components, pubsubTopics);
@@ -25098,7 +24930,13 @@ async function createFromParts(multihash, privKey, pubKey) {
25098
24930
  const key = unmarshalPublicKey(pubKey);
25099
24931
  return createFromPubKey(key);
25100
24932
  }
25101
- return peerIdFromBytes(multihash);
24933
+ const peerId = peerIdFromBytes(multihash);
24934
+ if (peerId.type !== 'Ed25519' && peerId.type !== 'secp256k1' && peerId.type !== 'RSA') {
24935
+ // should not be possible since `multihash` is derived from keys and these
24936
+ // are the cryptographic peer id types
24937
+ throw new Error('Supplied PeerID is invalid');
24938
+ }
24939
+ return peerId;
25102
24940
  }
25103
24941
 
25104
24942
  const log = new Logger$1("peer-exchange-discovery");