@waku/discovery 0.0.4-1887f4f.0 → 0.0.4-77b2cdd.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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;
@@ -537,6 +537,11 @@ var ProtocolError;
537
537
  * Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
538
538
  */
539
539
  ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
540
+ /**
541
+ * The topics passed in the decoders do not match each other, or don't exist at all.
542
+ * Ensure that all the pubsub topics used in the decoders are valid and match each other.
543
+ */
544
+ ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
540
545
  /**
541
546
  * Failure to find a peer with suitable protocols. This may due to a connection issue.
542
547
  * Mitigation can be: retrying after a given time period, display connectivity issue
@@ -567,12 +572,6 @@ var ProtocolError;
567
572
  ProtocolError["REQUEST_TIMEOUT"] = "Request timeout";
568
573
  })(ProtocolError || (ProtocolError = {}));
569
574
 
570
- var PageDirection;
571
- (function (PageDirection) {
572
- PageDirection["BACKWARD"] = "backward";
573
- PageDirection["FORWARD"] = "forward";
574
- })(PageDirection || (PageDirection = {}));
575
-
576
575
  var Tags;
577
576
  (function (Tags) {
578
577
  Tags["BOOTSTRAP"] = "bootstrap";
@@ -591,10 +590,12 @@ var EConnectionStateEvents;
591
590
  EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
592
591
  })(EConnectionStateEvents || (EConnectionStateEvents = {}));
593
592
 
594
- /**
595
- * The default cluster ID for The Waku Network
596
- */
597
- const DEFAULT_CLUSTER_ID = 1;
593
+ var HealthStatus;
594
+ (function (HealthStatus) {
595
+ HealthStatus["Unhealthy"] = "Unhealthy";
596
+ HealthStatus["MinimallyHealthy"] = "MinimallyHealthy";
597
+ HealthStatus["SufficientlyHealthy"] = "SufficientlyHealthy";
598
+ })(HealthStatus || (HealthStatus = {}));
598
599
 
599
600
  function equals$2(aa, bb) {
600
601
  if (aa === bb)
@@ -1905,41 +1906,7 @@ const bytesToUtf8 = (b) => toString$6(b, "utf8");
1905
1906
  * Encode utf-8 string to byte array.
1906
1907
  */
1907
1908
  const utf8ToBytes$1 = (s) => fromString(s, "utf8");
1908
- /**
1909
- * Concatenate using Uint8Arrays as `Buffer` has a different behavior with `DataView`
1910
- */
1911
- function concat$2(byteArrays, totalLength) {
1912
- const len = totalLength ?? byteArrays.reduce((acc, curr) => acc + curr.length, 0);
1913
- const res = new Uint8Array(len);
1914
- let offset = 0;
1915
- for (const bytes of byteArrays) {
1916
- res.set(bytes, offset);
1917
- offset += bytes.length;
1918
- }
1919
- return res;
1920
- }
1921
1909
 
1922
- const shardInfoToPubsubTopics = (shardInfo) => {
1923
- if ("contentTopics" in shardInfo && shardInfo.contentTopics) {
1924
- // Autosharding: explicitly defined content topics
1925
- return Array.from(new Set(shardInfo.contentTopics.map((contentTopic) => contentTopicToPubsubTopic(contentTopic, shardInfo.clusterId))));
1926
- }
1927
- else if ("shards" in shardInfo) {
1928
- // Static sharding
1929
- if (shardInfo.shards === undefined)
1930
- throw new Error("Invalid shard");
1931
- return Array.from(new Set(shardInfo.shards.map((index) => `/waku/2/rs/${shardInfo.clusterId ?? DEFAULT_CLUSTER_ID}/${index}`)));
1932
- }
1933
- else if ("application" in shardInfo && "version" in shardInfo) {
1934
- // Autosharding: single shard from application and version
1935
- return [
1936
- contentTopicToPubsubTopic(`/${shardInfo.application}/${shardInfo.version}/default/default`, shardInfo.clusterId)
1937
- ];
1938
- }
1939
- else {
1940
- throw new Error("Missing required configuration in shard parameters");
1941
- }
1942
- };
1943
1910
  const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
1944
1911
  const parts = pubsubTopics.split("/");
1945
1912
  if (parts.length != 6 ||
@@ -1956,112 +1923,26 @@ const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
1956
1923
  shard
1957
1924
  };
1958
1925
  };
