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