@waku/core 0.0.1

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 (235) hide show
  1. package/CHANGELOG.md +614 -0
  2. package/README.md +56 -0
  3. package/bundle/browser-1e1a2f27.js +722 -0
  4. package/bundle/crypto-8551d579.js +2585 -0
  5. package/bundle/crypto-b00764b7.js +1772 -0
  6. package/bundle/enr-564d4a51.js +20785 -0
  7. package/bundle/enr-9fc5eed8.js +20786 -0
  8. package/bundle/enr-f6e82a53.js +20785 -0
  9. package/bundle/events-158407bb.js +1929 -0
  10. package/bundle/events-fcbda4dc.js +76 -0
  11. package/bundle/index-02d21809.js +20 -0
  12. package/bundle/index-0a4bdddc.js +2976 -0
  13. package/bundle/index-2ae915be.js +1854 -0
  14. package/bundle/index-64ce43f0.js +69 -0
  15. package/bundle/index-691c0be6.js +4059 -0
  16. package/bundle/index-a013a259.js +20 -0
  17. package/bundle/index-ba42b4fc.js +862 -0
  18. package/bundle/index.js +13428 -0
  19. package/bundle/lib/enr.js +8 -0
  20. package/bundle/lib/peer_discovery_dns.js +5018 -0
  21. package/bundle/lib/peer_discovery_static_list.js +75 -0
  22. package/bundle/lib/predefined_bootstrap_nodes.js +59 -0
  23. package/bundle/lib/utils.js +1 -0
  24. package/bundle/lib/wait_for_remote_peer.js +327 -0
  25. package/bundle/lib/waku_message/topic_only_message.js +4 -0
  26. package/bundle/lib/waku_message/version_0.js +4 -0
  27. package/bundle/lib/waku_message/version_1.js +463 -0
  28. package/bundle/message-e2db79d7.js +8393 -0
  29. package/bundle/multiaddr_to_peer_info-c406b1e1.js +19 -0
  30. package/bundle/multiaddr_to_peer_info-fd1de516.js +19 -0
  31. package/bundle/random_subset-75d1c511.js +26 -0
  32. package/bundle/topic_only_message-34f36fa6.js +82 -0
  33. package/bundle/utils-9a3221f2.js +815 -0
  34. package/bundle/version_0-e6fe440c.js +317 -0
  35. package/dist/index.d.ts +16 -0
  36. package/dist/index.js +17 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/lib/constants.d.ts +4 -0
  39. package/dist/lib/constants.js +5 -0
  40. package/dist/lib/constants.js.map +1 -0
  41. package/dist/lib/crypto.d.ts +34 -0
  42. package/dist/lib/crypto.js +79 -0
  43. package/dist/lib/crypto.js.map +1 -0
  44. package/dist/lib/enr/constants.d.ts +4 -0
  45. package/dist/lib/enr/constants.js +8 -0
  46. package/dist/lib/enr/constants.js.map +1 -0
  47. package/dist/lib/enr/enr.d.ts +90 -0
  48. package/dist/lib/enr/enr.js +432 -0
  49. package/dist/lib/enr/enr.js.map +1 -0
  50. package/dist/lib/enr/index.d.ts +5 -0
  51. package/dist/lib/enr/index.js +6 -0
  52. package/dist/lib/enr/index.js.map +1 -0
  53. package/dist/lib/enr/keypair/index.d.ts +8 -0
  54. package/dist/lib/enr/keypair/index.js +53 -0
  55. package/dist/lib/enr/keypair/index.js.map +1 -0
  56. package/dist/lib/enr/keypair/secp256k1.d.ts +13 -0
  57. package/dist/lib/enr/keypair/secp256k1.js +57 -0
  58. package/dist/lib/enr/keypair/secp256k1.js.map +1 -0
  59. package/dist/lib/enr/keypair/types.d.ts +13 -0
  60. package/dist/lib/enr/keypair/types.js +7 -0
  61. package/dist/lib/enr/keypair/types.js.map +1 -0
  62. package/dist/lib/enr/multiaddr_from_fields.d.ts +2 -0
  63. package/dist/lib/enr/multiaddr_from_fields.js +8 -0
  64. package/dist/lib/enr/multiaddr_from_fields.js.map +1 -0
  65. package/dist/lib/enr/multiaddrs_codec.d.ts +3 -0
  66. package/dist/lib/enr/multiaddrs_codec.js +32 -0
  67. package/dist/lib/enr/multiaddrs_codec.js.map +1 -0
  68. package/dist/lib/enr/types.d.ts +8 -0
  69. package/dist/lib/enr/types.js +3 -0
  70. package/dist/lib/enr/types.js.map +1 -0
  71. package/dist/lib/enr/v4.d.ts +3 -0
  72. package/dist/lib/enr/v4.js +14 -0
  73. package/dist/lib/enr/v4.js.map +1 -0
  74. package/dist/lib/enr/waku2_codec.d.ts +8 -0
  75. package/dist/lib/enr/waku2_codec.js +36 -0
  76. package/dist/lib/enr/waku2_codec.js.map +1 -0
  77. package/dist/lib/group_by.d.ts +3 -0
  78. package/dist/lib/group_by.js +13 -0
  79. package/dist/lib/group_by.js.map +1 -0
  80. package/dist/lib/multiaddr_to_peer_info.d.ts +3 -0
  81. package/dist/lib/multiaddr_to_peer_info.js +15 -0
  82. package/dist/lib/multiaddr_to_peer_info.js.map +1 -0
  83. package/dist/lib/peer_discovery_dns/dns.d.ts +48 -0
  84. package/dist/lib/peer_discovery_dns/dns.js +158 -0
  85. package/dist/lib/peer_discovery_dns/dns.js.map +1 -0
  86. package/dist/lib/peer_discovery_dns/dns_over_https.d.ts +32 -0
  87. package/dist/lib/peer_discovery_dns/dns_over_https.js +87 -0
  88. package/dist/lib/peer_discovery_dns/dns_over_https.js.map +1 -0
  89. package/dist/lib/peer_discovery_dns/enrtree.d.ts +33 -0
  90. package/dist/lib/peer_discovery_dns/enrtree.js +76 -0
  91. package/dist/lib/peer_discovery_dns/enrtree.js.map +1 -0
  92. package/dist/lib/peer_discovery_dns/fetch_nodes.d.ts +14 -0
  93. package/dist/lib/peer_discovery_dns/fetch_nodes.js +133 -0
  94. package/dist/lib/peer_discovery_dns/fetch_nodes.js.map +1 -0
  95. package/dist/lib/peer_discovery_dns/index.d.ts +30 -0
  96. package/dist/lib/peer_discovery_dns/index.js +54 -0
  97. package/dist/lib/peer_discovery_dns/index.js.map +1 -0
  98. package/dist/lib/peer_discovery_static_list.d.ts +44 -0
  99. package/dist/lib/peer_discovery_static_list.js +72 -0
  100. package/dist/lib/peer_discovery_static_list.js.map +1 -0
  101. package/dist/lib/predefined_bootstrap_nodes.d.ts +35 -0
  102. package/dist/lib/predefined_bootstrap_nodes.js +56 -0
  103. package/dist/lib/predefined_bootstrap_nodes.js.map +1 -0
  104. package/dist/lib/push_or_init_map.d.ts +1 -0
  105. package/dist/lib/push_or_init_map.js +9 -0
  106. package/dist/lib/push_or_init_map.js.map +1 -0
  107. package/dist/lib/random_subset.d.ts +4 -0
  108. package/dist/lib/random_subset.js +25 -0
  109. package/dist/lib/random_subset.js.map +1 -0
  110. package/dist/lib/select_connection.d.ts +2 -0
  111. package/dist/lib/select_connection.js +19 -0
  112. package/dist/lib/select_connection.js.map +1 -0
  113. package/dist/lib/select_peer.d.ts +15 -0
  114. package/dist/lib/select_peer.js +59 -0
  115. package/dist/lib/select_peer.js.map +1 -0
  116. package/dist/lib/to_proto_message.d.ts +3 -0
  117. package/dist/lib/to_proto_message.js +11 -0
  118. package/dist/lib/to_proto_message.js.map +1 -0
  119. package/dist/lib/utils.d.ts +22 -0
  120. package/dist/lib/utils.js +40 -0
  121. package/dist/lib/utils.js.map +1 -0
  122. package/dist/lib/wait_for_remote_peer.d.ts +22 -0
  123. package/dist/lib/wait_for_remote_peer.js +113 -0
  124. package/dist/lib/wait_for_remote_peer.js.map +1 -0
  125. package/dist/lib/waku.d.ts +61 -0
  126. package/dist/lib/waku.js +174 -0
  127. package/dist/lib/waku.js.map +1 -0
  128. package/dist/lib/waku_filter/filter_rpc.d.ts +25 -0
  129. package/dist/lib/waku_filter/filter_rpc.js +44 -0
  130. package/dist/lib/waku_filter/filter_rpc.js.map +1 -0
  131. package/dist/lib/waku_filter/index.d.ts +50 -0
  132. package/dist/lib/waku_filter/index.js +181 -0
  133. package/dist/lib/waku_filter/index.js.map +1 -0
  134. package/dist/lib/waku_light_push/index.d.ts +38 -0
  135. package/dist/lib/waku_light_push/index.js +83 -0
  136. package/dist/lib/waku_light_push/index.js.map +1 -0
  137. package/dist/lib/waku_light_push/push_rpc.d.ts +11 -0
  138. package/dist/lib/waku_light_push/push_rpc.js +31 -0
  139. package/dist/lib/waku_light_push/push_rpc.js.map +1 -0
  140. package/dist/lib/waku_message/constants.d.ts +12 -0
  141. package/dist/lib/waku_message/constants.js +10 -0
  142. package/dist/lib/waku_message/constants.js.map +1 -0
  143. package/dist/lib/waku_message/ecies.d.ts +17 -0
  144. package/dist/lib/waku_message/ecies.js +126 -0
  145. package/dist/lib/waku_message/ecies.js.map +1 -0
  146. package/dist/lib/waku_message/symmetric.d.ts +3 -0
  147. package/dist/lib/waku_message/symmetric.js +18 -0
  148. package/dist/lib/waku_message/symmetric.js.map +1 -0
  149. package/dist/lib/waku_message/topic_only_message.d.ts +15 -0
  150. package/dist/lib/waku_message/topic_only_message.js +31 -0
  151. package/dist/lib/waku_message/topic_only_message.js.map +1 -0
  152. package/dist/lib/waku_message/version_0.d.ts +26 -0
  153. package/dist/lib/waku_message/version_0.js +96 -0
  154. package/dist/lib/waku_message/version_0.js.map +1 -0
  155. package/dist/lib/waku_message/version_1.d.ts +93 -0
  156. package/dist/lib/waku_message/version_1.js +325 -0
  157. package/dist/lib/waku_message/version_1.js.map +1 -0
  158. package/dist/lib/waku_relay/constants.d.ts +63 -0
  159. package/dist/lib/waku_relay/constants.js +67 -0
  160. package/dist/lib/waku_relay/constants.js.map +1 -0
  161. package/dist/lib/waku_relay/index.d.ts +65 -0
  162. package/dist/lib/waku_relay/index.js +111 -0
  163. package/dist/lib/waku_relay/index.js.map +1 -0
  164. package/dist/lib/waku_store/history_rpc.d.ts +27 -0
  165. package/dist/lib/waku_store/history_rpc.js +71 -0
  166. package/dist/lib/waku_store/history_rpc.js.map +1 -0
  167. package/dist/lib/waku_store/index.d.ts +126 -0
  168. package/dist/lib/waku_store/index.js +218 -0
  169. package/dist/lib/waku_store/index.js.map +1 -0
  170. package/dist/proto/filter.d.ts +65 -0
  171. package/dist/proto/filter.js +425 -0
  172. package/dist/proto/filter.js.map +1 -0
  173. package/dist/proto/light_push.d.ts +57 -0
  174. package/dist/proto/light_push.js +369 -0
  175. package/dist/proto/light_push.js.map +1 -0
  176. package/dist/proto/message.d.ts +29 -0
  177. package/dist/proto/message.js +215 -0
  178. package/dist/proto/message.js.map +1 -0
  179. package/dist/proto/store.d.ts +104 -0
  180. package/dist/proto/store.js +602 -0
  181. package/dist/proto/store.js.map +1 -0
  182. package/dist/proto/topic_only_message.d.ts +10 -0
  183. package/dist/proto/topic_only_message.js +46 -0
  184. package/dist/proto/topic_only_message.js.map +1 -0
  185. package/package.json +292 -0
  186. package/src/index.ts +33 -0
  187. package/src/lib/constants.ts +4 -0
  188. package/src/lib/crypto.ts +100 -0
  189. package/src/lib/enr/constants.ts +10 -0
  190. package/src/lib/enr/enr.ts +516 -0
  191. package/src/lib/enr/index.ts +5 -0
  192. package/src/lib/enr/keypair/index.ts +76 -0
  193. package/src/lib/enr/keypair/secp256k1.ts +69 -0
  194. package/src/lib/enr/keypair/types.ts +14 -0
  195. package/src/lib/enr/multiaddr_from_fields.ts +18 -0
  196. package/src/lib/enr/multiaddrs_codec.ts +50 -0
  197. package/src/lib/enr/types.ts +11 -0
  198. package/src/lib/enr/v4.ts +22 -0
  199. package/src/lib/enr/waku2_codec.ts +39 -0
  200. package/src/lib/group_by.ts +14 -0
  201. package/src/lib/multiaddr_to_peer_info.ts +17 -0
  202. package/src/lib/peer_discovery_dns/dns.ts +223 -0
  203. package/src/lib/peer_discovery_dns/dns_over_https.ts +98 -0
  204. package/src/lib/peer_discovery_dns/enrtree.ts +123 -0
  205. package/src/lib/peer_discovery_dns/fetch_nodes.ts +180 -0
  206. package/src/lib/peer_discovery_dns/index.ts +84 -0
  207. package/src/lib/peer_discovery_static_list.ts +118 -0
  208. package/src/lib/predefined_bootstrap_nodes.ts +72 -0
  209. package/src/lib/push_or_init_map.ts +13 -0
  210. package/src/lib/random_subset.ts +30 -0
  211. package/src/lib/select_connection.ts +24 -0
  212. package/src/lib/select_peer.ts +77 -0
  213. package/src/lib/to_proto_message.ts +15 -0
  214. package/src/lib/utils.ts +50 -0
  215. package/src/lib/wait_for_remote_peer.ts +151 -0
  216. package/src/lib/waku.ts +258 -0
  217. package/src/lib/waku_filter/filter_rpc.ts +57 -0
  218. package/src/lib/waku_filter/index.ts +291 -0
  219. package/src/lib/waku_light_push/index.ts +137 -0
  220. package/src/lib/waku_light_push/push_rpc.ts +39 -0
  221. package/src/lib/waku_message/constants.ts +10 -0
  222. package/src/lib/waku_message/ecies.ts +194 -0
  223. package/src/lib/waku_message/symmetric.ts +33 -0
  224. package/src/lib/waku_message/topic_only_message.ts +40 -0
  225. package/src/lib/waku_message/version_0.ts +121 -0
  226. package/src/lib/waku_message/version_1.ts +457 -0
  227. package/src/lib/waku_relay/constants.ts +77 -0
  228. package/src/lib/waku_relay/index.ts +189 -0
  229. package/src/lib/waku_store/history_rpc.ts +94 -0
  230. package/src/lib/waku_store/index.ts +372 -0
  231. package/src/proto/filter.ts +602 -0
  232. package/src/proto/light_push.ts +526 -0
  233. package/src/proto/message.ts +304 -0
  234. package/src/proto/store.ts +844 -0
  235. package/src/proto/topic_only_message.ts +67 -0
