@waku/discovery 0.0.2-434be7b.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/bundle/index.js +27179 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/dns/constants.d.ts +9 -0
  4. package/dist/dns/constants.js +13 -0
  5. package/dist/dns/constants.js.map +1 -0
  6. package/dist/dns/dns.d.ts +32 -0
  7. package/dist/dns/dns.js +160 -0
  8. package/dist/dns/dns.js.map +1 -0
  9. package/dist/dns/dns_discovery.d.ts +24 -0
  10. package/dist/dns/dns_discovery.js +95 -0
  11. package/dist/dns/dns_discovery.js.map +1 -0
  12. package/dist/dns/dns_over_https.d.ts +25 -0
  13. package/dist/dns/dns_over_https.js +72 -0
  14. package/dist/dns/dns_over_https.js.map +1 -0
  15. package/dist/dns/enrtree.d.ts +33 -0
  16. package/dist/dns/enrtree.js +76 -0
  17. package/dist/dns/enrtree.js.map +1 -0
  18. package/dist/dns/fetch_nodes.d.ts +13 -0
  19. package/dist/dns/fetch_nodes.js +133 -0
  20. package/dist/dns/fetch_nodes.js.map +1 -0
  21. package/dist/dns/index.d.ts +3 -0
  22. package/dist/dns/index.js +4 -0
  23. package/dist/dns/index.js.map +1 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.js +10 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/local-peer-cache/index.d.ts +24 -0
  28. package/dist/local-peer-cache/index.js +106 -0
  29. package/dist/local-peer-cache/index.js.map +1 -0
  30. package/dist/peer-exchange/index.d.ts +2 -0
  31. package/dist/peer-exchange/index.js +3 -0
  32. package/dist/peer-exchange/index.js.map +1 -0
  33. package/dist/peer-exchange/rpc.d.ts +22 -0
  34. package/dist/peer-exchange/rpc.js +41 -0
  35. package/dist/peer-exchange/rpc.js.map +1 -0
  36. package/dist/peer-exchange/waku_peer_exchange.d.ts +21 -0
  37. package/dist/peer-exchange/waku_peer_exchange.js +80 -0
  38. package/dist/peer-exchange/waku_peer_exchange.js.map +1 -0
  39. package/dist/peer-exchange/waku_peer_exchange_discovery.d.ts +53 -0
  40. package/dist/peer-exchange/waku_peer_exchange_discovery.js +136 -0
  41. package/dist/peer-exchange/waku_peer_exchange_discovery.js.map +1 -0
  42. package/package.json +1 -0
  43. package/src/dns/constants.ts +16 -0
  44. package/src/dns/dns.ts +215 -0
  45. package/src/dns/dns_discovery.ts +144 -0
  46. package/src/dns/dns_over_https.ts +83 -0
  47. package/src/dns/enrtree.ts +123 -0
  48. package/src/dns/fetch_nodes.ts +181 -0
  49. package/src/dns/index.ts +3 -0
  50. package/src/index.ts +21 -0
  51. package/src/local-peer-cache/index.ts +160 -0
  52. package/src/peer-exchange/index.ts +11 -0
  53. package/src/peer-exchange/rpc.ts +44 -0
  54. package/src/peer-exchange/waku_peer_exchange.ts +111 -0
  55. package/src/peer-exchange/waku_peer_exchange_discovery.ts +238 -0