1959
- /**
1960
- * 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/
1961
- * @param contentTopic String to validate
1962
- * @returns Object with each content topic field as an attribute
1963
- */
1964
- function ensureValidContentTopic(contentTopic) {
1965
- const parts = contentTopic.split("/");
1966
- if (parts.length < 5 || parts.length > 6) {
1967
- throw Error("Content topic format is invalid");
1968
- }
1969
- // Validate generation field if present
1970
- let generation = 0;
1971
- if (parts.length == 6) {
1972
- generation = parseInt(parts[1]);
1973
- if (isNaN(generation)) {
1974
- throw new Error("Invalid generation field in content topic");
1975
- }
1976
- if (generation > 0) {
1977
- throw new Error("Generation greater than 0 is not supported");
1978
- }
1979
- }
1980
- // Validate remaining fields
1981
- const fields = parts.splice(-4);
1982
- // Validate application field
1983
- if (fields[0].length == 0) {
1984
- throw new Error("Application field cannot be empty");
1985
- }
1986
- // Validate version field
1987
- if (fields[1].length == 0) {
1988
- throw new Error("Version field cannot be empty");
1989
- }
1990
- // Validate topic name field
1991
- if (fields[2].length == 0) {
1992
- throw new Error("Topic name field cannot be empty");
1993
- }
1994
- // Validate encoding field
1995
- if (fields[3].length == 0) {
1996
- throw new Error("Encoding field cannot be empty");
1997
- }
1926
+ const pubsubTopicsToShardInfo = (pubsubTopics) => {
1927
+ const shardInfoSet = new Set();
1928
+ const clusterIds = new Set();
1929
+ for (const topic of pubsubTopics) {
1930
+ const { clusterId, shard } = pubsubTopicToSingleShardInfo(topic);
1931
+ shardInfoSet.add(`${clusterId}:${shard}`);
1932
+ clusterIds.add(clusterId);
1933
+ }
1934
+ if (shardInfoSet.size === 0) {
1935
+ throw new Error("No valid pubsub topics provided");
1936
+ }
1937
+ if (clusterIds.size > 1) {
1938
+ throw new Error("Pubsub topics from multiple cluster IDs are not supported");
1939
+ }
1940
+ const clusterId = clusterIds.values().next().value;
1941
+ const shards = Array.from(shardInfoSet).map((info) => parseInt(info.split(":")[1]));
1998
1942
  return {
1999
- generation,
2000
- application: fields[0],
2001
- version: fields[1],
2002
- topicName: fields[2],
2003
- encoding: fields[3]
1943
+ clusterId,
1944
+ shards
2004
1945
  };
2005
- }
2006
- /**
2007
- * Given a string, determines which autoshard index to use for its pubsub topic.
2008
- * Based on the algorithm described in the RFC: https://rfc.vac.dev/spec/51//#algorithm
2009
- */
2010
- function contentTopicToShardIndex(contentTopic, networkShards = 8) {
2011
- const { application, version } = ensureValidContentTopic(contentTopic);
2012
- const digest = sha256$1(concat$2([utf8ToBytes$1(application), utf8ToBytes$1(version)]));
2013
- const dataview = new DataView(digest.buffer.slice(-8));
2014
- return Number(dataview.getBigUint64(0, false) % BigInt(networkShards));
2015
- }
2016
- function contentTopicToPubsubTopic(contentTopic, clusterId = DEFAULT_CLUSTER_ID, networkShards = 8) {
2017
- if (!contentTopic) {
2018
- throw Error("Content topic must be specified");
2019
- }
2020
- const shardIndex = contentTopicToShardIndex(contentTopic, networkShards);
2021
- return `/waku/2/rs/${clusterId}/${shardIndex}`;
2022
- }
2023
- /**
2024
- * Validates sharding configuration and sets defaults where possible.
2025
- * @returns Validated sharding parameters, with any missing values set to defaults
2026
- */
2027
- const ensureShardingConfigured = (shardInfo) => {
2028
- const clusterId = shardInfo.clusterId ?? DEFAULT_CLUSTER_ID;
2029
- const shards = "shards" in shardInfo ? shardInfo.shards : [];
2030
- const contentTopics = "contentTopics" in shardInfo ? shardInfo.contentTopics : [];
2031
- const [application, version] = "application" in shardInfo && "version" in shardInfo
2032
- ? [shardInfo.application, shardInfo.version]
2033
- : [undefined, undefined];
2034
- const isShardsConfigured = shards && shards.length > 0;
2035
- const isContentTopicsConfigured = contentTopics && contentTopics.length > 0;
2036
- const isApplicationVersionConfigured = application && version;
2037
- if (isShardsConfigured) {
2038
- return {
2039
- shardingParams: { clusterId, shards },
2040
- shardInfo: { clusterId, shards },
2041
- pubsubTopics: shardInfoToPubsubTopics({ clusterId, shards })
2042
- };
2043
- }
2044
- if (isContentTopicsConfigured) {
2045
- const pubsubTopics = Array.from(new Set(contentTopics.map((topic) => contentTopicToPubsubTopic(topic, clusterId))));
2046
- const shards = Array.from(new Set(contentTopics.map((topic) => contentTopicToShardIndex(topic))));
2047
- return {
2048
- shardingParams: { clusterId, contentTopics },
2049
- shardInfo: { clusterId, shards },
2050
- pubsubTopics
2051
- };
2052
- }
2053
- if (isApplicationVersionConfigured) {
2054
- const pubsubTopic = contentTopicToPubsubTopic(`/${application}/${version}/default/default`, clusterId);
2055
- return {
2056
- shardingParams: { clusterId, application, version },
2057
- shardInfo: {
2058
- clusterId,
2059
- shards: [pubsubTopicToSingleShardInfo(pubsubTopic).shard]
2060
- },
2061
- pubsubTopics: [pubsubTopic]
2062
- };
2063
- }
2064
- throw new Error("Missing minimum required configuration options for static sharding or autosharding.");
2065
1946
  };
2066
1947
 
2067
1948
  const decodeRelayShard = (bytes) => {
@@ -2707,6 +2588,8 @@ var common = setup;
2707
2588
  return false;
2708
2589
  }
2709
2590
 
2591
+ let m;
2592
+
2710
2593
  // Is webkit? http://stackoverflow.com/a/16459606/376773
2711
2594
  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
2712
2595
  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
@@ -2714,7 +2597,7 @@ var common = setup;
2714
2597
  (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
2715
2598
  // Is firefox >= v31?
2716
2599
  // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
2717
- (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
2600
+ (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
2718
2601
  // Double check webkit in userAgent just in case we are in a worker
2719
2602
  (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
2720
2603
  }
@@ -2917,7 +2800,7 @@ const _0n$5 = BigInt(0);
2917
2800
  const _1n$7 = BigInt(1);
2918
2801
  const _2n$5 = BigInt(2);
2919
2802
  const _3n$2 = BigInt(3);
2920
- const _8n$2 = BigInt(8);
2803
+ const _8n$3 = BigInt(8);
2921
2804
  const CURVE = Object.freeze({
2922
2805
  a: _0n$5,
2923
2806
  b: BigInt(7),
@@ -3021,7 +2904,7 @@ class JacobianPoint {
3021
2904
  const E = mod$1(_3n$2 * A);
3022
2905
  const F = mod$1(E * E);
3023
2906
  const X3 = mod$1(F - _2n$5 * D);
3024
- const Y3 = mod$1(E * (D - X3) - _8n$2 * C);
2907
+ const Y3 = mod$1(E * (D - X3) - _8n$3 * C);
3025
2908
  const Z3 = mod$1(_2n$5 * Y1 * Z1);
3026
2909
  return new JacobianPoint(X3, Y3, Z3);
3027
2910
  }
@@ -3121,12 +3004,12 @@ class JacobianPoint {
3121
3004
  if (256 % W) {
3122
3005
  throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
3123
3006
  }
3124
- let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
3007
+ let precomputes = affinePoint && pointPrecomputes$1.get(affinePoint);
3125
3008
  if (!precomputes) {
3126
3009
  precomputes = this.precomputeWindow(W);
3127
3010
  if (affinePoint && W !== 1) {
3128
3011
  precomputes = JacobianPoint.normalizeZ(precomputes);
3129
- pointPrecomputes.set(affinePoint, precomputes);
3012
+ pointPrecomputes$1.set(affinePoint, precomputes);
3130
3013
  }
3131
3014
  }
3132
3015
  let p = JacobianPoint.ZERO;
@@ -3182,7 +3065,7 @@ class JacobianPoint {
3182
3065
  const { x, y, z } = this;
3183
3066
  const is0 = this.equals(JacobianPoint.ZERO);
3184
3067
  if (invZ == null)
3185
- invZ = is0 ? _8n$2 : invert$1(z);
3068
+ invZ = is0 ? _8n$3 : invert$1(z);
3186
3069
  const iz1 = invZ;
3187
3070
  const iz2 = mod$1(iz1 * iz1);
3188
3071
  const iz3 = mod$1(iz2 * iz1);
@@ -3202,7 +3085,7 @@ function constTimeNegate(condition, item) {
3202
3085
  const neg = item.negate();
3203
3086
  return condition ? neg : item;
3204
3087
  }
3205
- const pointPrecomputes = new WeakMap();
3088
+ const pointPrecomputes$1 = new WeakMap();
3206
3089
  class Point {
3207
3090
  constructor(x, y) {
3208
3091
  this.x = x;
@@ -3210,7 +3093,7 @@ class Point {
3210
3093
  }
3211
3094
  _setWindowSize(windowSize) {
3212
3095
  this._WINDOW_SIZE = windowSize;
3213
- pointPrecomputes.delete(this);
3096
+ pointPrecomputes$1.delete(this);
3214
3097
  }
3215
3098
  hasEvenY() {
3216
3099
  return this.y % _2n$5 === _0n$5;
@@ -5268,6 +5151,7 @@ const table = [
5268
5151
  [478, 0, 'wss'],
5269
5152
  [479, 0, 'p2p-websocket-star'],
5270
5153
  [480, 0, 'http'],
5154
+ [481, V, 'http-path'],
5271
5155
  [777, V, 'memory']
5272
5156
  ];
5273
5157
  // populate tables
@@ -5353,6 +5237,8 @@ function convertToString(proto, buf) {
5353
5237
  return bytes2onion(buf);
5354
5238
  case 466: // certhash
5355
5239
  return bytes2mb(buf);
5240
+ case 481: // http-path
5241
+ return globalThis.encodeURIComponent(bytes2str(buf));
5356
5242
  default:
5357
5243
  return toString$6(buf, 'base16'); // no clue. convert to hex
5358
5244
  }
@@ -5387,6 +5273,8 @@ function convertToBytes(proto, str) {
5387
5273
  return onion32bytes(str);
5388
5274
  case 466: // certhash
5389
5275
  return mb2bytes(str);
5276
+ case 481: // http-path
5277
+ return str2bytes(globalThis.decodeURIComponent(str));
5390
5278
  default:
5391
5279
  return fromString(str, 'base16'); // no clue. convert from hex
5392
5280
  }
@@ -5848,7 +5736,7 @@ class Multiaddr {
5848
5736
  }
5849
5737
  const resolver = resolvers$1.get(resolvableProto.name);
5850
5738
  if (resolver == null) {
5851
- throw new CodeError$1(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
5739
+ throw new CodeError(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
5852
5740
  }
5853
5741
  const result = await resolver(this, options);
5854
5742
  return result.map(str => multiaddr(str));
@@ -6291,9 +6179,9 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
6291
6179
  // This is OK: `abstract` directory does not use noble-hashes.
6292
6180
  // User may opt-in into using different hashing library. This way, noble-hashes
6293
6181
  // won't be included into their bundle.
6294
- const _0n$4 = BigInt(0);
6295
- const _1n$6 = BigInt(1);
6296
- const _2n$4 = BigInt(2);
6182
+ const _0n$4 = /* @__PURE__ */ BigInt(0);
6183
+ const _1n$6 = /* @__PURE__ */ BigInt(1);
6184
+ const _2n$4 = /* @__PURE__ */ BigInt(2);
6297
6185
  function isBytes$1(a) {
6298
6186
  return (a instanceof Uint8Array ||
6299
6187
  (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
@@ -6302,6 +6190,10 @@ function abytes(item) {
6302
6190
  if (!isBytes$1(item))
6303
6191
  throw new Error('Uint8Array expected');
6304
6192
  }
6193
+ function abool(title, value) {
6194
+ if (typeof value !== 'boolean')
6195
+ throw new Error(`${title} must be valid boolean, got "${value}".`);
6196
+ }
6305
6197
  // Array where index 0xf0 (240) is mapped to string 'f0'
6306
6198
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
6307
6199
  /**
@@ -6444,6 +6336,25 @@ function utf8ToBytes(str) {
6444
6336
  throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
6445
6337
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
6446
6338
  }
6339
+ // Is positive bigint
6340
+ const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
6341
+ function inRange(n, min, max) {
6342
+ return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
6343
+ }
6344
+ /**
6345
+ * Asserts min <= n < max. NOTE: It's < max and not <= max.
6346
+ * @example
6347
+ * aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)
6348
+ */
6349
+ function aInRange(title, n, min, max) {
6350
+ // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?
6351
+ // consider P=256n, min=0n, max=P
6352
+ // - a for min=0 would require -1: `inRange('x', x, -1n, P)`
6353
+ // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
6354
+ // - our way is the cleanest: `inRange('x', x, 0n, P)
6355
+ if (!inRange(n, min, max))
6356
+ throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
6357
+ }
6447
6358
  // Bit operations
6448
6359
  /**
6449
6360
  * Calculates amount of bits in a bigint.
@@ -6574,9 +6485,32 @@ function validateObject(object, validators, optValidators = {}) {
6574
6485
  // const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
6575
6486
  // const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
6576
6487
  // const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
6488
+ /**
6489
+ * throws not implemented error
6490
+ */
6491
+ const notImplemented = () => {
6492
+ throw new Error('not implemented');
6493
+ };
6494
+ /**
6495
+ * Memoizes (caches) computation result.
6496
+ * Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
6497
+ */
6498
+ function memoized(fn) {
6499
+ const map = new WeakMap();
6500
+ return (arg, ...args) => {
6501
+ const val = map.get(arg);
6502
+ if (val !== undefined)
6503
+ return val;
6504
+ const computed = fn(arg, ...args);
6505
+ map.set(arg, computed);
6506
+ return computed;
6507
+ };
6508
+ }
6577
6509
 
6578
6510
  var ut = /*#__PURE__*/Object.freeze({
6579
6511
  __proto__: null,
6512
+ aInRange: aInRange,
6513
+ abool: abool,
6580
6514
  abytes: abytes,
6581
6515
  bitGet: bitGet,
6582
6516
  bitLen: bitLen,
@@ -6591,7 +6525,10 @@ var ut = /*#__PURE__*/Object.freeze({
6591
6525
  equalBytes: equalBytes,
6592
6526
  hexToBytes: hexToBytes,
6593
6527
  hexToNumber: hexToNumber,
6528
+ inRange: inRange,
6594
6529
  isBytes: isBytes$1,
6530
+ memoized: memoized,
6531
+ notImplemented: notImplemented,
6595
6532
  numberToBytesBE: numberToBytesBE,
6596
6533
  numberToBytesLE: numberToBytesLE,
6597
6534
  numberToHexUnpadded: numberToHexUnpadded,
@@ -6605,7 +6542,7 @@ var ut = /*#__PURE__*/Object.freeze({
6605
6542
  // prettier-ignore
6606
6543
  const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
6607
6544
  // prettier-ignore
6608
- const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$1 = BigInt(8);
6545
+ const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
6609
6546
  // prettier-ignore
6610
6547
  BigInt(9); BigInt(16);
6611
6548
  // Calculates a modulo b
@@ -6751,8 +6688,8 @@ function FpSqrt(P) {
6751
6688
  };
6752
6689
  }
6753
6690
  // Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
6754
- if (P % _8n$1 === _5n$1) {
6755
- const c1 = (P - _5n$1) / _8n$1;
6691
+ if (P % _8n$2 === _5n$1) {
6692
+ const c1 = (P - _5n$1) / _8n$2;
6756
6693
  return function sqrt5mod8(Fp, n) {
6757
6694
  const n2 = Fp.mul(n, _2n$3);
6758
6695
  const v = Fp.pow(n2, c1);
@@ -6850,6 +6787,9 @@ function nLength(n, nBitLength) {
6850
6787
  * * a) denormalized operations like mulN instead of mul
6851
6788
  * * b) same object shape: never add or remove keys
6852
6789
  * * c) Object.freeze
6790
+ * NOTE: operations don't check 'isValid' for all elements for performance reasons,
6791
+ * it is caller responsibility to check this.
6792
+ * This is low-level code, please make sure you know what you doing.
6853
6793
  * @param ORDER prime positive bigint
6854
6794
  * @param bitLen how many bits the field consumes
6855
6795
  * @param isLE (def: false) if encoding / decoding should be in little-endian
@@ -6905,12 +6845,6 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6905
6845
  });
6906
6846
  return Object.freeze(f);
6907
6847
  }
6908
- function FpSqrtEven(Fp, elm) {
6909
- if (!Fp.isOdd)
6910
- throw new Error(`Field doesn't have isOdd`);
6911
- const root = Fp.sqrt(elm);
6912
- return Fp.isOdd(root) ? Fp.neg(root) : root;
6913
- }
6914
6848
  /**
6915
6849
  * Returns total number of bytes consumed by the field element.
6916
6850
  * For example, 32 bytes for usual 256-bit weierstrass curve.
@@ -6964,6 +6898,10 @@ function mapHashToField(key, fieldOrder, isLE = false) {
6964
6898
  // Abelian group utilities
6965
6899
  const _0n$2 = BigInt(0);
6966
6900
  const _1n$4 = BigInt(1);
6901
+ // Since points in different groups cannot be equal (different object constructor),
6902
+ // we can have single place to store precomputes
6903
+ const pointPrecomputes = new WeakMap();
6904
+ const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
6967
6905
  // Elliptic curve multiplication of Point by scalar. Fragile.
6968
6906
  // Scalars should always be less than curve order: this should be checked inside of a curve itself.
6969
6907
  // Creates precomputation tables for fast multiplication:
@@ -6980,7 +6918,12 @@ function wNAF(c, bits) {
6980
6918
  const neg = item.negate();
6981
6919
  return condition ? neg : item;
6982
6920
  };
6921
+ const validateW = (W) => {
6922
+ if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
6923
+ throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
6924
+ };
6983
6925
  const opts = (W) => {
6926
+ validateW(W);
6984
6927
  const windows = Math.ceil(bits / W) + 1; // +1, because
6985
6928
  const windowSize = 2 ** (W - 1); // -1 because we skip zero
6986
6929
  return { windows, windowSize };
@@ -7080,19 +7023,25 @@ function wNAF(c, bits) {
7080
7023
  // which makes it less const-time: around 1 bigint multiply.
7081
7024
  return { p, f };
7082
7025
  },
7083
- wNAFCached(P, precomputesMap, n, transform) {
7084
- // @ts-ignore
7085
- const W = P._WINDOW_SIZE || 1;
7026
+ wNAFCached(P, n, transform) {
7027
+ const W = pointWindowSizes.get(P) || 1;
7086
7028
  // Calculate precomputes on a first run, reuse them after
7087
- let comp = precomputesMap.get(P);
7029
+ let comp = pointPrecomputes.get(P);
7088
7030
  if (!comp) {
7089
7031
  comp = this.precomputeWindow(P, W);
7090
- if (W !== 1) {
7091
- precomputesMap.set(P, transform(comp));
7092
- }
7032
+ if (W !== 1)
7033
+ pointPrecomputes.set(P, transform(comp));
7093
7034
  }
7094
7035
  return this.wNAF(W, comp, n);
7095
7036
  },
7037
+ // We calculate precomputes for elliptic curve point multiplication
7038
+ // using windowed method. This specifies window size and
7039
+ // stores precomputed values. Usually only base point would be precomputed.
7040
+ setWindowSize(P, W) {
7041
+ validateW(W);
7042
+ pointWindowSizes.set(P, W);
7043
+ pointPrecomputes.delete(P);
7044
+ },
7096
7045
  };
7097
7046
  }
7098
7047
  function validateBasic(curve) {
@@ -7118,7 +7067,7 @@ function validateBasic(curve) {
7118
7067
  // Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
7119
7068
  // Be friendly to bad ECMAScript parsers by not using bigint literals
7120
7069
  // prettier-ignore
7121
- const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n = BigInt(8);
7070
+ const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
7122
7071
  // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
7123
7072
  const VERIFY_DEFAULT = { zip215: true };
7124
7073
  function validateOpts$1(curve) {
@@ -7137,7 +7086,13 @@ function validateOpts$1(curve) {
7137
7086
  // Set defaults
7138
7087
  return Object.freeze({ ...opts });
7139
7088
  }
7140
- // It is not generic twisted curve for now, but ed25519/ed448 generic implementation
7089
+ /**
7090
+ * Creates Twisted Edwards curve with EdDSA signatures.
7091
+ * @example
7092
+ * import { Field } from '@noble/curves/abstract/modular';
7093
+ * // Before that, define BigInt-s: a, d, p, n, Gx, Gy, h
7094
+ * const curve = twistedEdwards({ a, d, Fp: Field(p), n, Gx, Gy, h })
7095
+ */
7141
7096
  function twistedEdwards(curveDef) {
7142
7097
  const CURVE = validateOpts$1(curveDef);
7143
7098
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
@@ -7156,28 +7111,59 @@ function twistedEdwards(curveDef) {
7156
7111
  const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
7157
7112
  const domain = CURVE.domain ||
7158
7113
  ((data, ctx, phflag) => {
7114
+ abool('phflag', phflag);
7159
7115
  if (ctx.length || phflag)
7160
7116
  throw new Error('Contexts/pre-hash are not supported');
7161
7117
  return data;
7162
7118
  }); // NOOP
7163
- const inBig = (n) => typeof n === 'bigint' && _0n$1 < n; // n in [1..]
7164
- const inRange = (n, max) => inBig(n) && inBig(max) && n < max; // n in [1..max-1]
7165
- const in0MaskRange = (n) => n === _0n$1 || inRange(n, MASK); // n in [0..MASK-1]
7166
- function assertInRange(n, max) {
7167
- // n in [1..max-1]
7168
- if (inRange(n, max))
7169
- return n;
7170
- throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
7171
- }
7172
- function assertGE0(n) {
7173
- // n in [0..CURVE_ORDER-1]
7174
- return n === _0n$1 ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
7175
- }
7176
- const pointPrecomputes = new Map();
7177
- function isPoint(other) {
7119
+ // 0 <= n < MASK
7120
+ // Coordinates larger than Fp.ORDER are allowed for zip215
7121
+ function aCoordinate(title, n) {
7122
+ aInRange('coordinate ' + title, n, _0n$1, MASK);
7123
+ }
7124
+ function assertPoint(other) {
7178
7125
  if (!(other instanceof Point))
7179
7126
  throw new Error('ExtendedPoint expected');
7180
7127
  }
7128
+ // Converts Extended point to default (x, y) coordinates.
7129
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
7130
+ const toAffineMemo = memoized((p, iz) => {
7131
+ const { ex: x, ey: y, ez: z } = p;
7132
+ const is0 = p.is0();
7133
+ if (iz == null)
7134
+ iz = is0 ? _8n$1 : Fp.inv(z); // 8 was chosen arbitrarily
7135
+ const ax = modP(x * iz);
7136
+ const ay = modP(y * iz);
7137
+ const zz = modP(z * iz);
7138
+ if (is0)
7139
+ return { x: _0n$1, y: _1n$3 };
7140
+ if (zz !== _1n$3)
7141
+ throw new Error('invZ was invalid');
7142
+ return { x: ax, y: ay };
7143
+ });
7144
+ const assertValidMemo = memoized((p) => {
7145
+ const { a, d } = CURVE;
7146
+ if (p.is0())
7147
+ throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
7148
+ // Equation in affine coordinates: ax² + y² = 1 + dx²y²
7149
+ // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
7150
+ const { ex: X, ey: Y, ez: Z, et: T } = p;
7151
+ const X2 = modP(X * X); // X²
7152
+ const Y2 = modP(Y * Y); // Y²
7153
+ const Z2 = modP(Z * Z); // Z²
7154
+ const Z4 = modP(Z2 * Z2); // Z⁴
7155
+ const aX2 = modP(X2 * a); // aX²
7156
+ const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
7157
+ const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
7158
+ if (left !== right)
7159
+ throw new Error('bad point: equation left != right (1)');
7160
+ // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
7161
+ const XY = modP(X * Y);
7162
+ const ZT = modP(Z * T);
7163
+ if (XY !== ZT)
7164
+ throw new Error('bad point: equation left != right (2)');
7165
+ return true;
7166
+ });
7181
7167
  // Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
7182
7168
  // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
7183
7169
  class Point {
@@ -7186,14 +7172,11 @@ function twistedEdwards(curveDef) {
7186
7172
  this.ey = ey;
7187
7173
  this.ez = ez;
7188
7174
  this.et = et;
7189
- if (!in0MaskRange(ex))
7190
- throw new Error('x required');
7191
- if (!in0MaskRange(ey))
7192
- throw new Error('y required');
7193
- if (!in0MaskRange(ez))
7194
- throw new Error('z required');
7195
- if (!in0MaskRange(et))
7196
- throw new Error('t required');
7175
+ aCoordinate('x', ex);
7176
+ aCoordinate('y', ey);
7177
+ aCoordinate('z', ez);
7178
+ aCoordinate('t', et);
7179
+ Object.freeze(this);
7197
7180
  }
7198
7181
  get x() {
7199
7182
  return this.toAffine().x;
@@ -7205,8 +7188,8 @@ function twistedEdwards(curveDef) {
7205
7188
  if (p instanceof Point)
7206
7189
  throw new Error('extended point not allowed');
7207
7190
  const { x, y } = p || {};
7208
- if (!in0MaskRange(x) || !in0MaskRange(y))
7209
- throw new Error('invalid affine point');
7191
+ aCoordinate('x', x);
7192
+ aCoordinate('y', y);
7210
7193
  return new Point(x, y, _1n$3, modP(x * y));
7211
7194
  }
7212
7195
  static normalizeZ(points) {
@@ -7215,36 +7198,16 @@ function twistedEdwards(curveDef) {
7215
7198
  }
7216
7199
  // "Private method", don't use it directly
7217
7200
  _setWindowSize(windowSize) {
7218
- this._WINDOW_SIZE = windowSize;
7219
- pointPrecomputes.delete(this);
7201
+ wnaf.setWindowSize(this, windowSize);
7220
7202
  }
7221
7203
  // Not required for fromHex(), which always creates valid points.
7222
7204
  // Could be useful for fromAffine().
7223
7205
  assertValidity() {
7224
- const { a, d } = CURVE;
7225
- if (this.is0())
7226
- throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
7227
- // Equation in affine coordinates: ax² + y² = 1 + dx²y²
7228
- // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
7229
- const { ex: X, ey: Y, ez: Z, et: T } = this;
7230
- const X2 = modP(X * X); // X²
7231
- const Y2 = modP(Y * Y); // Y²
7232
- const Z2 = modP(Z * Z); // Z²
7233
- const Z4 = modP(Z2 * Z2); // Z⁴
7234
- const aX2 = modP(X2 * a); // aX²
7235
- const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
7236
- const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
7237
- if (left !== right)
7238
- throw new Error('bad point: equation left != right (1)');
7239
- // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
7240
- const XY = modP(X * Y);
7241
- const ZT = modP(Z * T);
7242
- if (XY !== ZT)
7243
- throw new Error('bad point: equation left != right (2)');
7206
+ assertValidMemo(this);
7244
7207
  }
7245
7208
  // Compare one point to another.
7246
7209
  equals(other) {
7247
- isPoint(other);
7210
+ assertPoint(other);
7248
7211
  const { ex: X1, ey: Y1, ez: Z1 } = this;
7249
7212
  const { ex: X2, ey: Y2, ez: Z2 } = other;
7250
7213
  const X1Z2 = modP(X1 * Z2);
@@ -7285,7 +7248,7 @@ function twistedEdwards(curveDef) {
7285
7248
  // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
7286
7249
  // Cost: 9M + 1*a + 1*d + 7add.
7287
7250
  add(other) {
7288
- isPoint(other);
7251
+ assertPoint(other);
7289
7252
  const { a, d } = CURVE;
7290
7253
  const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
7291
7254
  const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
@@ -7328,11 +7291,13 @@ function twistedEdwards(curveDef) {
7328
7291
  return this.add(other.negate());
7329
7292
  }
7330
7293
  wNAF(n) {
7331
- return wnaf.wNAFCached(this, pointPrecomputes, n, Point.normalizeZ);
7294
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
7332
7295
  }
7333
7296
  // Constant-time multiplication.
7334
7297
  multiply(scalar) {
7335
- const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
7298
+ const n = scalar;
7299
+ aInRange('scalar', n, _1n$3, CURVE_ORDER); // 1 <= scalar < L
7300
+ const { p, f } = this.wNAF(n);
7336
7301
  return Point.normalizeZ([p, f])[0];
7337
7302
  }
7338
7303
  // Non-constant-time multiplication. Uses double-and-add algorithm.
@@ -7340,7 +7305,8 @@ function twistedEdwards(curveDef) {
7340
7305
  // an exposed private key e.g. sig verification.
7341
7306
  // Does NOT allow scalars higher than CURVE.n.
7342
7307
  multiplyUnsafe(scalar) {
7343
- let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
7308
+ const n = scalar;
7309
+ aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
7344
7310
  if (n === _0n$1)
7345
7311
  return I;
7346
7312
  if (this.equals(I) || n === _1n$3)
@@ -7364,18 +7330,7 @@ function twistedEdwards(curveDef) {
7364
7330
  // Converts Extended point to default (x, y) coordinates.
7365
7331
  // Can accept precomputed Z^-1 - for example, from invertBatch.
7366
7332
  toAffine(iz) {
7367
- const { ex: x, ey: y, ez: z } = this;
7368
- const is0 = this.is0();
7369
- if (iz == null)
7370
- iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
7371
- const ax = modP(x * iz);
7372
- const ay = modP(y * iz);
7373
- const zz = modP(z * iz);
7374
- if (is0)
7375
- return { x: _0n$1, y: _1n$3 };
7376
- if (zz !== _1n$3)
7377
- throw new Error('invZ was invalid');
7378
- return { x: ax, y: ay };
7333
+ return toAffineMemo(this, iz);
7379
7334
  }
7380
7335
  clearCofactor() {
7381
7336
  const { h: cofactor } = CURVE;
@@ -7389,18 +7344,16 @@ function twistedEdwards(curveDef) {
7389
7344
  const { d, a } = CURVE;
7390
7345
  const len = Fp.BYTES;
7391
7346
  hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
7347
+ abool('zip215', zip215);
7392
7348
  const normed = hex.slice(); // copy again, we'll manipulate it
7393
7349
  const lastByte = hex[len - 1]; // select last byte
7394
7350
  normed[len - 1] = lastByte & ~0x80; // clear last bit
7395
7351
  const y = bytesToNumberLE(normed);
7396
- if (y === _0n$1) ;
7397
- else {
7398
- // RFC8032 prohibits >= p, but ZIP215 doesn't
7399
- if (zip215)
7400
- assertInRange(y, MASK); // zip215=true [1..P-1] (2^255-19-1 for ed25519)
7401
- else
7402
- assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
7403
- }
7352
+ // RFC8032 prohibits >= p, but ZIP215 doesn't
7353
+ // zip215=true: 0 <= y < MASK (2^256 for ed25519)
7354
+ // zip215=false: 0 <= y < P (2^255-19 for ed25519)
7355
+ const max = zip215 ? MASK : Fp.ORDER;
7356
+ aInRange('pointHex.y', y, _0n$1, max);
7404
7357
  // Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
7405
7358
  // ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
7406
7359
  const y2 = modP(y * y); // denominator is always non-0 mod p.
@@ -7475,7 +7428,7 @@ function twistedEdwards(curveDef) {
7475
7428
  const R = G.multiply(r).toRawBytes(); // R = rG
7476
7429
  const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
7477
7430
  const s = modN(r + k * scalar); // S = (r + k * s) mod L
7478
- assertGE0(s); // 0 <= s < l
7431
+ aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
7479
7432
  const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
7480
7433
  return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
7481
7434
  }
@@ -7485,6 +7438,8 @@ function twistedEdwards(curveDef) {
7485
7438
  const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
7486
7439
  sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
7487
7440
  msg = ensureBytes('message', msg);
7441
+ if (zip215 !== undefined)
7442
+ abool('zip215', zip215);
7488
7443
  if (prehash)
7489
7444
  msg = prehash(msg); // for ed25519ph, etc
7490
7445
  const s = bytesToNumberLE(sig.slice(len, 2 * len));
@@ -7542,12 +7497,14 @@ function twistedEdwards(curveDef) {
7542
7497
  */
7543
7498
  const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
7544
7499
  // √(-1) aka √(a) aka 2^((p-1)/4)
7545
- const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
7500
+ const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
7546
7501
  // prettier-ignore
7547
- BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2), _5n = BigInt(5);
7502
+ BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
7548
7503
  // prettier-ignore
7549
- const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
7504
+ const _5n = BigInt(5), _8n = BigInt(8);
7550
7505
  function ed25519_pow_2_252_3(x) {
7506
+ // prettier-ignore
7507
+ const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
7551
7508
  const P = ED25519_P;
7552
7509
  const x2 = (x * x) % P;
7553
7510
  const b2 = (x2 * x) % P; // x^3, 11
@@ -7596,8 +7553,8 @@ function uvRatio(u, v) {
7596
7553
  x = mod(-x, P);
7597
7554
  return { isValid: useRoot1 || useRoot2, value: x };
7598
7555
  }
7599
- const Fp$1 = Field(ED25519_P, undefined, true);
7600
- const ed25519Defaults = {
7556
+ const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
7557
+ const ed25519Defaults = /* @__PURE__ */ (() => ({
7601
7558
  // Param: a
7602
7559
  a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
7603
7560
  // d is equal to -121665/121666 over finite field.
@@ -7609,7 +7566,7 @@ const ed25519Defaults = {
7609
7566
  // 2n**252n + 27742317777372353535851937790883648493n;
7610
7567
  n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
7611
7568
  // Cofactor
7612
- h: BigInt(8),
7569
+ h: _8n,
7613
7570
  // Base point (x, y) aka generator point
7614
7571
  Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
7615
7572
  Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
@@ -7620,40 +7577,11 @@ const ed25519Defaults = {
7620
7577
  // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
7621
7578
  // Constant-time, u/√v
7622
7579
  uvRatio,
7623
- };
7624
- const ed25519 = /* @__PURE__ */ twistedEdwards(ed25519Defaults);
7625
- function ed25519_domain(data, ctx, phflag) {
7626
- if (ctx.length > 255)
7627
- throw new Error('Context is too big');
7628
- return concatBytes$2(utf8ToBytes$2('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
7629
- }
7630
- /* @__PURE__ */ twistedEdwards({
7631
- ...ed25519Defaults,
7632
- domain: ed25519_domain,
7633
- });
7634
- /* @__PURE__ */ twistedEdwards({
7635
- ...ed25519Defaults,
7636
- domain: ed25519_domain,
7637
- prehash: sha512,
7638
- });
7639
- // Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
7640
- // NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
7641
- // SageMath returns different root first and everything falls apart
7642
- const ELL2_C1 = (Fp$1.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
7643
- Fp$1.pow(_2n$1, ELL2_C1); // 2. c2 = 2^c1
7644
- Fp$1.sqrt(Fp$1.neg(Fp$1.ONE)); // 3. c3 = sqrt(-1)
7645
- (Fp$1.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
7646
- BigInt(486662);
7647
- FpSqrtEven(Fp$1, Fp$1.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
7648
- // √(ad - 1)
7649
- BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
7650
- // 1 / √(a-d)
7651
- BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
7652
- // 1-d²
7653
- BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
7654
- // (d-1)²
7655
- BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
7656
- BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
7580
+ }))();
7581
+ /**
7582
+ * ed25519 curve with EdDSA signatures.
7583
+ */
7584
+ const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
7657
7585
 
7658
7586
  const PUBLIC_KEY_BYTE_LENGTH = 32;
7659
7587
  const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
@@ -7710,7 +7638,7 @@ function concatKeys(privateKeyRaw, publicKey) {
7710
7638
  var webcrypto = {
7711
7639
  get(win = globalThis) {
7712
7640
  const nativeCrypto = win.crypto;
7713
- if (nativeCrypto == null || nativeCrypto.subtle == null) {
7641
+ if (nativeCrypto?.subtle == null) {
7714
7642
  throw Object.assign(new Error('Missing Web Crypto API. ' +
7715
7643
  'The most likely cause of this error is that this page is being accessed ' +
7716
7644
  'from an insecure context (i.e. not HTTPS). For more information and ' +
@@ -7734,12 +7662,12 @@ var webcrypto = {
7734
7662
  const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
7735
7663
  // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
7736
7664
  function create(opts) {
7737
- const algorithm = opts?.algorithm ?? 'AES-GCM';
7738
- let keyLength = opts?.keyLength ?? 16;
7739
- const nonceLength = opts?.nonceLength ?? 12;
7740
- const digest = opts?.digest ?? 'SHA-256';
7741
- const saltLength = opts?.saltLength ?? 16;
7742
- const iterations = opts?.iterations ?? 32767;
7665
+ const algorithm = 'AES-GCM';
7666
+ let keyLength = 16;
7667
+ const nonceLength = 12;
7668
+ const digest = 'SHA-256';
7669
+ const saltLength = 16;
7670
+ const iterations = 32767;
7743
7671
  const crypto = webcrypto.get();
7744
7672
  keyLength *= 8; // Browser crypto uses bits instead of bytes
7745
7673
  /**
@@ -8523,7 +8451,7 @@ function decodeMessage(buf, codec, opts) {
8523
8451
  * A general purpose buffer pool
8524
8452
  */
8525
8453
  function pool(size) {
8526
- const SIZE = size ?? 8192;
8454
+ const SIZE = 8192;
8527
8455
  const MAX = SIZE >>> 1;
8528
8456
  let slab;
8529
8457
  let offset = SIZE;
@@ -9036,12 +8964,17 @@ function message(encode, decode) {
9036
8964
  * npm i protons-runtime
9037
8965
  * ```
9038
8966
  */
9039
- class CodeError extends Error {
9040
- code;
9041
- constructor(message, code, options) {
9042
- super(message, options);
9043
- this.code = code;
9044
- }
8967
+ /**
8968
+ * Thrown when a repeated field has too many elements
8969
+ */
8970
+ class MaxLengthError extends Error {
8971
+ /**
8972
+ * This will be removed in a future release
8973
+ *
8974
+ * @deprecated use the `.name` property instead
8975
+ */
8976
+ code = 'ERR_MAX_LENGTH';
8977
+ name = 'MaxLengthError';
9045
8978
  }
9046
8979
 
9047
8980
  /* eslint-disable import/export */
@@ -9252,7 +9185,7 @@ class Ed25519PrivateKey {
9252
9185
  return exporter(this.bytes, password);
9253
9186
  }
9254
9187
  else {
9255
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
9188
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
9256
9189
  }
9257
9190
  }
9258
9191
  }
@@ -9284,7 +9217,7 @@ async function generateKeyPairFromSeed(seed) {
9284
9217
  function ensureKey(key, length) {
9285
9218
  key = Uint8Array.from(key ?? []);
9286
9219
  if (key.length !== length) {
9287
- throw new CodeError$1(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
9220
+ throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
9288
9221
  }
9289
9222
  return key;
9290
9223
  }
@@ -9304,7 +9237,7 @@ var Ed25519 = /*#__PURE__*/Object.freeze({
9304
9237
  */
9305
9238
  function randomBytes(length) {
9306
9239
  if (isNaN(length) || length <= 0) {
9307
- throw new CodeError$1('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
9240
+ throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
9308
9241
  }
9309
9242
  return randomBytes$1(length);
9310
9243
  }
@@ -12713,7 +12646,7 @@ function pkcs1ToJwk(bytes) {
12713
12646
  */
12714
12647
  function jwkToPkcs1(jwk) {
12715
12648
  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) {
12716
- throw new CodeError$1('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12649
+ throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12717
12650
  }
12718
12651
  const root = new Sequence({
12719
12652
  value: [
@@ -12750,7 +12683,7 @@ function pkixToJwk(bytes) {
12750
12683
  */
12751
12684
  function jwkToPkix(jwk) {
12752
12685
  if (jwk.n == null || jwk.e == null) {
12753
- throw new CodeError$1('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12686
+ throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12754
12687
  }
12755
12688
  const root = new Sequence({
12756
12689
  value: [
@@ -12962,7 +12895,7 @@ async function hashAndVerify$1(key, sig, msg) {
12962
12895
  }
12963
12896
  async function exportKey(pair) {
12964
12897
  if (pair.privateKey == null || pair.publicKey == null) {
12965
- throw new CodeError$1('Private and public key are required', 'ERR_INVALID_PARAMETERS');
12898
+ throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
12966
12899
  }
12967
12900
  return Promise.all([
12968
12901
  webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
@@ -12981,10 +12914,10 @@ async function derivePublicFromPrivate(jwKey) {
12981
12914
  }
12982
12915
  function keySize(jwk) {
12983
12916
  if (jwk.kty !== 'RSA') {
12984
- throw new CodeError$1('invalid key type', 'ERR_INVALID_KEY_TYPE');
12917
+ throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
12985
12918
  }
12986
12919
  else if (jwk.n == null) {
12987
- throw new CodeError$1('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
12920
+ throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
12988
12921
  }
12989
12922
  const bytes = fromString(jwk.n, 'base64url');
12990
12923
  return bytes.length * 8;
@@ -13034,7 +12967,7 @@ class RsaPrivateKey {
13034
12967
  }
13035
12968
  get public() {
13036
12969
  if (this._publicKey == null) {
13037
- throw new CodeError$1('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
12970
+ throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
13038
12971
  }
13039
12972
  return new RsaPublicKey(this._publicKey);
13040
12973
  }
@@ -13083,14 +13016,14 @@ class RsaPrivateKey {
13083
13016
  return exporter(this.bytes, password);
13084
13017
  }
13085
13018
  else {
13086
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
13019
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
13087
13020
  }
13088
13021
  }
13089
13022
  }
13090
13023
  async function unmarshalRsaPrivateKey(bytes) {
13091
13024
  const jwk = pkcs1ToJwk(bytes);
13092
13025
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13093
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13026
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13094
13027
  }
13095
13028
  const keys = await unmarshalPrivateKey$1(jwk);
13096
13029
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
@@ -13098,20 +13031,20 @@ async function unmarshalRsaPrivateKey(bytes) {
13098
13031
  function unmarshalRsaPublicKey(bytes) {
13099
13032
  const jwk = pkixToJwk(bytes);
13100
13033
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13101
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13034
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13102
13035
  }
13103
13036
  return new RsaPublicKey(jwk);
13104
13037
  }
13105
13038
  async function fromJwk(jwk) {
13106
13039
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13107
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13040
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13108
13041
  }
13109
13042
  const keys = await unmarshalPrivateKey$1(jwk);
13110
13043
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
13111
13044
  }
13112
13045
  async function generateKeyPair$1(bits) {
13113
13046
  if (bits > MAX_RSA_KEY_SIZE) {
13114
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13047
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13115
13048
  }
13116
13049
  const keys = await generateKey$1(bits);
13117
13050
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
@@ -13130,6 +13063,12 @@ var RSA = /*#__PURE__*/Object.freeze({
13130
13063
 
13131
13064
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
13132
13065
  // Short Weierstrass curve. The formula is: y² = x³ + ax + b
13066
+ function validateSigVerOpts(opts) {
13067
+ if (opts.lowS !== undefined)
13068
+ abool('lowS', opts.lowS);
13069
+ if (opts.prehash !== undefined)
13070
+ abool('prehash', opts.prehash);
13071
+ }
13133
13072
  function validatePointOpts(curve) {
13134
13073
  const opts = validateBasic(curve);
13135
13074
  validateObject(opts, {
@@ -13254,16 +13193,12 @@ function weierstrassPoints(opts) {
13254
13193
  throw new Error('bad generator point: equation left != right');
13255
13194
  // Valid group elements reside in range 1..n-1
13256
13195
  function isWithinCurveOrder(num) {
13257
- return typeof num === 'bigint' && _0n < num && num < CURVE.n;
13258
- }
13259
- function assertGE(num) {
13260
- if (!isWithinCurveOrder(num))
13261
- throw new Error('Expected valid bigint: 0 < bigint < curve.n');
13196
+ return inRange(num, _1n$1, CURVE.n);
13262
13197
  }
13263
13198
  // Validates if priv key is valid and converts it to bigint.
13264
13199
  // Supports options allowedPrivateKeyLengths and wrapPrivateKey.
13265
13200
  function normPrivateKeyToScalar(key) {
13266
- const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
13201
+ const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
13267
13202
  if (lengths && typeof key !== 'bigint') {
13268
13203
  if (isBytes$1(key))
13269
13204
  key = bytesToHex(key);
@@ -13283,15 +13218,61 @@ function weierstrassPoints(opts) {
13283
13218
  throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
13284
13219
  }
13285
13220
  if (wrapPrivateKey)
13286
- num = mod(num, n); // disabled by default, enabled for BLS
13287
- assertGE(num); // num in range [1..N-1]
13221
+ num = mod(num, N); // disabled by default, enabled for BLS
13222
+ aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
13288
13223
  return num;
13289
13224
  }
13290
- const pointPrecomputes = new Map();
13291
13225
  function assertPrjPoint(other) {
13292
13226
  if (!(other instanceof Point))
13293
13227
  throw new Error('ProjectivePoint expected');
13294
13228
  }
13229
+ // Memoized toAffine / validity check. They are heavy. Points are immutable.
13230
+ // Converts Projective point to affine (x, y) coordinates.
13231
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
13232
+ // (x, y, z) ∋ (x=x/z, y=y/z)
13233
+ const toAffineMemo = memoized((p, iz) => {
13234
+ const { px: x, py: y, pz: z } = p;
13235
+ // Fast-path for normalized points
13236
+ if (Fp.eql(z, Fp.ONE))
13237
+ return { x, y };
13238
+ const is0 = p.is0();
13239
+ // If invZ was 0, we return zero point. However we still want to execute
13240
+ // all operations, so we replace invZ with a random number, 1.
13241
+ if (iz == null)
13242
+ iz = is0 ? Fp.ONE : Fp.inv(z);
13243
+ const ax = Fp.mul(x, iz);
13244
+ const ay = Fp.mul(y, iz);
13245
+ const zz = Fp.mul(z, iz);
13246
+ if (is0)
13247
+ return { x: Fp.ZERO, y: Fp.ZERO };
13248
+ if (!Fp.eql(zz, Fp.ONE))
13249
+ throw new Error('invZ was invalid');
13250
+ return { x: ax, y: ay };
13251
+ });
13252
+ // NOTE: on exception this will crash 'cached' and no value will be set.
13253
+ // Otherwise true will be return
13254
+ const assertValidMemo = memoized((p) => {
13255
+ if (p.is0()) {
13256
+ // (0, 1, 0) aka ZERO is invalid in most contexts.
13257
+ // In BLS, ZERO can be serialized, so we allow it.
13258
+ // (0, 0, 0) is wrong representation of ZERO and is always invalid.
13259
+ if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
13260
+ return;
13261
+ throw new Error('bad point: ZERO');
13262
+ }
13263
+ // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
13264
+ const { x, y } = p.toAffine();
13265
+ // Check if x, y are valid field elements
13266
+ if (!Fp.isValid(x) || !Fp.isValid(y))
13267
+ throw new Error('bad point: x or y not FE');
13268
+ const left = Fp.sqr(y); // y²
13269
+ const right = weierstrassEquation(x); // x³ + ax + b
13270
+ if (!Fp.eql(left, right))
13271
+ throw new Error('bad point: equation left != right');
13272
+ if (!p.isTorsionFree())
13273
+ throw new Error('bad point: not in prime-order subgroup');
13274
+ return true;
13275
+ });
13295
13276
  /**
13296
13277
  * Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
13297
13278
  * Default Point works in 2d / affine coordinates: (x, y)
@@ -13308,6 +13289,7 @@ function weierstrassPoints(opts) {
13308
13289
  throw new Error('y required');
13309
13290
  if (pz == null || !Fp.isValid(pz))
13310
13291
  throw new Error('z required');
13292
+ Object.freeze(this);
13311
13293
  }
13312
13294
  // Does not validate if the point is on-curve.
13313
13295
  // Use fromHex instead, or call assertValidity() later.
@@ -13354,30 +13336,11 @@ function weierstrassPoints(opts) {
13354
13336
  }
13355
13337
  // "Private method", don't use it directly
13356
13338
  _setWindowSize(windowSize) {
13357
- this._WINDOW_SIZE = windowSize;
13358
- pointPrecomputes.delete(this);
13339
+ wnaf.setWindowSize(this, windowSize);
13359
13340
  }
13360
13341
  // A point on curve is valid if it conforms to equation.
13361
13342
  assertValidity() {
13362
- if (this.is0()) {
13363
- // (0, 1, 0) aka ZERO is invalid in most contexts.
13364
- // In BLS, ZERO can be serialized, so we allow it.
13365
- // (0, 0, 0) is wrong representation of ZERO and is always invalid.
13366
- if (CURVE.allowInfinityPoint && !Fp.is0(this.py))
13367
- return;
13368
- throw new Error('bad point: ZERO');
13369
- }
13370
- // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
13371
- const { x, y } = this.toAffine();
13372
- // Check if x, y are valid field elements
13373
- if (!Fp.isValid(x) || !Fp.isValid(y))
13374
- throw new Error('bad point: x or y not FE');
13375
- const left = Fp.sqr(y); // y²
13376
- const right = weierstrassEquation(x); // x³ + ax + b
13377
- if (!Fp.eql(left, right))
13378
- throw new Error('bad point: equation left != right');
13379
- if (!this.isTorsionFree())
13380
- throw new Error('bad point: not in prime-order subgroup');
13343
+ assertValidMemo(this);
13381
13344
  }
13382
13345
  hasEvenY() {
13383
13346
  const { y } = this.toAffine();
@@ -13504,28 +13467,25 @@ function weierstrassPoints(opts) {
13504
13467
  return this.equals(Point.ZERO);
13505
13468
  }
13506
13469
  wNAF(n) {
13507
- return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => {
13508
- const toInv = Fp.invertBatch(comp.map((p) => p.pz));
13509
- return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
13510
- });
13470
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
13511
13471
  }
13512
13472
  /**
13513
13473
  * Non-constant-time multiplication. Uses double-and-add algorithm.
13514
13474
  * It's faster, but should only be used when you don't care about
13515
13475
  * an exposed private key e.g. sig verification, which works over *public* keys.
13516
13476
  */
13517
- multiplyUnsafe(n) {
13477
+ multiplyUnsafe(sc) {
13478
+ aInRange('scalar', sc, _0n, CURVE.n);
13518
13479
  const I = Point.ZERO;
13519
- if (n === _0n)
13480
+ if (sc === _0n)
13520
13481
  return I;
13521
- assertGE(n); // Will throw on 0
13522
- if (n === _1n$1)
13482
+ if (sc === _1n$1)
13523
13483
  return this;
13524
13484
  const { endo } = CURVE;
13525
13485
  if (!endo)
13526
- return wnaf.unsafeLadder(this, n);
13486
+ return wnaf.unsafeLadder(this, sc);
13527
13487
  // Apply endomorphism
13528
- let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
13488
+ let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
13529
13489
  let k1p = I;
13530
13490
  let k2p = I;
13531
13491
  let d = this;
@@ -13555,12 +13515,11 @@ function weierstrassPoints(opts) {
13555
13515
  * @returns New point
13556
13516
  */
13557
13517
  multiply(scalar) {
13558
- assertGE(scalar);
13559
- let n = scalar;
13518
+ const { endo, n: N } = CURVE;
13519
+ aInRange('scalar', scalar, _1n$1, N);
13560
13520
  let point, fake; // Fake point is used to const-time mult
13561
- const { endo } = CURVE;
13562
13521
  if (endo) {
13563
- const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
13522
+ const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
13564
13523
  let { p: k1p, f: f1p } = this.wNAF(k1);
13565
13524
  let { p: k2p, f: f2p } = this.wNAF(k2);
13566
13525
  k1p = wnaf.constTimeNegate(k1neg, k1p);
@@ -13570,7 +13529,7 @@ function weierstrassPoints(opts) {
13570
13529
  fake = f1p.add(f2p);
13571
13530
  }
13572
13531
  else {
13573
- const { p, f } = this.wNAF(n);
13532
+ const { p, f } = this.wNAF(scalar);
13574
13533
  point = p;
13575
13534
  fake = f;
13576
13535
  }
@@ -13594,20 +13553,7 @@ function weierstrassPoints(opts) {
13594
13553
  // Can accept precomputed Z^-1 - for example, from invertBatch.
13595
13554
  // (x, y, z) ∋ (x=x/z, y=y/z)
13596
13555
  toAffine(iz) {
13597
- const { px: x, py: y, pz: z } = this;
13598
- const is0 = this.is0();
13599
- // If invZ was 0, we return zero point. However we still want to execute
13600
- // all operations, so we replace invZ with a random number, 1.
13601
- if (iz == null)
13602
- iz = is0 ? Fp.ONE : Fp.inv(z);
13603
- const ax = Fp.mul(x, iz);
13604
- const ay = Fp.mul(y, iz);
13605
- const zz = Fp.mul(z, iz);
13606
- if (is0)
13607
- return { x: Fp.ZERO, y: Fp.ZERO };
13608
- if (!Fp.eql(zz, Fp.ONE))
13609
- throw new Error('invZ was invalid');
13610
- return { x: ax, y: ay };
13556
+ return toAffineMemo(this, iz);
13611
13557
  }
13612
13558
  isTorsionFree() {
13613
13559
  const { h: cofactor, isTorsionFree } = CURVE;
@@ -13626,10 +13572,12 @@ function weierstrassPoints(opts) {
13626
13572
  return this.multiplyUnsafe(CURVE.h);
13627
13573
  }
13628
13574
  toRawBytes(isCompressed = true) {
13575
+ abool('isCompressed', isCompressed);
13629
13576
  this.assertValidity();
13630
13577
  return toBytes(Point, this, isCompressed);
13631
13578
  }
13632
13579
  toHex(isCompressed = true) {
13580
+ abool('isCompressed', isCompressed);
13633
13581
  return bytesToHex(this.toRawBytes(isCompressed));
13634
13582
  }
13635
13583
  }
@@ -13659,14 +13607,18 @@ function validateOpts(curve) {
13659
13607
  });
13660
13608
  return Object.freeze({ lowS: true, ...opts });
13661
13609
  }
13610
+ /**
13611
+ * Creates short weierstrass curve and ECDSA signature methods for it.
13612
+ * @example
13613
+ * import { Field } from '@noble/curves/abstract/modular';
13614
+ * // Before that, define BigInt-s: a, b, p, n, Gx, Gy
13615
+ * const curve = weierstrass({ a, b, Fp: Field(p), n, Gx, Gy, h: 1n })
13616
+ */
13662
13617
  function weierstrass(curveDef) {
13663
13618
  const CURVE = validateOpts(curveDef);
13664
13619
  const { Fp, n: CURVE_ORDER } = CURVE;
13665
13620
  const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
13666
13621
  const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
13667
- function isValidFieldElement(num) {
13668
- return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE
13669
- }
13670
13622
  function modN(a) {
13671
13623
  return mod(a, CURVE_ORDER);
13672
13624
  }
@@ -13679,6 +13631,7 @@ function weierstrass(curveDef) {
13679
13631
  const a = point.toAffine();
13680
13632
  const x = Fp.toBytes(a.x);
13681
13633
  const cat = concatBytes;
13634
+ abool('isCompressed', isCompressed);
13682
13635
  if (isCompressed) {
13683
13636
  return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
13684
13637
  }
@@ -13693,7 +13646,7 @@ function weierstrass(curveDef) {
13693
13646
  // this.assertValidity() is done inside of fromHex
13694
13647
  if (len === compressedLen && (head === 0x02 || head === 0x03)) {
13695
13648
  const x = bytesToNumberBE(tail);
13696
- if (!isValidFieldElement(x))
13649
+ if (!inRange(x, _1n$1, Fp.ORDER))
13697
13650
  throw new Error('Point is not on curve');
13698
13651
  const y2 = weierstrassEquation(x); // y² = x³ + ax + b
13699
13652
  let y;
@@ -13754,11 +13707,8 @@ function weierstrass(curveDef) {
13754
13707
  return new Signature(r, s);
13755
13708
  }
13756
13709
  assertValidity() {
13757
- // can use assertGE here
13758
- if (!isWithinCurveOrder(this.r))
13759
- throw new Error('r must be 0 < r < CURVE.n');
13760
- if (!isWithinCurveOrder(this.s))
13761
- throw new Error('s must be 0 < s < CURVE.n');
13710
+ aInRange('r', this.r, _1n$1, CURVE_ORDER); // r in [1..N]
13711
+ aInRange('s', this.s, _1n$1, CURVE_ORDER); // s in [1..N]
13762
13712
  }
13763
13713
  addRecoveryBit(recovery) {
13764
13714
  return new Signature(this.r, this.s, recovery);
@@ -13901,10 +13851,7 @@ function weierstrass(curveDef) {
13901
13851
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
13902
13852
  */
13903
13853
  function int2octets(num) {
13904
- if (typeof num !== 'bigint')
13905
- throw new Error('bigint expected');
13906
- if (!(_0n <= num && num < ORDER_MASK))
13907
- throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
13854
+ aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
13908
13855
  // works with order, can have different size than numToField!
13909
13856
  return numberToBytesBE(num, CURVE.nByteLength);
13910
13857
  }
@@ -13921,6 +13868,7 @@ function weierstrass(curveDef) {
13921
13868
  if (lowS == null)
13922
13869
  lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
13923
13870
  msgHash = ensureBytes('msgHash', msgHash);
13871
+ validateSigVerOpts(opts);
13924
13872
  if (prehash)
13925
13873
  msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
13926
13874
  // We can't later call bits2octets, since nested bits2int is broken for curves
@@ -14007,6 +13955,7 @@ function weierstrass(curveDef) {
14007
13955
  publicKey = ensureBytes('publicKey', publicKey);
14008
13956
  if ('strict' in opts)
14009
13957
  throw new Error('options.strict was renamed to lowS');
13958
+ validateSigVerOpts(opts);
14010
13959
  const { lowS, prehash } = opts;
14011
13960
  let _sig = undefined;
14012
13961
  let P;
@@ -14113,6 +14062,9 @@ function sqrtMod(y) {
14113
14062
  return root;
14114
14063
  }
14115
14064
  const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
14065
+ /**
14066
+ * secp256k1 short weierstrass curve and ECDSA signatures over it.
14067
+ */
14116
14068
  const secp256k1 = createCurve({
14117
14069
  a: BigInt(0), // equation params: a, b
14118
14070
  b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
@@ -14171,14 +14123,14 @@ function hashAndSign(key, msg) {
14171
14123
  if (isPromise$1(p)) {
14172
14124
  return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
14173
14125
  .catch(err => {
14174
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14126
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14175
14127
  });
14176
14128
  }
14177
14129
  try {
14178
14130
  return secp256k1.sign(p.digest, key).toDERRawBytes();
14179
14131
  }
14180
14132
  catch (err) {
14181
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14133
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14182
14134
  }
14183
14135
  }
14184
14136
  /**
@@ -14189,14 +14141,14 @@ function hashAndVerify(key, sig, msg) {
14189
14141
  if (isPromise$1(p)) {
14190
14142
  return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
14191
14143
  .catch(err => {
14192
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14144
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14193
14145
  });
14194
14146
  }
14195
14147
  try {
14196
14148
  return secp256k1.verify(sig, p.digest, key);
14197
14149
  }
14198
14150
  catch (err) {
14199
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14151
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14200
14152
  }
14201
14153
  }
14202
14154
  function compressPublicKey(key) {
@@ -14208,7 +14160,7 @@ function validatePrivateKey(key) {
14208
14160
  secp256k1.getPublicKey(key, true);
14209
14161
  }
14210
14162
  catch (err) {
14211
- throw new CodeError$1(String(err), 'ERR_INVALID_PRIVATE_KEY');
14163
+ throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
14212
14164
  }
14213
14165
  }
14214
14166
  function validatePublicKey(key) {
@@ -14216,7 +14168,7 @@ function validatePublicKey(key) {
14216
14168
  secp256k1.ProjectivePoint.fromHex(key);
14217
14169
  }
14218
14170
  catch (err) {
14219
- throw new CodeError$1(String(err), 'ERR_INVALID_PUBLIC_KEY');
14171
+ throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
14220
14172
  }
14221
14173
  }
14222
14174
  function computePublicKey(privateKey) {
@@ -14224,7 +14176,7 @@ function computePublicKey(privateKey) {
14224
14176
  return secp256k1.getPublicKey(privateKey, true);
14225
14177
  }
14226
14178
  catch (err) {
14227
- throw new CodeError$1(String(err), 'ERR_INVALID_PRIVATE_KEY');
14179
+ throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
14228
14180
  }
14229
14181
  }
14230
14182
 
@@ -14314,7 +14266,7 @@ class Secp256k1PrivateKey {
14314
14266
  return exporter(this.bytes, password);
14315
14267
  }
14316
14268
  else {
14317
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
14269
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
14318
14270
  }
14319
14271
  }
14320
14272
  }
@@ -14356,7 +14308,7 @@ const supportedKeys = {
14356
14308
  };
14357
14309
  function unsupportedKey(type) {
14358
14310
  const supported = Object.keys(supportedKeys).join(' / ');
14359
- return new CodeError$1(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
14311
+ return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
14360
14312
  }
14361
14313
  function typeToKey(type) {
14362
14314
  type = type.toLowerCase();
@@ -14541,6 +14493,41 @@ class Secp256k1PeerIdImpl extends PeerIdImpl {
14541
14493
  this.publicKey = init.multihash.digest;
14542
14494
  }
14543
14495
  }
14496
+ // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
14497
+ const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
14498
+ class URLPeerIdImpl {
14499
+ type = 'url';
14500
+ multihash;
14501
+ privateKey;
14502
+ publicKey;
14503
+ url;
14504
+ constructor(url) {
14505
+ this.url = url.toString();
14506
+ this.multihash = identity.digest(fromString(this.url));
14507
+ }
14508
+ [inspect]() {
14509
+ return `PeerId(${this.url})`;
14510
+ }
14511
+ [peerIdSymbol] = true;
14512
+ toString() {
14513
+ return this.toCID().toString();
14514
+ }
14515
+ toCID() {
14516
+ return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
14517
+ }
14518
+ toBytes() {
14519
+ return this.toCID().bytes;
14520
+ }
14521
+ equals(other) {
14522
+ if (other == null) {
14523
+ return false;
14524
+ }
14525
+ if (other instanceof Uint8Array) {
14526
+ other = toString$6(other);
14527
+ }
14528
+ return other.toString() === this.toString();
14529
+ }
14530
+ }
14544
14531
  function peerIdFromString(str, decoder) {
14545
14532
  if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
14546
14533
  // identity hash ed25519/secp256k1 key or sha2-256 hash of
@@ -14579,9 +14566,13 @@ function peerIdFromBytes(buf) {
14579
14566
  throw new Error('Supplied PeerID CID is invalid');
14580
14567
  }
14581
14568
  function peerIdFromCID(cid) {
14582
- if (cid == null || cid.multihash == null || cid.version == null || (cid.version === 1 && cid.code !== LIBP2P_KEY_CODE)) {
14569
+ if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
14583
14570
  throw new Error('Supplied PeerID CID is invalid');
14584
14571
  }
14572
+ if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
14573
+ const url = toString$6(cid.multihash.digest);
14574
+ return new URLPeerIdImpl(new URL(url));
14575
+ }
14585
14576
  const multihash = cid.multihash;
14586
14577
  if (multihash.code === sha256.code) {
14587
14578
  return new RSAPeerIdImpl({ multihash: cid.multihash });
@@ -15427,9 +15418,6 @@ function isHexString(value, length) {
15427
15418
  if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
15428
15419
  return false;
15429
15420
  }
15430
- if (length && value.length !== 2 + 2 * length) {
15431
- return false;
15432
- }
15433
15421
  return true;
15434
15422
  }
15435
15423
  const HexCharacters = "0123456789abcdef";
@@ -17853,7 +17841,7 @@ if (!AbortError$1) {
17853
17841
  AbortError$1.prototype.name = 'AbortError';
17854
17842
  AbortError$1.prototype.code = 'ABORT_ERR';
17855
17843
 
17856
- const URL = (typeof globalThis !== 'undefined' && globalThis.URL) || require('url').URL;
17844
+ const URL$1 = (typeof globalThis !== 'undefined' && globalThis.URL) || require('url').URL;
17857
17845
 
17858
17846
  class HTTPStatusError extends Error {
17859
17847
  constructor (uri, code, method) {
@@ -18102,7 +18090,7 @@ class HTTPEndpoint extends BaseEndpoint {
18102
18090
  }
18103
18091
  const url = `${this.protocol}//${safeHost(this.host)}:${this.port}${this.path}`;
18104
18092
  try {
18105
- this.url = new URL(url);
18093
+ this.url = new URL$1(url);
18106
18094
  } catch (err) {
18107
18095
  throw new Error(err.message + ` [${url}]`)
18108
18096
  }
@@ -18184,7 +18172,7 @@ async function loadJSON (url, cache, timeout, abortSignal) {
18184
18172
 
18185
18173
  function requestRaw (url, method, data, timeout, abortSignal) {
18186
18174
  return new Promise((resolve, reject) => {
18187
- const target = new URL(url);
18175
+ const target = new URL$1(url);
18188
18176
  if (method === 'GET' && data) {
18189
18177
  target.search = '?dns=' + base64URL.decode(data);
18190
18178
  }
@@ -19563,7 +19551,7 @@ function queryDoh (endpoint, query, timeout, abortSignal) {
19563
19551
  )
19564
19552
  }
19565
19553
 
19566
- const UPDATE_URL = new URL('https://martinheidegger.github.io/dns-query/resolvers.json');
19554
+ const UPDATE_URL = new URL$1('https://martinheidegger.github.io/dns-query/resolvers.json');
19567
19555
 
19568
19556
  function isNameString (entry) {
19569
19557
  return /^@/.test(entry)
@@ -20918,16 +20906,14 @@ class BaseProtocol {
20918
20906
  components;
20919
20907
  log;
20920
20908
  pubsubTopics;
20921
- options;
20922
20909
  addLibp2pEventListener;
20923
20910
  removeLibp2pEventListener;
20924
20911
  streamManager;
20925
- constructor(multicodec, components, log, pubsubTopics, options) {
20912
+ constructor(multicodec, components, log, pubsubTopics) {
20926
20913
  this.multicodec = multicodec;
20927
20914
  this.components = components;
20928
20915
  this.log = log;
20929
20916
  this.pubsubTopics = pubsubTopics;
20930
- this.options = options;
20931
20917
  this.addLibp2pEventListener = components.events.addEventListener.bind(components.events);
20932
20918
  this.removeLibp2pEventListener = components.events.removeEventListener.bind(components.events);
20933
20919
  this.streamManager = new StreamManager(multicodec, components.connectionManager.getConnections.bind(components.connectionManager), this.addLibp2pEventListener);
@@ -20965,9 +20951,7 @@ class BaseProtocol {
20965
20951
  numPeers: 0
20966
20952
  }) {
20967
20953
  // Retrieve all connected peers that support the protocol & shard (if configured)
20968
- const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], this.options?.shardInfo
20969
- ? ensureShardingConfigured(this.options.shardInfo).shardInfo
20970
- : undefined);
20954
+ const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], pubsubTopicsToShardInfo(this.pubsubTopics));
20971
20955
  // Filter the peers based on discovery & number of peers requested
20972
20956
  const filteredPeers = filterPeersByDiscovery(connectedPeersForProtocolAndShard, numPeers, maxBootstrapPeers);
20973
20957
  // Sort the peers by latency
@@ -21657,74 +21641,35 @@ encode.single = (chunk, options) => {
21657
21641
  };
21658
21642
 
21659
21643
  /**
21660
- * @typedef {{ [key: string]: any }} Extensions
21661
- * @typedef {Error} Err
21662
- * @property {string} message
21644
+ * The reported length of the next data message was not a positive integer
21663
21645
  */
21664
-
21646
+ class InvalidMessageLengthError extends Error {
21647
+ name = 'InvalidMessageLengthError';
21648
+ code = 'ERR_INVALID_MSG_LENGTH';
21649
+ }
21665
21650
  /**
21666
- *
21667
- * @param {Error} obj
21668
- * @param {Extensions} props
21669
- * @returns {Error & Extensions}
21651
+ * The reported length of the next data message was larger than the configured
21652
+ * max allowable value
21670
21653
  */
21671
- function assign(obj, props) {
21672
- for (const key in props) {
21673
- Object.defineProperty(obj, key, {
21674
- value: props[key],
21675
- enumerable: true,
21676
- configurable: true,
21677
- });
21678
- }
21679
-
21680
- return obj;
21654
+ class InvalidDataLengthError extends Error {
21655
+ name = 'InvalidDataLengthError';
21656
+ code = 'ERR_MSG_DATA_TOO_LONG';
21681
21657
  }
21682
-
21683
21658
  /**
21684
- *
21685
- * @param {any} err - An Error
21686
- * @param {string|Extensions} code - A string code or props to set on the error
21687
- * @param {Extensions} [props] - Props to set on the error
21688
- * @returns {Error & Extensions}
21659
+ * The varint used to specify the length of the next data message contained more
21660
+ * bytes than the configured max allowable value
21689
21661
  */
21690
- function createError(err, code, props) {
21691
- if (!err || typeof err === 'string') {
21692
- throw new TypeError('Please pass an Error to err-code');
21693
- }
21694
-
21695
- if (!props) {
21696
- props = {};
21697
- }
21698
-
21699
- if (typeof code === 'object') {
21700
- props = code;
21701
- code = '';
21702
- }
21703
-
21704
- if (code) {
21705
- props.code = code;
21706
- }
21707
-
21708
- try {
21709
- return assign(err, props);
21710
- } catch (_) {
21711
- props.message = err.message;
21712
- props.stack = err.stack;
21713
-
21714
- const ErrClass = function () {};
21715
-
21716
- ErrClass.prototype = Object.create(Object.getPrototypeOf(err));
21717
-
21718
- // @ts-ignore
21719
- const output = assign(new ErrClass(), props);
21720
-
21721
- return output;
21722
- }
21662
+ class InvalidDataLengthLengthError extends Error {
21663
+ name = 'InvalidDataLengthLengthError';
21664
+ code = 'ERR_MSG_LENGTH_TOO_LONG';
21665
+ }
21666
+ /**
21667
+ * The incoming stream ended before the expected number of bytes were read
21668
+ */
21669
+ class UnexpectedEOFError extends Error {
21670
+ name = 'UnexpectedEOFError';
21671
+ code = 'ERR_UNEXPECTED_EOF';
21723
21672
  }
21724
-
21725
- var errCode = createError;
21726
-
21727
- var errCode$1 = /*@__PURE__*/getDefaultExportFromCjs(errCode);
21728
21673
 
21729
21674
  /* eslint max-depth: ["error", 6] */
21730
21675
  // Maximum length of the length section of the message
@@ -21756,10 +21701,10 @@ function decode(source, options) {
21756
21701
  try {
21757
21702
  dataLength = lengthDecoder(buffer);
21758
21703
  if (dataLength < 0) {
21759
- throw errCode$1(new Error('invalid message length'), 'ERR_INVALID_MSG_LENGTH');
21704
+ throw new InvalidMessageLengthError('Invalid message length');
21760
21705
  }
21761
21706
  if (dataLength > maxDataLength) {
21762
- throw errCode$1(new Error('message length too long'), 'ERR_MSG_DATA_TOO_LONG');
21707
+ throw new InvalidDataLengthError('Message length too long');
21763
21708
  }
21764
21709
  const dataLengthLength = lengthDecoder.bytes;
21765
21710
  buffer.consume(dataLengthLength);
@@ -21771,7 +21716,7 @@ function decode(source, options) {
21771
21716
  catch (err) {
21772
21717
  if (err instanceof RangeError) {
21773
21718
  if (buffer.byteLength > maxLengthLength) {
21774
- throw errCode$1(new Error('message length length too long'), 'ERR_MSG_LENGTH_TOO_LONG');
21719
+ throw new InvalidDataLengthLengthError('Message length length too long');
21775
21720
  }
21776
21721
  break;
21777
21722
  }
@@ -21800,7 +21745,7 @@ function decode(source, options) {
21800
21745
  yield* maybeYield();
21801
21746
  }
21802
21747
  if (buffer.byteLength > 0) {
21803
- throw errCode$1(new Error('unexpected end of input'), 'ERR_UNEXPECTED_EOF');
21748
+ throw new UnexpectedEOFError('Unexpected end of input');
21804
21749
  }
21805
21750
  })();
21806
21751
  }
@@ -21810,7 +21755,7 @@ function decode(source, options) {
21810
21755
  yield* maybeYield();
21811
21756
  }
21812
21757
  if (buffer.byteLength > 0) {
21813
- throw errCode$1(new Error('unexpected end of input'), 'ERR_UNEXPECTED_EOF');
21758
+ throw new UnexpectedEOFError('Unexpected end of input');
21814
21759
  }
21815
21760
  })();
21816
21761
  }
@@ -22645,7 +22590,7 @@ var FilterRequest;
22645
22590
  }
22646
22591
  case 3: {
22647
22592
  if (opts.limits?.contentFilters != null && obj.contentFilters.length === opts.limits.contentFilters) {
22648
- throw new CodeError('decode error - map field "contentFilters" had too many elements', 'ERR_MAX_LENGTH');
22593
+ throw new MaxLengthError('Decode error - map field "contentFilters" had too many elements');
22649
22594
  }
22650
22595
  obj.contentFilters.push(FilterRequest.ContentFilter.codec().decode(reader, reader.uint32(), {
22651
22596
  limits: opts.limits?.contentFilters$
@@ -22698,7 +22643,7 @@ var MessagePush$1;
22698
22643
  switch (tag >>> 3) {
22699
22644
  case 1: {
22700
22645
  if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
22701
- throw new CodeError('decode error - map field "messages" had too many elements', 'ERR_MAX_LENGTH');
22646
+ throw new MaxLengthError('Decode error - map field "messages" had too many elements');
22702
22647
  }
22703
22648
  obj.messages.push(WakuMessage$3.codec().decode(reader, reader.uint32(), {
22704
22649
  limits: opts.limits?.messages$
@@ -23117,7 +23062,7 @@ var FilterSubscribeRequest;
23117
23062
  }
23118
23063
  case 11: {
23119
23064
  if (opts.limits?.contentTopics != null && obj.contentTopics.length === opts.limits.contentTopics) {
23120
- throw new CodeError('decode error - map field "contentTopics" had too many elements', 'ERR_MAX_LENGTH');
23065
+ throw new MaxLengthError('Decode error - map field "contentTopics" had too many elements');
23121
23066
  }
23122
23067
  obj.contentTopics.push(reader.string());
23123
23068
  break;
@@ -23839,113 +23784,26 @@ var WakuMessage$1;
23839
23784
  /* eslint-disable @typescript-eslint/no-namespace */
23840
23785
  /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
23841
23786
  /* eslint-disable @typescript-eslint/no-empty-interface */
23842
- var Index;
23843
- (function (Index) {
23787
+ var WakuMessageKeyValue;
23788
+ (function (WakuMessageKeyValue) {
23844
23789
  let _codec;
23845
- Index.codec = () => {
23790
+ WakuMessageKeyValue.codec = () => {
23846
23791
  if (_codec == null) {
23847
23792
  _codec = message((obj, w, opts = {}) => {
23848
23793
  if (opts.lengthDelimited !== false) {
23849
23794
  w.fork();
23850
23795
  }
23851
- if ((obj.digest != null && obj.digest.byteLength > 0)) {
23796
+ if (obj.messageHash != null) {
23852
23797
  w.uint32(10);
23853
- w.bytes(obj.digest);
23798
+ w.bytes(obj.messageHash);
23854
23799
  }
23855
- if ((obj.receiverTime != null && obj.receiverTime !== 0n)) {
23856
- w.uint32(16);
23857
- w.sint64(obj.receiverTime);
23858
- }
23859
- if ((obj.senderTime != null && obj.senderTime !== 0n)) {
23860
- w.uint32(24);
23861
- w.sint64(obj.senderTime);
23862
- }
23863
- if ((obj.pubsubTopic != null && obj.pubsubTopic !== '')) {
23864
- w.uint32(34);
23865
- w.string(obj.pubsubTopic);
23866
- }
23867
- if (opts.lengthDelimited !== false) {
23868
- w.ldelim();
23869
- }
23870
- }, (reader, length, opts = {}) => {
23871
- const obj = {
23872
- digest: alloc$2(0),
23873
- receiverTime: 0n,
23874
- senderTime: 0n,
23875
- pubsubTopic: ''
23876
- };
23877
- const end = length == null ? reader.len : reader.pos + length;
23878
- while (reader.pos < end) {
23879
- const tag = reader.uint32();
23880
- switch (tag >>> 3) {
23881
- case 1: {
23882
- obj.digest = reader.bytes();
23883
- break;
23884
- }
23885
- case 2: {
23886
- obj.receiverTime = reader.sint64();
23887
- break;
23888
- }
23889
- case 3: {
23890
- obj.senderTime = reader.sint64();
23891
- break;
23892
- }
23893
- case 4: {
23894
- obj.pubsubTopic = reader.string();
23895
- break;
23896
- }
23897
- default: {
23898
- reader.skipType(tag & 7);
23899
- break;
23900
- }
23901
- }
23902
- }
23903
- return obj;
23904
- });
23905
- }
23906
- return _codec;
23907
- };
23908
- Index.encode = (obj) => {
23909
- return encodeMessage(obj, Index.codec());
23910
- };
23911
- Index.decode = (buf, opts) => {
23912
- return decodeMessage(buf, Index.codec(), opts);
23913
- };
23914
- })(Index || (Index = {}));
23915
- var PagingInfo;
23916
- (function (PagingInfo) {
23917
- (function (Direction) {
23918
- Direction["BACKWARD"] = "BACKWARD";
23919
- Direction["FORWARD"] = "FORWARD";
23920
- })(PagingInfo.Direction || (PagingInfo.Direction = {}));
23921
- let __DirectionValues;
23922
- (function (__DirectionValues) {
23923
- __DirectionValues[__DirectionValues["BACKWARD"] = 0] = "BACKWARD";
23924
- __DirectionValues[__DirectionValues["FORWARD"] = 1] = "FORWARD";
23925
- })(__DirectionValues || (__DirectionValues = {}));
23926
- (function (Direction) {
23927
- Direction.codec = () => {
23928
- return enumeration(__DirectionValues);
23929
- };
23930
- })(PagingInfo.Direction || (PagingInfo.Direction = {}));
23931
- let _codec;
23932
- PagingInfo.codec = () => {
23933
- if (_codec == null) {
23934
- _codec = message((obj, w, opts = {}) => {
23935
- if (opts.lengthDelimited !== false) {
23936
- w.fork();
23937
- }
23938
- if (obj.pageSize != null) {
23939
- w.uint32(8);
23940
- w.uint64(obj.pageSize);
23941
- }
23942
- if (obj.cursor != null) {
23800
+ if (obj.message != null) {
23943
23801
  w.uint32(18);
23944
- Index.codec().encode(obj.cursor, w);
23802
+ WakuMessage.codec().encode(obj.message, w);
23945
23803
  }
23946
- if (obj.direction != null) {
23947
- w.uint32(24);
23948
- PagingInfo.Direction.codec().encode(obj.direction, w);
23804
+ if (obj.pubsubTopic != null) {
23805
+ w.uint32(26);
23806
+ w.string(obj.pubsubTopic);
23949
23807
  }
23950
23808
  if (opts.lengthDelimited !== false) {
23951
23809
  w.ldelim();
@@ -23957,17 +23815,17 @@ var PagingInfo;
23957
23815
  const tag = reader.uint32();
23958
23816
  switch (tag >>> 3) {
23959
23817
  case 1: {
23960
- obj.pageSize = reader.uint64();
23818
+ obj.messageHash = reader.bytes();
23961
23819
  break;
23962
23820
  }
23963
23821
  case 2: {
23964
- obj.cursor = Index.codec().decode(reader, reader.uint32(), {
23965
- limits: opts.limits?.cursor
23822
+ obj.message = WakuMessage.codec().decode(reader, reader.uint32(), {
23823
+ limits: opts.limits?.message
23966
23824
  });
23967
23825
  break;
23968
23826
  }
23969
23827
  case 3: {
23970
- obj.direction = PagingInfo.Direction.codec().decode(reader);
23828
+ obj.pubsubTopic = reader.string();
23971
23829
  break;
23972
23830
  }
23973
23831
  default: {
@@ -23981,217 +23839,125 @@ var PagingInfo;
23981
23839
  }
23982
23840
  return _codec;
23983
23841
  };
23984
- PagingInfo.encode = (obj) => {
23985
- return encodeMessage(obj, PagingInfo.codec());
23842
+ WakuMessageKeyValue.encode = (obj) => {
23843
+ return encodeMessage(obj, WakuMessageKeyValue.codec());
23986
23844
  };
23987
- PagingInfo.decode = (buf, opts) => {
23988
- return decodeMessage(buf, PagingInfo.codec(), opts);
23845
+ WakuMessageKeyValue.decode = (buf, opts) => {
23846
+ return decodeMessage(buf, WakuMessageKeyValue.codec(), opts);
23989
23847
  };
23990
- })(PagingInfo || (PagingInfo = {}));
23991
- var ContentFilter;
23992
- (function (ContentFilter) {
23848
+ })(WakuMessageKeyValue || (WakuMessageKeyValue = {}));
23849
+ var StoreQueryRequest;
23850
+ (function (StoreQueryRequest) {
23993
23851
  let _codec;
23994
- ContentFilter.codec = () => {
23852
+ StoreQueryRequest.codec = () => {
23995
23853
  if (_codec == null) {
23996
23854
  _codec = message((obj, w, opts = {}) => {
23997
23855
  if (opts.lengthDelimited !== false) {
23998
23856
  w.fork();
23999
23857
  }
24000
- if ((obj.contentTopic != null && obj.contentTopic !== '')) {
23858
+ if ((obj.requestId != null && obj.requestId !== '')) {
24001
23859
  w.uint32(10);
24002
- w.string(obj.contentTopic);
23860
+ w.string(obj.requestId);
24003
23861
  }
24004
- if (opts.lengthDelimited !== false) {
24005
- w.ldelim();
23862
+ if ((obj.includeData != null && obj.includeData !== false)) {
23863
+ w.uint32(16);
23864
+ w.bool(obj.includeData);
24006
23865
  }
24007
- }, (reader, length, opts = {}) => {
24008
- const obj = {
24009
- contentTopic: ''
24010
- };
24011
- const end = length == null ? reader.len : reader.pos + length;
24012
- while (reader.pos < end) {
24013
- const tag = reader.uint32();
24014
- switch (tag >>> 3) {
24015
- case 1: {
24016
- obj.contentTopic = reader.string();
24017
- break;
24018
- }
24019
- default: {
24020
- reader.skipType(tag & 7);
24021
- break;
24022
- }
23866
+ if (obj.pubsubTopic != null) {
23867
+ w.uint32(82);
23868
+ w.string(obj.pubsubTopic);
23869
+ }
23870
+ if (obj.contentTopics != null) {
23871
+ for (const value of obj.contentTopics) {
23872
+ w.uint32(90);
23873
+ w.string(value);
24023
23874
  }
24024
23875
  }
24025
- return obj;
24026
- });
24027
- }
24028
- return _codec;
24029
- };
24030
- ContentFilter.encode = (obj) => {
24031
- return encodeMessage(obj, ContentFilter.codec());
24032
- };
24033
- ContentFilter.decode = (buf, opts) => {
24034
- return decodeMessage(buf, ContentFilter.codec(), opts);
24035
- };
24036
- })(ContentFilter || (ContentFilter = {}));
24037
- var HistoryQuery;
24038
- (function (HistoryQuery) {
24039
- let _codec;
24040
- HistoryQuery.codec = () => {
24041
- if (_codec == null) {
24042
- _codec = message((obj, w, opts = {}) => {
24043
- if (opts.lengthDelimited !== false) {
24044
- w.fork();
23876
+ if (obj.timeStart != null) {
23877
+ w.uint32(96);
23878
+ w.sint64(obj.timeStart);
24045
23879
  }
24046
- if (obj.pubsubTopic != null) {
24047
- w.uint32(18);
24048
- w.string(obj.pubsubTopic);
23880
+ if (obj.timeEnd != null) {
23881
+ w.uint32(104);
23882
+ w.sint64(obj.timeEnd);
24049
23883
  }
24050
- if (obj.contentFilters != null) {
24051
- for (const value of obj.contentFilters) {
24052
- w.uint32(26);
24053
- ContentFilter.codec().encode(value, w);
23884
+ if (obj.messageHashes != null) {
23885
+ for (const value of obj.messageHashes) {
23886
+ w.uint32(162);
23887
+ w.bytes(value);
24054
23888
  }
24055
23889
  }
24056
- if (obj.pagingInfo != null) {
24057
- w.uint32(34);
24058
- PagingInfo.codec().encode(obj.pagingInfo, w);
23890
+ if (obj.paginationCursor != null) {
23891
+ w.uint32(410);
23892
+ w.bytes(obj.paginationCursor);
24059
23893
  }
24060
- if (obj.startTime != null) {
24061
- w.uint32(40);
24062
- w.sint64(obj.startTime);
23894
+ if ((obj.paginationForward != null && obj.paginationForward !== false)) {
23895
+ w.uint32(416);
23896
+ w.bool(obj.paginationForward);
24063
23897
  }
24064
- if (obj.endTime != null) {
24065
- w.uint32(48);
24066
- w.sint64(obj.endTime);
23898
+ if (obj.paginationLimit != null) {
23899
+ w.uint32(424);
23900
+ w.uint64(obj.paginationLimit);
24067
23901
  }
24068
23902
  if (opts.lengthDelimited !== false) {
24069
23903
  w.ldelim();
24070
23904
  }
24071
23905
  }, (reader, length, opts = {}) => {
24072
23906
  const obj = {
24073
- contentFilters: []
23907
+ requestId: '',
23908
+ includeData: false,
23909
+ contentTopics: [],
23910
+ messageHashes: [],
23911
+ paginationForward: false
24074
23912
  };
24075
23913
  const end = length == null ? reader.len : reader.pos + length;
24076
23914
  while (reader.pos < end) {
24077
23915
  const tag = reader.uint32();
24078
23916
  switch (tag >>> 3) {
24079
- case 2: {
24080
- obj.pubsubTopic = reader.string();
23917
+ case 1: {
23918
+ obj.requestId = reader.string();
24081
23919
  break;
24082
23920
  }
24083
- case 3: {
24084
- if (opts.limits?.contentFilters != null && obj.contentFilters.length === opts.limits.contentFilters) {
24085
- throw new CodeError('decode error - map field "contentFilters" had too many elements', 'ERR_MAX_LENGTH');
24086
- }
24087
- obj.contentFilters.push(ContentFilter.codec().decode(reader, reader.uint32(), {
24088
- limits: opts.limits?.contentFilters$
24089
- }));
23921
+ case 2: {
23922
+ obj.includeData = reader.bool();
24090
23923
  break;
24091
23924
  }
24092
- case 4: {
24093
- obj.pagingInfo = PagingInfo.codec().decode(reader, reader.uint32(), {
24094
- limits: opts.limits?.pagingInfo
24095
- });
23925
+ case 10: {
23926
+ obj.pubsubTopic = reader.string();
24096
23927
  break;
24097
23928
  }
24098
- case 5: {
24099
- obj.startTime = reader.sint64();
23929
+ case 11: {
23930
+ if (opts.limits?.contentTopics != null && obj.contentTopics.length === opts.limits.contentTopics) {
23931
+ throw new MaxLengthError('Decode error - map field "contentTopics" had too many elements');
23932
+ }
23933
+ obj.contentTopics.push(reader.string());
24100
23934
  break;
24101
23935
  }
24102
- case 6: {
24103
- obj.endTime = reader.sint64();
23936
+ case 12: {
23937
+ obj.timeStart = reader.sint64();
24104
23938
  break;
24105
23939
  }
24106
- default: {
24107
- reader.skipType(tag & 7);
23940
+ case 13: {
23941
+ obj.timeEnd = reader.sint64();
24108
23942
  break;
24109
23943
  }
24110
- }
24111
- }
24112
- return obj;
24113
- });
24114
- }
24115
- return _codec;
24116
- };
24117
- HistoryQuery.encode = (obj) => {
24118
- return encodeMessage(obj, HistoryQuery.codec());
24119
- };
24120
- HistoryQuery.decode = (buf, opts) => {
24121
- return decodeMessage(buf, HistoryQuery.codec(), opts);
24122
- };
24123
- })(HistoryQuery || (HistoryQuery = {}));
24124
- var HistoryResponse;
24125
- (function (HistoryResponse) {
24126
- let HistoryError;
24127
- (function (HistoryError) {
24128
- HistoryError["NONE"] = "NONE";
24129
- HistoryError["INVALID_CURSOR"] = "INVALID_CURSOR";
24130
- HistoryError["TOO_MANY_REQUESTS"] = "TOO_MANY_REQUESTS";
24131
- HistoryError["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
24132
- })(HistoryError = HistoryResponse.HistoryError || (HistoryResponse.HistoryError = {}));
24133
- let __HistoryErrorValues;
24134
- (function (__HistoryErrorValues) {
24135
- __HistoryErrorValues[__HistoryErrorValues["NONE"] = 0] = "NONE";
24136
- __HistoryErrorValues[__HistoryErrorValues["INVALID_CURSOR"] = 1] = "INVALID_CURSOR";
24137
- __HistoryErrorValues[__HistoryErrorValues["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
24138
- __HistoryErrorValues[__HistoryErrorValues["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
24139
- })(__HistoryErrorValues || (__HistoryErrorValues = {}));
24140
- (function (HistoryError) {
24141
- HistoryError.codec = () => {
24142
- return enumeration(__HistoryErrorValues);
24143
- };
24144
- })(HistoryError = HistoryResponse.HistoryError || (HistoryResponse.HistoryError = {}));
24145
- let _codec;
24146
- HistoryResponse.codec = () => {
24147
- if (_codec == null) {
24148
- _codec = message((obj, w, opts = {}) => {
24149
- if (opts.lengthDelimited !== false) {
24150
- w.fork();
24151
- }
24152
- if (obj.messages != null) {
24153
- for (const value of obj.messages) {
24154
- w.uint32(18);
24155
- WakuMessage.codec().encode(value, w);
24156
- }
24157
- }
24158
- if (obj.pagingInfo != null) {
24159
- w.uint32(26);
24160
- PagingInfo.codec().encode(obj.pagingInfo, w);
24161
- }
24162
- if (obj.error != null && __HistoryErrorValues[obj.error] !== 0) {
24163
- w.uint32(32);
24164
- HistoryResponse.HistoryError.codec().encode(obj.error, w);
24165
- }
24166
- if (opts.lengthDelimited !== false) {
24167
- w.ldelim();
24168
- }
24169
- }, (reader, length, opts = {}) => {
24170
- const obj = {
24171
- messages: [],
24172
- error: HistoryError.NONE
24173
- };
24174
- const end = length == null ? reader.len : reader.pos + length;
24175
- while (reader.pos < end) {
24176
- const tag = reader.uint32();
24177
- switch (tag >>> 3) {
24178
- case 2: {
24179
- if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
24180
- throw new CodeError('decode error - map field "messages" had too many elements', 'ERR_MAX_LENGTH');
23944
+ case 20: {
23945
+ if (opts.limits?.messageHashes != null && obj.messageHashes.length === opts.limits.messageHashes) {
23946
+ throw new MaxLengthError('Decode error - map field "messageHashes" had too many elements');
24181
23947
  }
24182
- obj.messages.push(WakuMessage.codec().decode(reader, reader.uint32(), {
24183
- limits: opts.limits?.messages$
24184
- }));
23948
+ obj.messageHashes.push(reader.bytes());
24185
23949
  break;
24186
23950
  }
24187
- case 3: {
24188
- obj.pagingInfo = PagingInfo.codec().decode(reader, reader.uint32(), {
24189
- limits: opts.limits?.pagingInfo
24190
- });
23951
+ case 51: {
23952
+ obj.paginationCursor = reader.bytes();
24191
23953
  break;
24192
23954
  }
24193
- case 4: {
24194
- obj.error = HistoryResponse.HistoryError.codec().decode(reader);
23955
+ case 52: {
23956
+ obj.paginationForward = reader.bool();
23957
+ break;
23958
+ }
23959
+ case 53: {
23960
+ obj.paginationLimit = reader.uint64();
24195
23961
  break;
24196
23962
  }
24197
23963
  default: {
@@ -24205,17 +23971,17 @@ var HistoryResponse;
24205
23971
  }
24206
23972
  return _codec;
24207
23973
  };
24208
- HistoryResponse.encode = (obj) => {
24209
- return encodeMessage(obj, HistoryResponse.codec());
23974
+ StoreQueryRequest.encode = (obj) => {
23975
+ return encodeMessage(obj, StoreQueryRequest.codec());
24210
23976
  };
24211
- HistoryResponse.decode = (buf, opts) => {
24212
- return decodeMessage(buf, HistoryResponse.codec(), opts);
23977
+ StoreQueryRequest.decode = (buf, opts) => {
23978
+ return decodeMessage(buf, StoreQueryRequest.codec(), opts);
24213
23979
  };
24214
- })(HistoryResponse || (HistoryResponse = {}));
24215
- var HistoryRpc;
24216
- (function (HistoryRpc) {
23980
+ })(StoreQueryRequest || (StoreQueryRequest = {}));
23981
+ var StoreQueryResponse;
23982
+ (function (StoreQueryResponse) {
24217
23983
  let _codec;
24218
- HistoryRpc.codec = () => {
23984
+ StoreQueryResponse.codec = () => {
24219
23985
  if (_codec == null) {
24220
23986
  _codec = message((obj, w, opts = {}) => {
24221
23987
  if (opts.lengthDelimited !== false) {
@@ -24225,20 +23991,31 @@ var HistoryRpc;
24225
23991
  w.uint32(10);
24226
23992
  w.string(obj.requestId);
24227
23993
  }
24228
- if (obj.query != null) {
24229
- w.uint32(18);
24230
- HistoryQuery.codec().encode(obj.query, w);
23994
+ if (obj.statusCode != null) {
23995
+ w.uint32(80);
23996
+ w.uint32(obj.statusCode);
24231
23997
  }
24232
- if (obj.response != null) {
24233
- w.uint32(26);
24234
- HistoryResponse.codec().encode(obj.response, w);
23998
+ if (obj.statusDesc != null) {
23999
+ w.uint32(90);
24000
+ w.string(obj.statusDesc);
24001
+ }
24002
+ if (obj.messages != null) {
24003
+ for (const value of obj.messages) {
24004
+ w.uint32(162);
24005
+ WakuMessageKeyValue.codec().encode(value, w);
24006
+ }
24007
+ }
24008
+ if (obj.paginationCursor != null) {
24009
+ w.uint32(410);
24010
+ w.bytes(obj.paginationCursor);
24235
24011
  }
24236
24012
  if (opts.lengthDelimited !== false) {
24237
24013
  w.ldelim();
24238
24014
  }
24239
24015
  }, (reader, length, opts = {}) => {
24240
24016
  const obj = {
24241
- requestId: ''
24017
+ requestId: '',
24018
+ messages: []
24242
24019
  };
24243
24020
  const end = length == null ? reader.len : reader.pos + length;
24244
24021
  while (reader.pos < end) {
@@ -24248,16 +24025,25 @@ var HistoryRpc;
24248
24025
  obj.requestId = reader.string();
24249
24026
  break;
24250
24027
  }
24251
- case 2: {
24252
- obj.query = HistoryQuery.codec().decode(reader, reader.uint32(), {
24253
- limits: opts.limits?.query
24254
- });
24028
+ case 10: {
24029
+ obj.statusCode = reader.uint32();
24255
24030
  break;
24256
24031
  }
24257
- case 3: {
24258
- obj.response = HistoryResponse.codec().decode(reader, reader.uint32(), {
24259
- limits: opts.limits?.response
24260
- });
24032
+ case 11: {
24033
+ obj.statusDesc = reader.string();
24034
+ break;
24035
+ }
24036
+ case 20: {
24037
+ if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
24038
+ throw new MaxLengthError('Decode error - map field "messages" had too many elements');
24039
+ }
24040
+ obj.messages.push(WakuMessageKeyValue.codec().decode(reader, reader.uint32(), {
24041
+ limits: opts.limits?.messages$
24042
+ }));
24043
+ break;
24044
+ }
24045
+ case 51: {
24046
+ obj.paginationCursor = reader.bytes();
24261
24047
  break;
24262
24048
  }
24263
24049
  default: {
@@ -24271,13 +24057,13 @@ var HistoryRpc;
24271
24057
  }
24272
24058
  return _codec;
24273
24059
  };
24274
- HistoryRpc.encode = (obj) => {
24275
- return encodeMessage(obj, HistoryRpc.codec());
24060
+ StoreQueryResponse.encode = (obj) => {
24061
+ return encodeMessage(obj, StoreQueryResponse.codec());
24276
24062
  };
24277
- HistoryRpc.decode = (buf, opts) => {
24278
- return decodeMessage(buf, HistoryRpc.codec(), opts);
24063
+ StoreQueryResponse.decode = (buf, opts) => {
24064
+ return decodeMessage(buf, StoreQueryResponse.codec(), opts);
24279
24065
  };
24280
- })(HistoryRpc || (HistoryRpc = {}));
24066
+ })(StoreQueryResponse || (StoreQueryResponse = {}));
24281
24067
  var RateLimitProof;
24282
24068
  (function (RateLimitProof) {
24283
24069
  let _codec;
@@ -24597,7 +24383,7 @@ var PeerExchangeResponse;
24597
24383
  switch (tag >>> 3) {
24598
24384
  case 1: {
24599
24385
  if (opts.limits?.peerInfos != null && obj.peerInfos.length === opts.limits.peerInfos) {
24600
- throw new CodeError('decode error - map field "peerInfos" had too many elements', 'ERR_MAX_LENGTH');
24386
+ throw new MaxLengthError('Decode error - map field "peerInfos" had too many elements');
24601
24387
  }
24602
24388
  obj.peerInfos.push(PeerInfo.codec().decode(reader, reader.uint32(), {
24603
24389
  limits: opts.limits?.peerInfos$
@@ -24720,7 +24506,7 @@ var WakuMetadataRequest;
24720
24506
  }
24721
24507
  case 2: {
24722
24508
  if (opts.limits?.shards != null && obj.shards.length === opts.limits.shards) {
24723
- throw new CodeError('decode error - map field "shards" had too many elements', 'ERR_MAX_LENGTH');
24509
+ throw new MaxLengthError('Decode error - map field "shards" had too many elements');
24724
24510
  }
24725
24511
  obj.shards.push(reader.uint32());
24726
24512
  break;
@@ -24779,7 +24565,7 @@ var WakuMetadataResponse;
24779
24565
  }
24780
24566
  case 2: {
24781
24567
  if (opts.limits?.shards != null && obj.shards.length === opts.limits.shards) {
24782
- throw new CodeError('decode error - map field "shards" had too many elements', 'ERR_MAX_LENGTH');
24568
+ throw new MaxLengthError('Decode error - map field "shards" had too many elements');
24783
24569
  }
24784
24570
  obj.shards.push(reader.uint32());
24785
24571
  break;
@@ -24859,11 +24645,11 @@ class WakuPeerExchange extends BaseProtocol {
24859
24645
  * Make a peer exchange query to a peer
24860
24646
  */
24861
24647
  async query(params) {
24862
- const { numPeers } = params;
24648
+ const { numPeers, peerId } = params;
24863
24649
  const rpcQuery = PeerExchangeRPC.createRequest({
24864
24650
  numPeers: BigInt(numPeers)
24865
24651
  });
24866
- const peer = await this.peerStore.get(params.peerId);
24652
+ const peer = await this.peerStore.get(peerId);
24867
24653
  if (!peer) {
24868
24654
  return {
24869
24655
  peerInfos: null,
@@ -25019,7 +24805,31 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
25019
24805
  }
25020
24806
  const hasPeer = await this.components.peerStore.has(peerId);
25021
24807
  if (hasPeer) {
25022
- continue;
24808
+ const { hasMultiaddrDiff, hasShardDiff } = await this.checkPeerInfoDiff(peerInfo, shardInfo);
24809
+ if (hasMultiaddrDiff || hasShardDiff) {
24810
+ log$1.info(`Peer ${peerId.toString()} has updated multiaddrs or shardInfo, updating`);
24811
+ if (hasMultiaddrDiff) {
24812
+ log$1.info(`Peer ${peerId.toString()} has updated multiaddrs, updating`);
24813
+ await this.components.peerStore.patch(peerId, {
24814
+ multiaddrs: peerInfo.multiaddrs
24815
+ });
24816
+ }
24817
+ if (hasShardDiff && shardInfo) {
24818
+ log$1.info(`Peer ${peerId.toString()} has updated shardInfo, updating`);
24819
+ await this.components.peerStore.merge(peerId, {
24820
+ metadata: {
24821
+ shardInfo: encodeRelayShard(shardInfo)
24822
+ }
24823
+ });
24824
+ this.dispatchEvent(new CustomEvent("peer", {
24825
+ detail: {
24826
+ id: peerId,
24827
+ multiaddrs: peerInfo.multiaddrs
24828
+ }
24829
+ }));
24830
+ }
24831
+ continue;
24832
+ }
25023
24833
  }
25024
24834
  // update the tags for the peer
25025
24835
  await this.components.peerStore.save(peerId, {
@@ -25033,6 +24843,9 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
25033
24843
  metadata: {
25034
24844
  shardInfo: encodeRelayShard(shardInfo)
25035
24845
  }
24846
+ }),
24847
+ ...(peerInfo.multiaddrs && {
24848
+ multiaddrs: peerInfo.multiaddrs
25036
24849
  })
25037
24850
  });
25038
24851
  log$1.info(`Discovered peer: ${peerId.toString()}`);
@@ -25050,6 +24863,24 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
25050
24863
  this.queryingPeers.delete(peerIdStr);
25051
24864
  this.queryAttempts.delete(peerIdStr);
25052
24865
  }
24866
+ async checkPeerInfoDiff(peerInfo, shardInfo) {
24867
+ const { id: peerId } = peerInfo;
24868
+ const peer = await this.components.peerStore.get(peerId);
24869
+ const existingMultiaddrs = peer.addresses.map((a) => a.multiaddr.toString());
24870
+ const newMultiaddrs = peerInfo.multiaddrs.map((ma) => ma.toString());
24871
+ const hasMultiaddrDiff = existingMultiaddrs.some((ma) => !newMultiaddrs.includes(ma));
24872
+ let hasShardDiff = false;
24873
+ const existingShardInfoBytes = peer.metadata.get("shardInfo");
24874
+ if (existingShardInfoBytes) {
24875
+ const existingShardInfo = decodeRelayShard(existingShardInfoBytes);
24876
+ if (existingShardInfo || shardInfo) {
24877
+ hasShardDiff =
24878
+ existingShardInfo.clusterId !== shardInfo?.clusterId ||
24879
+ existingShardInfo.shards.some((shard) => !shardInfo?.shards.includes(shard));
24880
+ }
24881
+ }
24882
+ return { hasMultiaddrDiff, hasShardDiff };
24883
+ }
25053
24884
  }
25054
24885
  function wakuPeerExchangeDiscovery(pubsubTopics) {
25055
24886
  return (components) => new PeerExchangeDiscovery(components, pubsubTopics);
@@ -25095,7 +24926,13 @@ async function createFromParts(multihash, privKey, pubKey) {
25095
24926
  const key = unmarshalPublicKey(pubKey);
25096
24927
  return createFromPubKey(key);
25097
24928
  }
25098
- return peerIdFromBytes(multihash);
24929
+ const peerId = peerIdFromBytes(multihash);
24930
+ if (peerId.type !== 'Ed25519' && peerId.type !== 'secp256k1' && peerId.type !== 'RSA') {
24931
+ // should not be possible since `multihash` is derived from keys and these
24932
+ // are the cryptographic peer id types
24933
+ throw new Error('Supplied PeerID is invalid');
24934
+ }
24935
+ return peerId;
25099
24936
  }
25100
24937
 
25101
24938
  const log = new Logger$1("peer-exchange-discovery");