@@ -0,0 +1,151 @@
1
+ import { PeerProtocolsChangeData } from "@libp2p/interface-peer-store";
2
+ import type { PointToPointProtocol, Relay, Waku } from "@waku/interfaces";
3
+ import { Protocols } from "@waku/interfaces";
4
+ import debug from "debug";
5
+ import { pEvent } from "p-event";
6
+
7
+ import { FilterCodec } from "./waku_filter";
8
+ import { LightPushCodec } from "./waku_light_push";
9
+ import { StoreCodec } from "./waku_store";
10
+
11
+ const log = debug("waku:wait-for-remote-peer");
12
+
13
+ /**
14
+ * Wait for a remote peer to be ready given the passed protocols.
15
+ * Must be used after attempting to connect to nodes, using
16
+ * {@link index.waku.WakuNode.dial} or a bootstrap method with
17
+ * {@link lib/create_waku.createLightNode}.
18
+ *
19
+ * If the passed protocols is a GossipSub protocol, then it resolves only once
20
+ * a peer is in a mesh, to help ensure that other peers will send and receive
21
+ * message to us.
22
+ *
23
+ * @param waku The Waku Node
24
+ * @param protocols The protocols that need to be enabled by remote peers.
25
+ * @param timeoutMs A timeout value in milliseconds..
26
+ *
27
+ * @returns A promise that **resolves** if all desired protocols are fulfilled by
28
+ * remote nodes, **rejects** if the timeoutMs is reached.
29
+ * @throws If passing a protocol that is not mounted
30
+ * @default Wait for remote peers with protocols enabled locally and no time out is applied.
31
+ */
32
+ export async function waitForRemotePeer(
33
+ waku: Waku,
34
+ protocols?: Protocols[],
35
+ timeoutMs?: number
36
+ ): Promise<void> {
37
+ protocols = protocols ?? getEnabledProtocols(waku);
38
+
39
+ if (!waku.isStarted()) return Promise.reject("Waku node is not started");
40
+
41
+ const promises = [];
42
+
43
+ if (protocols.includes(Protocols.Relay)) {
44
+ if (!waku.relay)
45
+ throw new Error("Cannot wait for Relay peer: protocol not mounted");
46
+ promises.push(waitForGossipSubPeerInMesh(waku.relay));
47
+ }
48
+
49
+ if (protocols.includes(Protocols.Store)) {
50
+ if (!waku.store)
51
+ throw new Error("Cannot wait for Store peer: protocol not mounted");
52
+ promises.push(waitForConnectedPeer(waku.store, [StoreCodec]));
53
+ }
54
+
55
+ if (protocols.includes(Protocols.LightPush)) {
56
+ if (!waku.lightPush)
57
+ throw new Error("Cannot wait for LightPush peer: protocol not mounted");
58
+ promises.push(waitForConnectedPeer(waku.lightPush, [LightPushCodec]));
59
+ }
60
+
61
+ if (protocols.includes(Protocols.Filter)) {
62
+ if (!waku.filter)
63
+ throw new Error("Cannot wait for Filter peer: protocol not mounted");
64
+ promises.push(waitForConnectedPeer(waku.filter, [FilterCodec]));
65
+ }
66
+
67
+ if (timeoutMs) {
68
+ await rejectOnTimeout(
69
+ Promise.all(promises),
70
+ timeoutMs,
71
+ "Timed out waiting for a remote peer."
72
+ );
73
+ } else {
74
+ await Promise.all(promises);
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Wait for a peer with the given protocol to be connected.
80
+ */
81
+ async function waitForConnectedPeer(
82
+ waku: PointToPointProtocol,
83
+ codecs: string[]
84
+ ): Promise<void> {
85
+ const peers = await waku.peers();
86
+
87
+ if (peers.length) {
88
+ log(`${codecs} peer found: `, peers[0].id.toString());
89
+ return;
90
+ }
91
+
92
+ await new Promise<void>((resolve) => {
93
+ const cb = (evt: CustomEvent<PeerProtocolsChangeData>): void => {
94
+ for (const codec of codecs) {
95
+ if (evt.detail.protocols.includes(codec)) {
96
+ log("Resolving for", codec, evt.detail.protocols);
97
+ waku.libp2p.peerStore.removeEventListener("change:protocols", cb);
98
+ resolve();
99
+ break;
100
+ }
101
+ }
102
+ };
103
+ waku.libp2p.peerStore.addEventListener("change:protocols", cb);
104
+ });
105
+ }
106
+
107
+ /**
108
+ * Wait for a peer with the given protocol to be connected and in the gossipsub
109
+ * mesh.
110
+ */
111
+ async function waitForGossipSubPeerInMesh(waku: Relay): Promise<void> {
112
+ let peers = waku.getMeshPeers();
113
+
114
+ while (peers.length == 0) {
115
+ await pEvent(waku, "gossipsub:heartbeat");
116
+ peers = waku.getMeshPeers();
117
+ }
118
+ }
119
+
120
+ const awaitTimeout = (ms: number, rejectReason: string): Promise<void> =>
121
+ new Promise((_resolve, reject) => setTimeout(() => reject(rejectReason), ms));
122
+
123
+ async function rejectOnTimeout<T>(
124
+ promise: Promise<T>,
125
+ timeoutMs: number,
126
+ rejectReason: string
127
+ ): Promise<void> {
128
+ await Promise.race([promise, awaitTimeout(timeoutMs, rejectReason)]);
129
+ }
130
+
131
+ function getEnabledProtocols(waku: Waku): Protocols[] {
132
+ const protocols = [];
133
+
134
+ if (waku.relay) {
135
+ protocols.push(Protocols.Relay);
136
+ }
137
+
138
+ if (waku.filter) {
139
+ protocols.push(Protocols.Filter);
140
+ }
141
+
142
+ if (waku.store) {
143
+ protocols.push(Protocols.Store);
144
+ }
145
+
146
+ if (waku.lightPush) {
147
+ protocols.push(Protocols.LightPush);
148
+ }
149
+
150
+ return protocols;
151
+ }
@@ -0,0 +1,258 @@
1
+ import type { Stream } from "@libp2p/interface-connection";
2
+ import type { PeerId } from "@libp2p/interface-peer-id";
3
+ import type { PubSub } from "@libp2p/interface-pubsub";
4
+ import { peerIdFromString } from "@libp2p/peer-id";
5
+ import type { Multiaddr } from "@multiformats/multiaddr";
6
+ import { multiaddr } from "@multiformats/multiaddr";
7
+ import type { Waku } from "@waku/interfaces";
8
+ import { Protocols } from "@waku/interfaces";
9
+ import debug from "debug";
10
+ import type { Libp2p } from "libp2p";
11
+
12
+ import { FilterCodec, WakuFilter } from "./waku_filter";
13
+ import { LightPushCodec, WakuLightPush } from "./waku_light_push";
14
+ import { EncoderV0 } from "./waku_message/version_0";
15
+ import { WakuRelay } from "./waku_relay";
16
+ import { RelayCodecs, RelayPingContentTopic } from "./waku_relay/constants";
17
+ import * as relayConstants from "./waku_relay/constants";
18
+ import { StoreCodec, WakuStore } from "./waku_store";
19
+
20
+ export const DefaultPingKeepAliveValueSecs = 0;
21
+ export const DefaultRelayKeepAliveValueSecs = 5 * 60;
22
+
23
+ const log = debug("waku:waku");
24
+
25
+ export interface WakuOptions {
26
+ /**
27
+ * Set keep alive frequency in seconds: Waku will send a `/ipfs/ping/1.0.0`
28
+ * request to each peer after the set number of seconds. Set to 0 to disable.
29
+ *
30
+ * @default {@link DefaultPingKeepAliveValueSecs}
31
+ */
32
+ pingKeepAlive?: number;
33
+ /**
34
+ * Set keep alive frequency in seconds: Waku will send a ping message over
35
+ * relay to each peer after the set number of seconds. Set to 0 to disable.
36
+ *
37
+ * @default {@link DefaultRelayKeepAliveValueSecs}
38
+ */
39
+ relayKeepAlive?: number;
40
+ }
41
+
42
+ export class WakuNode implements Waku {
43
+ public libp2p: Libp2p;
44
+ public relay?: WakuRelay;
45
+ public store?: WakuStore;
46
+ public filter?: WakuFilter;
47
+ public lightPush?: WakuLightPush;
48
+
49
+ private pingKeepAliveTimers: {
50
+ [peer: string]: ReturnType<typeof setInterval>;
51
+ };
52
+ private relayKeepAliveTimers: {
53
+ [peer: string]: ReturnType<typeof setInterval>;
54
+ };
55
+
56
+ constructor(
57
+ options: WakuOptions,
58
+ libp2p: Libp2p,
59
+ store?: WakuStore,
60
+ lightPush?: WakuLightPush,
61
+ filter?: WakuFilter
62
+ ) {
63
+ this.libp2p = libp2p;
64
+ this.store = store;
65
+ this.filter = filter;
66
+ this.lightPush = lightPush;
67
+
68
+ if (isWakuRelay(libp2p.pubsub)) {
69
+ this.relay = libp2p.pubsub;
70
+ }
71
+
72
+ log(
73
+ "Waku node created",
74
+ this.libp2p.peerId.toString(),
75
+ `relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
76
+ .lightPush}, filter: ${!!this.filter}`
77
+ );
78
+
79
+ this.pingKeepAliveTimers = {};
80
+ this.relayKeepAliveTimers = {};
81
+
82
+ const pingKeepAlive =
83
+ options.pingKeepAlive || DefaultPingKeepAliveValueSecs;
84
+ const relayKeepAlive = this.relay
85
+ ? options.relayKeepAlive || DefaultRelayKeepAliveValueSecs
86
+ : 0;
87
+
88
+ libp2p.connectionManager.addEventListener("peer:connect", (evt) => {
89
+ this.startKeepAlive(evt.detail.remotePeer, pingKeepAlive, relayKeepAlive);
90
+ });
91
+
92
+ /**
93
+ * NOTE: Event is not being emitted on closing nor losing a connection.
94
+ * @see https://github.com/libp2p/js-libp2p/issues/939
95
+ * @see https://github.com/status-im/js-waku/issues/252
96
+ *
97
+ * >This event will be triggered anytime we are disconnected from another peer,
98
+ * >regardless of the circumstances of that disconnection.
99
+ * >If we happen to have multiple connections to a peer,
100
+ * >this event will **only** be triggered when the last connection is closed.
101
+ * @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100
102
+ */
103
+ libp2p.connectionManager.addEventListener("peer:disconnect", (evt) => {
104
+ this.stopKeepAlive(evt.detail.remotePeer);
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Dials to the provided peer.
110
+ *
111
+ * @param peer The peer to dial
112
+ * @param protocols Waku protocols we expect from the peer; Default to Relay
113
+ */
114
+ async dial(
115
+ peer: PeerId | Multiaddr,
116
+ protocols?: Protocols[]
117
+ ): Promise<Stream> {
118
+ const _protocols = protocols ?? [Protocols.Relay];
119
+
120
+ const codecs: string[] = [];
121
+ if (_protocols.includes(Protocols.Relay)) {
122
+ RelayCodecs.forEach((codec) => codecs.push(codec));
123
+ }
124
+ if (_protocols.includes(Protocols.Store)) {
125
+ codecs.push(StoreCodec);
126
+ }
127
+ if (_protocols.includes(Protocols.LightPush)) {
128
+ codecs.push(LightPushCodec);
129
+ }
130
+ if (_protocols.includes(Protocols.Filter)) {
131
+ codecs.push(FilterCodec);
132
+ }
133
+
134
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
135
+ // @ts-ignore: new Multiaddr is not backward compatible
136
+ return this.libp2p.dialProtocol(peer, codecs);
137
+ }
138
+
139
+ /**
140
+ * Add peer to address book, it will be auto-dialed in the background.
141
+ */
142
+ async addPeerToAddressBook(
143
+ peerId: PeerId | string,
144
+ multiaddrs: Multiaddr[] | string[]
145
+ ): Promise<void> {
146
+ let peer;
147
+ if (typeof peerId === "string") {
148
+ peer = peerIdFromString(peerId);
149
+ } else {
150
+ peer = peerId;
151
+ }
152
+ const addresses = multiaddrs.map((addr: Multiaddr | string) => {
153
+ if (typeof addr === "string") {
154
+ return multiaddr(addr);
155
+ } else {
156
+ return addr;
157
+ }
158
+ });
159
+ await this.libp2p.peerStore.addressBook.set(peer, addresses);
160
+ }
161
+
162
+ async start(): Promise<void> {
163
+ await this.libp2p.start();
164
+ }
165
+
166
+ async stop(): Promise<void> {
167
+ this.stopAllKeepAlives();
168
+ await this.libp2p.stop();
169
+ }
170
+
171
+ isStarted(): boolean {
172
+ return this.libp2p.isStarted();
173
+ }
174
+
175
+ /**
176
+ * Return the local multiaddr with peer id on which libp2p is listening.
177
+ *
178
+ * @throws if libp2p is not listening on localhost.
179
+ */
180
+ getLocalMultiaddrWithID(): string {
181
+ const localMultiaddr = this.libp2p
182
+ .getMultiaddrs()
183
+ .find((addr) => addr.toString().match(/127\.0\.0\.1/));
184
+ if (!localMultiaddr || localMultiaddr.toString() === "") {
185
+ throw "Not listening on localhost";
186
+ }
187
+ return localMultiaddr + "/p2p/" + this.libp2p.peerId.toString();
188
+ }
189
+
190
+ private startKeepAlive(
191
+ peerId: PeerId,
192
+ pingPeriodSecs: number,
193
+ relayPeriodSecs: number
194
+ ): void {
195
+ // Just in case a timer already exist for this peer
196
+ this.stopKeepAlive(peerId);
197
+
198
+ const peerIdStr = peerId.toString();
199
+
200
+ if (pingPeriodSecs !== 0) {
201
+ this.pingKeepAliveTimers[peerIdStr] = setInterval(() => {
202
+ this.libp2p.ping(peerId).catch((e) => {
203
+ log(`Ping failed (${peerIdStr})`, e);
204
+ });
205
+ }, pingPeriodSecs * 1000);
206
+ }
207
+
208
+ const relay = this.relay;
209
+ if (relay && relayPeriodSecs !== 0) {
210
+ const encoder = new EncoderV0(RelayPingContentTopic);
211
+ this.relayKeepAliveTimers[peerIdStr] = setInterval(() => {
212
+ log("Sending Waku Relay ping message");
213
+ relay
214
+ .send(encoder, { payload: new Uint8Array() })
215
+ .catch((e) => log("Failed to send relay ping", e));
216
+ }, relayPeriodSecs * 1000);
217
+ }
218
+ }
219
+
220
+ private stopKeepAlive(peerId: PeerId): void {
221
+ const peerIdStr = peerId.toString();
222
+
223
+ if (this.pingKeepAliveTimers[peerIdStr]) {
224
+ clearInterval(this.pingKeepAliveTimers[peerIdStr]);
225
+ delete this.pingKeepAliveTimers[peerIdStr];
226
+ }
227
+
228
+ if (this.relayKeepAliveTimers[peerIdStr]) {
229
+ clearInterval(this.relayKeepAliveTimers[peerIdStr]);
230
+ delete this.relayKeepAliveTimers[peerIdStr];
231
+ }
232
+ }
233
+
234
+ private stopAllKeepAlives(): void {
235
+ for (const timer of [
236
+ ...Object.values(this.pingKeepAliveTimers),
237
+ ...Object.values(this.relayKeepAliveTimers),
238
+ ]) {
239
+ clearInterval(timer);
240
+ }
241
+
242
+ this.pingKeepAliveTimers = {};
243
+ this.relayKeepAliveTimers = {};
244
+ }
245
+ }
246
+
247
+ function isWakuRelay(pubsub: PubSub): pubsub is WakuRelay {
248
+ if (pubsub) {
249
+ try {
250
+ return pubsub.multicodecs.includes(
251
+ relayConstants.RelayCodecs[relayConstants.RelayCodecs.length - 1]
252
+ );
253
+ // Exception is expected if `libp2p` was not instantiated with pubsub
254
+ // eslint-disable-next-line no-empty
255
+ } catch (e) {}
256
+ }
257
+ return false;
258
+ }
@@ -0,0 +1,57 @@
1
+ import { v4 as uuid } from "uuid";
2
+
3
+ import * as proto from "../../proto/filter";
4
+
5
+ export type ContentFilter = {
6
+ contentTopic: string;
7
+ };
8
+
9
+ /**
10
+ * FilterRPC represents a message conforming to the Waku Filter protocol
11
+ */
12
+ export class FilterRPC {
13
+ public constructor(public proto: proto.FilterRPC) {}
14
+
15
+ static createRequest(
16
+ topic: string,
17
+ contentFilters: ContentFilter[],
18
+ requestId?: string,
19
+ subscribe = true
20
+ ): FilterRPC {
21
+ return new FilterRPC({
22
+ requestId: requestId || uuid(),
23
+ request: {
24
+ subscribe,
25
+ topic,
26
+ contentFilters,
27
+ },
28
+ push: undefined,
29
+ });
30
+ }
31
+
32
+ /**
33
+ *
34
+ * @param bytes Uint8Array of bytes from a FilterRPC message
35
+ * @returns FilterRPC
36
+ */
37
+ static decode(bytes: Uint8Array): FilterRPC {
38
+ const res = proto.FilterRPC.decode(bytes);
39
+ return new FilterRPC(res);
40
+ }
41
+
42
+ /**
43
+ * Encode the current FilterRPC request to bytes
44
+ * @returns Uint8Array
45
+ */
46
+ encode(): Uint8Array {
47
+ return proto.FilterRPC.encode(this.proto);
48
+ }
49
+
50
+ get push(): proto.MessagePush | undefined {
51
+ return this.proto.push;
52
+ }
53
+
54
+ get requestId(): string | undefined {
55
+ return this.proto.requestId;
56
+ }
57
+ }