@@ -0,0 +1,33 @@
1
+ export type ENRRootValues = {
2
+ eRoot: string;
3
+ lRoot: string;
4
+ seq: number;
5
+ signature: string;
6
+ };
7
+ export type ENRTreeValues = {
8
+ publicKey: string;
9
+ domain: string;
10
+ };
11
+ export declare class ENRTree {
12
+ static readonly RECORD_PREFIX = "enr:";
13
+ static readonly TREE_PREFIX = "enrtree:";
14
+ static readonly BRANCH_PREFIX = "enrtree-branch:";
15
+ static readonly ROOT_PREFIX = "enrtree-root:";
16
+ /**
17
+ * Extracts the branch subdomain referenced by a DNS tree root string after verifying
18
+ * the root record signature with its base32 compressed public key.
19
+ */
20
+ static parseAndVerifyRoot(root: string, publicKey: string): string;
21
+ static parseRootValues(txt: string): ENRRootValues;
22
+ /**
23
+ * Returns the public key and top level domain of an ENR tree entry.
24
+ * The domain is the starting point for traversing a set of linked DNS TXT records
25
+ * and the public key is used to verify the root entry record
26
+ */
27
+ static parseTree(tree: string): ENRTreeValues;
28
+ /**
29
+ * Returns subdomains listed in an ENR branch entry. These in turn lead to
30
+ * either further branch entries or ENR records.
31
+ */
32
+ static parseBranch(branch: string): string[];
33
+ }
@@ -0,0 +1,76 @@
1
+ import { ENR } from "@waku/enr";
2
+ import { keccak256, verifySignature } from "@waku/enr";
3
+ import { utf8ToBytes } from "@waku/utils/bytes";
4
+ import base32 from "hi-base32";
5
+ import { fromString } from "uint8arrays/from-string";
6
+ export class ENRTree {
7
+ static RECORD_PREFIX = ENR.RECORD_PREFIX;
8
+ static TREE_PREFIX = "enrtree:";
9
+ static BRANCH_PREFIX = "enrtree-branch:";
10
+ static ROOT_PREFIX = "enrtree-root:";
11
+ /**
12
+ * Extracts the branch subdomain referenced by a DNS tree root string after verifying
13
+ * the root record signature with its base32 compressed public key.
14
+ */
15
+ static parseAndVerifyRoot(root, publicKey) {
16
+ if (!root.startsWith(this.ROOT_PREFIX))
17
+ throw new Error(`ENRTree root entry must start with '${this.ROOT_PREFIX}'`);
18
+ const rootValues = ENRTree.parseRootValues(root);
19
+ const decodedPublicKey = base32.decode.asBytes(publicKey);
20
+ // The signature is a 65-byte secp256k1 over the keccak256 hash
21
+ // of the record content, excluding the `sig=` part, encoded as URL-safe base64 string
22
+ // (Trailing recovery bit must be trimmed to pass `ecdsaVerify` method)
23
+ const signedComponent = root.split(" sig")[0];
24
+ const signedComponentBuffer = utf8ToBytes(signedComponent);
25
+ const signatureBuffer = fromString(rootValues.signature, "base64url").slice(0, 64);
26
+ const isVerified = verifySignature(signatureBuffer, keccak256(signedComponentBuffer), new Uint8Array(decodedPublicKey));
27
+ if (!isVerified)
28
+ throw new Error("Unable to verify ENRTree root signature");
29
+ return rootValues.eRoot;
30
+ }
31
+ static parseRootValues(txt) {
32
+ const matches = txt.match(/^enrtree-root:v1 e=([^ ]+) l=([^ ]+) seq=(\d+) sig=([^ ]+)$/);
33
+ if (!Array.isArray(matches))
34
+ throw new Error("Could not parse ENRTree root entry");
35
+ matches.shift(); // The first entry is the full match
36
+ const [eRoot, lRoot, seq, signature] = matches;
37
+ if (!eRoot)
38
+ throw new Error("Could not parse 'e' value from ENRTree root entry");
39
+ if (!lRoot)
40
+ throw new Error("Could not parse 'l' value from ENRTree root entry");
41
+ if (!seq)
42
+ throw new Error("Could not parse 'seq' value from ENRTree root entry");
43
+ if (!signature)
44
+ throw new Error("Could not parse 'sig' value from ENRTree root entry");
45
+ return { eRoot, lRoot, seq: Number(seq), signature };
46
+ }
47
+ /**
48
+ * Returns the public key and top level domain of an ENR tree entry.
49
+ * The domain is the starting point for traversing a set of linked DNS TXT records
50
+ * and the public key is used to verify the root entry record
51
+ */
52
+ static parseTree(tree) {
53
+ if (!tree.startsWith(this.TREE_PREFIX))
54
+ throw new Error(`ENRTree tree entry must start with '${this.TREE_PREFIX}'`);
55
+ const matches = tree.match(/^enrtree:\/\/([^@]+)@(.+)$/);
56
+ if (!Array.isArray(matches))
57
+ throw new Error("Could not parse ENRTree tree entry");
58
+ matches.shift(); // The first entry is the full match
59
+ const [publicKey, domain] = matches;
60
+ if (!publicKey)
61
+ throw new Error("Could not parse public key from ENRTree tree entry");
62
+ if (!domain)
63
+ throw new Error("Could not parse domain from ENRTree tree entry");
64
+ return { publicKey, domain };
65
+ }
66
+ /**
67
+ * Returns subdomains listed in an ENR branch entry. These in turn lead to
68
+ * either further branch entries or ENR records.
69
+ */
70
+ static parseBranch(branch) {
71
+ if (!branch.startsWith(this.BRANCH_PREFIX))
72
+ throw new Error(`ENRTree branch entry must start with '${this.BRANCH_PREFIX}'`);
73
+ return branch.split(this.BRANCH_PREFIX)[1].split(",");
74
+ }
75
+ }
76
+ //# sourceMappingURL=enrtree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enrtree.js","sourceRoot":"","sources":["../../src/dns/enrtree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { IEnr, NodeCapabilityCount } from "@waku/interfaces";
2
+ /**
3
+ * Fetch nodes using passed [[getNode]] until all wanted capabilities are
4
+ * fulfilled or the number of [[getNode]] call exceeds the sum of
5
+ * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
6
+ */
7
+ export declare function fetchNodesUntilCapabilitiesFulfilled(wantedNodeCapabilityCount: Partial<NodeCapabilityCount>, errorTolerance: number, getNode: () => Promise<IEnr | null>): Promise<IEnr[]>;
8
+ /**
9
+ * Fetch nodes using passed [[getNode]] until all wanted capabilities are
10
+ * fulfilled or the number of [[getNode]] call exceeds the sum of
11
+ * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
12
+ */
13
+ export declare function yieldNodesUntilCapabilitiesFulfilled(wantedNodeCapabilityCount: Partial<NodeCapabilityCount>, errorTolerance: number, getNode: () => Promise<IEnr | null>): AsyncGenerator<IEnr>;
@@ -0,0 +1,133 @@
1
+ import { Logger } from "@waku/utils";
2
+ const log = new Logger("discovery:fetch_nodes");
3
+ /**
4
+ * Fetch nodes using passed [[getNode]] until all wanted capabilities are
5
+ * fulfilled or the number of [[getNode]] call exceeds the sum of
6
+ * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
7
+ */
8
+ export async function fetchNodesUntilCapabilitiesFulfilled(wantedNodeCapabilityCount, errorTolerance, getNode) {
9
+ const wanted = {
10
+ relay: wantedNodeCapabilityCount.relay ?? 0,
11
+ store: wantedNodeCapabilityCount.store ?? 0,
12
+ filter: wantedNodeCapabilityCount.filter ?? 0,
13
+ lightPush: wantedNodeCapabilityCount.lightPush ?? 0
14
+ };
15
+ const maxSearches = wanted.relay + wanted.store + wanted.filter + wanted.lightPush;
16
+ const actual = {
17
+ relay: 0,
18
+ store: 0,
19
+ filter: 0,
20
+ lightPush: 0
21
+ };
22
+ let totalSearches = 0;
23
+ const peers = [];
24
+ while (!isSatisfied(wanted, actual) &&
25
+ totalSearches < maxSearches + errorTolerance) {
26
+ const peer = await getNode();
27
+ if (peer && isNewPeer(peer, peers)) {
28
+ // ENRs without a waku2 key are ignored.
29
+ if (peer.waku2) {
30
+ if (helpsSatisfyCapabilities(peer.waku2, wanted, actual)) {
31
+ addCapabilities(peer.waku2, actual);
32
+ peers.push(peer);
33
+ }
34
+ }
35
+ log.info(`got new peer candidate from DNS address=${peer.nodeId}@${peer.ip}`);
36
+ }
37
+ totalSearches++;
38
+ }
39
+ return peers;
40
+ }
41
+ /**
42
+ * Fetch nodes using passed [[getNode]] until all wanted capabilities are
43
+ * fulfilled or the number of [[getNode]] call exceeds the sum of
44
+ * [[wantedNodeCapabilityCount]] plus [[errorTolerance]].
45
+ */
46
+ export async function* yieldNodesUntilCapabilitiesFulfilled(wantedNodeCapabilityCount, errorTolerance, getNode) {
47
+ const wanted = {
48
+ relay: wantedNodeCapabilityCount.relay ?? 0,
49
+ store: wantedNodeCapabilityCount.store ?? 0,
50
+ filter: wantedNodeCapabilityCount.filter ?? 0,
51
+ lightPush: wantedNodeCapabilityCount.lightPush ?? 0
52
+ };
53
+ const maxSearches = wanted.relay + wanted.store + wanted.filter + wanted.lightPush;
54
+ const actual = {
55
+ relay: 0,
56
+ store: 0,
57
+ filter: 0,
58
+ lightPush: 0
59
+ };
60
+ let totalSearches = 0;
61
+ const peerNodeIds = new Set();
62
+ while (!isSatisfied(wanted, actual) &&
63
+ totalSearches < maxSearches + errorTolerance) {
64
+ const peer = await getNode();
65
+ if (peer && peer.nodeId && !peerNodeIds.has(peer.nodeId)) {
66
+ peerNodeIds.add(peer.nodeId);
67
+ // ENRs without a waku2 key are ignored.
68
+ if (peer.waku2) {
69
+ if (helpsSatisfyCapabilities(peer.waku2, wanted, actual)) {
70
+ addCapabilities(peer.waku2, actual);
71
+ yield peer;
72
+ }
73
+ }
74
+ log.info(`got new peer candidate from DNS address=${peer.nodeId}@${peer.ip}`);
75
+ }
76
+ totalSearches++;
77
+ }
78
+ }
79
+ function isSatisfied(wanted, actual) {
80
+ return (actual.relay >= wanted.relay &&
81
+ actual.store >= wanted.store &&
82
+ actual.filter >= wanted.filter &&
83
+ actual.lightPush >= wanted.lightPush);
84
+ }
85
+ function isNewPeer(peer, peers) {
86
+ if (!peer.nodeId)
87
+ return false;
88
+ for (const existingPeer of peers) {
89
+ if (peer.nodeId === existingPeer.nodeId) {
90
+ return false;
91
+ }
92
+ }
93
+ return true;
94
+ }
95
+ function addCapabilities(node, total) {
96
+ if (node.relay)
97
+ total.relay += 1;
98
+ if (node.store)
99
+ total.store += 1;
100
+ if (node.filter)
101
+ total.filter += 1;
102
+ if (node.lightPush)
103
+ total.lightPush += 1;
104
+ }
105
+ /**
106
+ * Checks if the proposed ENR [[node]] helps satisfy the [[wanted]] capabilities,
107
+ * considering the [[actual]] capabilities of nodes retrieved so far..
108
+ *
109
+ * @throws If the function is called when the wanted capabilities are already fulfilled.
110
+ */
111
+ function helpsSatisfyCapabilities(node, wanted, actual) {
112
+ if (isSatisfied(wanted, actual)) {
113
+ throw "Internal Error: Waku2 wanted capabilities are already fulfilled";
114
+ }
115
+ const missing = missingCapabilities(wanted, actual);
116
+ return ((missing.relay && node.relay) ||
117
+ (missing.store && node.store) ||
118
+ (missing.filter && node.filter) ||
119
+ (missing.lightPush && node.lightPush));
120
+ }
121
+ /**
122
+ * Return a [[Waku2]] Object for which capabilities are set to true if they are
123
+ * [[wanted]] yet missing from [[actual]].
124
+ */
125
+ function missingCapabilities(wanted, actual) {
126
+ return {
127
+ relay: actual.relay < wanted.relay,
128
+ store: actual.store < wanted.store,
129
+ filter: actual.filter < wanted.filter,
130
+ lightPush: actual.lightPush < wanted.lightPush
131
+ };
132
+ }
133
+ //# sourceMappingURL=fetch_nodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch_nodes.js","sourceRoot":"","sources":["../../src/dns/fetch_nodes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAEhD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,yBAAuD,EACvD,cAAsB,EACtB,OAAmC;IAEnC,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,yBAAyB,CAAC,KAAK,IAAI,CAAC;QAC3C,KAAK,EAAE,yBAAyB,CAAC,KAAK,IAAI,CAAC;QAC3C,MAAM,EAAE,yBAAyB,CAAC,MAAM,IAAI,CAAC;QAC7C,SAAS,EAAE,yBAAyB,CAAC,SAAS,IAAI,CAAC;KACpD,CAAC;IAEF,MAAM,WAAW,GACf,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;IAEjE,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC;QACT,SAAS,EAAE,CAAC;KACb,CAAC;IAEF,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,MAAM,KAAK,GAAW,EAAE,CAAC;IAEzB,OACE,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;QAC5B,aAAa,GAAG,WAAW,GAAG,cAAc,EAC5C,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,IAAI,IAAI,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACnC,wCAAwC;YACxC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,IAAI,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;oBACzD,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;oBACpC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;YACD,GAAG,CAAC,IAAI,CACN,2CAA2C,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,EAAE,CACpE,CAAC;QACJ,CAAC;QAED,aAAa,EAAE,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,oCAAoC,CACzD,yBAAuD,EACvD,cAAsB,EACtB,OAAmC;IAEnC,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,yBAAyB,CAAC,KAAK,IAAI,CAAC;QAC3C,KAAK,EAAE,yBAAyB,CAAC,KAAK,IAAI,CAAC;QAC3C,MAAM,EAAE,yBAAyB,CAAC,MAAM,IAAI,CAAC;QAC7C,SAAS,EAAE,yBAAyB,CAAC,SAAS,IAAI,CAAC;KACpD,CAAC;IAEF,MAAM,WAAW,GACf,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;IAEjE,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC;QACT,SAAS,EAAE,CAAC;KACb,CAAC;IAEF,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;IAE9B,OACE,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;QAC5B,aAAa,GAAG,WAAW,GAAG,cAAc,EAC5C,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7B,wCAAwC;YACxC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,IAAI,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;oBACzD,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;oBACpC,MAAM,IAAI,CAAC;gBACb,CAAC;YACH,CAAC;YACD,GAAG,CAAC,IAAI,CACN,2CAA2C,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,EAAE,CACpE,CAAC;QACJ,CAAC;QACD,aAAa,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAClB,MAA2B,EAC3B,MAA2B;IAE3B,OAAO,CACL,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;QAC5B,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;QAC5B,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM;QAC9B,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CACrC,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,IAAU,EAAE,KAAa;IAC1C,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE/B,KAAK,MAAM,YAAY,IAAI,KAAK,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,IAAW,EAAE,KAA0B;IAC9D,IAAI,IAAI,CAAC,KAAK;QAAE,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,KAAK;QAAE,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,SAAS;QAAE,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAC/B,IAAW,EACX,MAA2B,EAC3B,MAA2B;IAE3B,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;QAChC,MAAM,iEAAiE,CAAC;IAC1E,CAAC;IAED,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpD,OAAO,CACL,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC;QAC7B,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC;QAC7B,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QAC/B,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,CACtC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,MAA2B,EAC3B,MAA2B;IAE3B,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK;QAClC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK;QAClC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS;KAC/C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { PeerDiscoveryDns, wakuDnsDiscovery } from "./dns_discovery.js";
2
+ export { enrTree } from "./constants.js";
3
+ export { DnsNodeDiscovery } from "./dns.js";
@@ -0,0 +1,4 @@
1
+ export { PeerDiscoveryDns, wakuDnsDiscovery } from "./dns_discovery.js";
2
+ export { enrTree } from "./constants.js";
3
+ export { DnsNodeDiscovery } from "./dns.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dns/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { PeerDiscoveryDns, wakuDnsDiscovery } from "./dns/dns_discovery.js";
2
+ export { enrTree } from "./dns/constants.js";
3
+ export { DnsNodeDiscovery } from "./dns/dns.js";
4
+ export { wakuPeerExchange, PeerExchangeCodec, WakuPeerExchange } from "./peer-exchange/waku_peer_exchange.js";
5
+ export { wakuPeerExchangeDiscovery, PeerExchangeDiscovery } from "./peer-exchange/waku_peer_exchange_discovery.js";
6
+ export { LocalPeerCacheDiscovery, wakuLocalPeerCacheDiscovery } from "./local-peer-cache/index.js";
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ // DNS Discovery
2
+ export { PeerDiscoveryDns, wakuDnsDiscovery } from "./dns/dns_discovery.js";
3
+ export { enrTree } from "./dns/constants.js";
4
+ export { DnsNodeDiscovery } from "./dns/dns.js";
5
+ // Peer Exchange Discovery
6
+ export { wakuPeerExchange, PeerExchangeCodec, WakuPeerExchange } from "./peer-exchange/waku_peer_exchange.js";
7
+ export { wakuPeerExchangeDiscovery, PeerExchangeDiscovery } from "./peer-exchange/waku_peer_exchange_discovery.js";
8
+ // Local Peer Cache Discovery
9
+ export { LocalPeerCacheDiscovery, wakuLocalPeerCacheDiscovery } from "./local-peer-cache/index.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,0BAA0B;AAC1B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACtB,MAAM,iDAAiD,CAAC;AAEzD,6BAA6B;AAC7B,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { TypedEventEmitter } from "@libp2p/interface";
2
+ import { CustomEvent, IdentifyResult, PeerDiscovery, PeerDiscoveryEvents, Startable } from "@libp2p/interface";
3
+ import { type Libp2pComponents, Tags } from "@waku/interfaces";
4
+ type LocalPeerCacheDiscoveryOptions = {
5
+ tagName?: string;
6
+ tagValue?: number;
7
+ tagTTL?: number;
8
+ };
9
+ export declare const DEFAULT_LOCAL_TAG_NAME = Tags.LOCAL;
10
+ export declare class LocalPeerCacheDiscovery extends TypedEventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Startable {
11
+ private readonly components;
12
+ private readonly options?;
13
+ private isStarted;
14
+ private peers;
15
+ constructor(components: Libp2pComponents, options?: LocalPeerCacheDiscoveryOptions | undefined);
16
+ get [Symbol.toStringTag](): string;
17
+ start(): Promise<void>;
18
+ stop(): void | Promise<void>;
19
+ handleNewPeers: (event: CustomEvent<IdentifyResult>) => void;
20
+ private getPeersFromLocalStorage;
21
+ private savePeersToLocalStorage;
22
+ }
23
+ export declare function wakuLocalPeerCacheDiscovery(): (components: Libp2pComponents, options?: LocalPeerCacheDiscoveryOptions) => LocalPeerCacheDiscovery;
24
+ export {};
@@ -0,0 +1,106 @@
1
+ import { TypedEventEmitter } from "@libp2p/interface";
2
+ import { CustomEvent } from "@libp2p/interface";
3
+ import { createFromJSON } from "@libp2p/peer-id-factory";
4
+ import { multiaddr } from "@multiformats/multiaddr";
5
+ import { Tags } from "@waku/interfaces";
6
+ import { getWsMultiaddrFromMultiaddrs, Logger } from "@waku/utils";
7
+ const log = new Logger("peer-exchange-discovery");
8
+ export const DEFAULT_LOCAL_TAG_NAME = Tags.LOCAL;
9
+ const DEFAULT_LOCAL_TAG_VALUE = 50;
10
+ const DEFAULT_LOCAL_TAG_TTL = 100000000;
11
+ export class LocalPeerCacheDiscovery extends TypedEventEmitter {
12
+ components;
13
+ options;
14
+ isStarted;
15
+ peers = [];
16
+ constructor(components, options) {
17
+ super();
18
+ this.components = components;
19
+ this.options = options;
20
+ this.isStarted = false;
21
+ this.peers = this.getPeersFromLocalStorage();
22
+ }
23
+ get [Symbol.toStringTag]() {
24
+ return "@waku/local-peer-cache-discovery";
25
+ }
26
+ async start() {
27
+ if (this.isStarted)
28
+ return;
29
+ log.info("Starting Local Storage Discovery");
30
+ this.components.events.addEventListener("peer:identify", this.handleNewPeers);
31
+ for (const { id: idStr, address } of this.peers) {
32
+ const peerId = await createFromJSON({ id: idStr });
33
+ if (await this.components.peerStore.has(peerId))
34
+ continue;
35
+ await this.components.peerStore.save(peerId, {
36
+ multiaddrs: [multiaddr(address)],
37
+ tags: {
38
+ [this.options?.tagName ?? DEFAULT_LOCAL_TAG_NAME]: {
39
+ value: this.options?.tagValue ?? DEFAULT_LOCAL_TAG_VALUE,
40
+ ttl: this.options?.tagTTL ?? DEFAULT_LOCAL_TAG_TTL
41
+ }
42
+ }
43
+ });
44
+ this.dispatchEvent(new CustomEvent("peer", {
45
+ detail: {
46
+ id: peerId,
47
+ multiaddrs: [multiaddr(address)]
48
+ }
49
+ }));
50
+ }
51
+ log.info(`Discovered ${this.peers.length} peers`);
52
+ this.isStarted = true;
53
+ }
54
+ stop() {
55
+ if (!this.isStarted)
56
+ return;
57
+ log.info("Stopping Local Storage Discovery");
58
+ this.components.events.removeEventListener("peer:identify", this.handleNewPeers);
59
+ this.isStarted = false;
60
+ this.savePeersToLocalStorage();
61
+ }
62
+ handleNewPeers = (event) => {
63
+ const { peerId, listenAddrs } = event.detail;
64
+ const websocketMultiaddr = getWsMultiaddrFromMultiaddrs(listenAddrs);
65
+ const localStoragePeers = this.getPeersFromLocalStorage();
66
+ const existingPeerIndex = localStoragePeers.findIndex((_peer) => _peer.id === peerId.toString());
67
+ if (existingPeerIndex >= 0) {
68
+ localStoragePeers[existingPeerIndex].address =
69
+ websocketMultiaddr.toString();
70
+ }
71
+ else {
72
+ localStoragePeers.push({
73
+ id: peerId.toString(),
74
+ address: websocketMultiaddr.toString()
75
+ });
76
+ }
77
+ this.peers = localStoragePeers;
78
+ this.savePeersToLocalStorage();
79
+ };
80
+ getPeersFromLocalStorage() {
81
+ try {
82
+ const storedPeersData = localStorage.getItem("waku:peers");
83
+ if (!storedPeersData)
84
+ return [];
85
+ const peers = JSON.parse(storedPeersData);
86
+ return peers.filter(isValidStoredPeer);
87
+ }
88
+ catch (error) {
89
+ log.error("Error parsing peers from local storage:", error);
90
+ return [];
91
+ }
92
+ }
93
+ savePeersToLocalStorage() {
94
+ localStorage.setItem("waku:peers", JSON.stringify(this.peers));
95
+ }
96
+ }
97
+ function isValidStoredPeer(peer) {
98
+ return (peer &&
99
+ typeof peer === "object" &&
100
+ typeof peer.id === "string" &&
101
+ typeof peer.address === "string");
102
+ }
103
+ export function wakuLocalPeerCacheDiscovery() {
104
+ return (components, options) => new LocalPeerCacheDiscovery(components, options);
105
+ }
106
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/local-peer-cache/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { wakuPeerExchange, PeerExchangeCodec, WakuPeerExchange } from "./waku_peer_exchange.js";
2
+ export { wakuPeerExchangeDiscovery, PeerExchangeDiscovery, Options, DEFAULT_PEER_EXCHANGE_TAG_NAME } from "./waku_peer_exchange_discovery.js";
@@ -0,0 +1,3 @@
1
+ export { wakuPeerExchange, PeerExchangeCodec, WakuPeerExchange } from "./waku_peer_exchange.js";
2
+ export { wakuPeerExchangeDiscovery, PeerExchangeDiscovery, DEFAULT_PEER_EXCHANGE_TAG_NAME } from "./waku_peer_exchange_discovery.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/peer-exchange/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EAErB,8BAA8B,EAC/B,MAAM,mCAAmC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { proto_peer_exchange as proto } from "@waku/proto";
2
+ import type { Uint8ArrayList } from "uint8arraylist";
3
+ /**
4
+ * PeerExchangeRPC represents a message conforming to the Waku Peer Exchange protocol
5
+ */
6
+ export declare class PeerExchangeRPC {
7
+ proto: proto.PeerExchangeRPC;
8
+ constructor(proto: proto.PeerExchangeRPC);
9
+ static createRequest(params: proto.PeerExchangeQuery): PeerExchangeRPC;
10
+ /**
11
+ * Encode the current PeerExchangeRPC request to bytes
12
+ * @returns Uint8Array
13
+ */
14
+ encode(): Uint8Array;
15
+ /**
16
+ * Decode the current PeerExchangeRPC request to bytes
17
+ * @returns Uint8Array
18
+ */
19
+ static decode(bytes: Uint8ArrayList): PeerExchangeRPC;
20
+ get query(): proto.PeerExchangeQuery | undefined;
21
+ get response(): proto.PeerExchangeResponse | undefined;
22
+ }
@@ -0,0 +1,41 @@
1
+ import { proto_peer_exchange as proto } from "@waku/proto";
2
+ /**
3
+ * PeerExchangeRPC represents a message conforming to the Waku Peer Exchange protocol
4
+ */
5
+ export class PeerExchangeRPC {
6
+ proto;
7
+ constructor(proto) {
8
+ this.proto = proto;
9
+ }
10
+ static createRequest(params) {
11
+ const { numPeers } = params;
12
+ return new PeerExchangeRPC({
13
+ query: {
14
+ numPeers: numPeers
15
+ },
16
+ response: undefined
17
+ });
18
+ }
19
+ /**
20
+ * Encode the current PeerExchangeRPC request to bytes
21
+ * @returns Uint8Array
22
+ */
23
+ encode() {
24
+ return proto.PeerExchangeRPC.encode(this.proto);
25
+ }
26
+ /**
27
+ * Decode the current PeerExchangeRPC request to bytes
28
+ * @returns Uint8Array
29
+ */
30
+ static decode(bytes) {
31
+ const res = proto.PeerExchangeRPC.decode(bytes);
32
+ return new PeerExchangeRPC(res);
33
+ }
34
+ get query() {
35
+ return this.proto.query;
36
+ }
37
+ get response() {
38
+ return this.proto.response;
39
+ }
40
+ }
41
+ //# sourceMappingURL=rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/peer-exchange/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,KAAK,EAAE,MAAM,aAAa,CAAC;AAG3D;;GAEG;AACH,MAAM,OAAO,eAAe;IACA;IAA1B,YAA0B,KAA4B;QAA5B,UAAK,GAAL,KAAK,CAAuB;IAAG,CAAC;IAE1D,MAAM,CAAC,aAAa,CAAC,MAA+B;QAClD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QAC5B,OAAO,IAAI,eAAe,CAAC;YACzB,KAAK,EAAE;gBACL,QAAQ,EAAE,QAAQ;aACnB;YACD,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,OAAO,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,KAAqB;QACjC,MAAM,GAAG,GAAG,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChD,OAAO,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import { BaseProtocol } from "@waku/core/lib/base_protocol";
2
+ import { IPeerExchange, Libp2pComponents, PeerExchangeQueryParams, PeerExchangeResult, PubsubTopic } from "@waku/interfaces";
3
+ export declare const PeerExchangeCodec = "/vac/waku/peer-exchange/2.0.0-alpha1";
4
+ /**
5
+ * Implementation of the Peer Exchange protocol (https://rfc.vac.dev/spec/34/)
6
+ */
7
+ export declare class WakuPeerExchange extends BaseProtocol implements IPeerExchange {
8
+ /**
9
+ * @param components - libp2p components
10
+ */
11
+ constructor(components: Libp2pComponents, pubsubTopics: PubsubTopic[]);
12
+ /**
13
+ * Make a peer exchange query to a peer
14
+ */
15
+ query(params: PeerExchangeQueryParams): Promise<PeerExchangeResult>;
16
+ }
17
+ /**
18
+ *
19
+ * @returns A function that creates a new peer exchange protocol
20
+ */
21
+ export declare function wakuPeerExchange(pubsubTopics: PubsubTopic[]): (components: Libp2pComponents) => WakuPeerExchange;
@@ -0,0 +1,80 @@
1
+ import { BaseProtocol } from "@waku/core/lib/base_protocol";
2
+ import { EnrDecoder } from "@waku/enr";
3
+ import { ProtocolError } from "@waku/interfaces";
4
+ import { isDefined } from "@waku/utils";
5
+ import { Logger } from "@waku/utils";
6
+ import all from "it-all";
7
+ import * as lp from "it-length-prefixed";
8
+ import { pipe } from "it-pipe";
9
+ import { Uint8ArrayList } from "uint8arraylist";
10
+ import { PeerExchangeRPC } from "./rpc.js";
11
+ export const PeerExchangeCodec = "/vac/waku/peer-exchange/2.0.0-alpha1";
12
+ const log = new Logger("peer-exchange");
13
+ /**
14
+ * Implementation of the Peer Exchange protocol (https://rfc.vac.dev/spec/34/)
15
+ */
16
+ export class WakuPeerExchange extends BaseProtocol {
17
+ /**
18
+ * @param components - libp2p components
19
+ */
20
+ constructor(components, pubsubTopics) {
21
+ super(PeerExchangeCodec, components, log, pubsubTopics);
22
+ }
23
+ /**
24
+ * Make a peer exchange query to a peer
25
+ */
26
+ async query(params) {
27
+ const { numPeers } = params;
28
+ const rpcQuery = PeerExchangeRPC.createRequest({
29
+ numPeers: BigInt(numPeers)
30
+ });
31
+ const peer = await this.peerStore.get(params.peerId);
32
+ if (!peer) {
33
+ return {
34
+ peerInfos: null,
35
+ error: ProtocolError.NO_PEER_AVAILABLE
36
+ };
37
+ }
38
+ const stream = await this.getStream(peer);
39
+ const res = await pipe([rpcQuery.encode()], lp.encode, stream, lp.decode, async (source) => await all(source));
40
+ try {
41
+ const bytes = new Uint8ArrayList();
42
+ res.forEach((chunk) => {
43
+ bytes.append(chunk);
44
+ });
45
+ const { response } = PeerExchangeRPC.decode(bytes);
46
+ if (!response) {
47
+ log.error("PeerExchangeRPC message did not contains a `response` field");
48
+ return {
49
+ peerInfos: null,
50
+ error: ProtocolError.EMPTY_PAYLOAD
51
+ };
52
+ }
53
+ const peerInfos = await Promise.all(response.peerInfos
54
+ .map((peerInfo) => peerInfo.enr)
55
+ .filter(isDefined)
56
+ .map(async (enr) => {
57
+ return { ENR: await EnrDecoder.fromRLP(enr) };
58
+ }));
59
+ return {
60
+ peerInfos,
61
+ error: null
62
+ };
63
+ }
64
+ catch (err) {
65
+ log.error("Failed to decode push reply", err);
66
+ return {
67
+ peerInfos: null,
68
+ error: ProtocolError.DECODE_FAILED
69
+ };
70
+ }
71
+ }
72
+ }
73
+ /**
74
+ *
75
+ * @returns A function that creates a new peer exchange protocol
76
+ */
77
+ export function wakuPeerExchange(pubsubTopics) {
78
+ return (components) => new WakuPeerExchange(components, pubsubTopics);
79
+ }
80
+ //# sourceMappingURL=waku_peer_exchange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waku_peer_exchange.js","sourceRoot":"","sources":["../../src/peer-exchange/waku_peer_exchange.ts"],"names":[],"mappings":"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"}