@waku/core 0.0.10 → 0.0.11

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 (86) hide show
  1. package/CHANGELOG.md +66 -1
  2. package/bundle/browser-2f1afe46.js +726 -0
  3. package/bundle/index.js +9166 -12074
  4. package/bundle/lib/base_protocol.js +108 -0
  5. package/bundle/lib/message/topic_only_message.js +3 -2
  6. package/bundle/lib/message/version_0.js +3 -2
  7. package/bundle/peer_exchange-1229c8b0.js +4302 -0
  8. package/bundle/{topic_only_message-b1eddea1.js → topic_only_message-e8406994.js} +12 -8
  9. package/bundle/{version_0-862a05e0.js → version_0-e9a6cfb0.js} +35 -35
  10. package/dist/.tsbuildinfo +1 -0
  11. package/dist/index.d.ts +4 -1
  12. package/dist/index.js +3 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/lib/base_protocol.d.ts +21 -0
  15. package/dist/lib/base_protocol.js +33 -0
  16. package/dist/lib/base_protocol.js.map +1 -0
  17. package/dist/lib/connection_manager.d.ts +31 -0
  18. package/dist/lib/connection_manager.js +146 -0
  19. package/dist/lib/connection_manager.js.map +1 -0
  20. package/dist/lib/filter/filter_rpc.d.ts +8 -8
  21. package/dist/lib/filter/filter_rpc.js +6 -6
  22. package/dist/lib/filter/index.d.ts +5 -22
  23. package/dist/lib/filter/index.js +31 -86
  24. package/dist/lib/filter/index.js.map +1 -1
  25. package/dist/lib/group_by.d.ts +1 -1
  26. package/dist/lib/group_by.js.map +1 -1
  27. package/dist/lib/keep_alive_manager.d.ts +17 -0
  28. package/dist/lib/keep_alive_manager.js +62 -0
  29. package/dist/lib/keep_alive_manager.js.map +1 -0
  30. package/dist/lib/light_push/index.d.ts +3 -19
  31. package/dist/lib/light_push/index.js +13 -39
  32. package/dist/lib/light_push/index.js.map +1 -1
  33. package/dist/lib/light_push/push_rpc.d.ts +5 -5
  34. package/dist/lib/light_push/push_rpc.js +6 -6
  35. package/dist/lib/message/topic_only_message.d.ts +5 -3
  36. package/dist/lib/message/topic_only_message.js +8 -5
  37. package/dist/lib/message/topic_only_message.js.map +1 -1
  38. package/dist/lib/message/version_0.d.ts +12 -12
  39. package/dist/lib/message/version_0.js +29 -30
  40. package/dist/lib/message/version_0.js.map +1 -1
  41. package/dist/lib/predefined_bootstrap_nodes.js +1 -1
  42. package/dist/lib/predefined_bootstrap_nodes.js.map +1 -1
  43. package/dist/lib/relay/index.d.ts +4 -18
  44. package/dist/lib/relay/index.js +47 -26
  45. package/dist/lib/relay/index.js.map +1 -1
  46. package/dist/lib/relay/message_validator.d.ts +4 -0
  47. package/dist/lib/relay/message_validator.js +25 -0
  48. package/dist/lib/relay/message_validator.js.map +1 -0
  49. package/dist/lib/store/history_rpc.d.ts +4 -4
  50. package/dist/lib/store/history_rpc.js +9 -9
  51. package/dist/lib/store/history_rpc.js.map +1 -1
  52. package/dist/lib/store/index.d.ts +4 -25
  53. package/dist/lib/store/index.js +20 -37
  54. package/dist/lib/store/index.js.map +1 -1
  55. package/dist/lib/to_proto_message.js +3 -2
  56. package/dist/lib/to_proto_message.js.map +1 -1
  57. package/dist/lib/wait_for_remote_peer.js +12 -23
  58. package/dist/lib/wait_for_remote_peer.js.map +1 -1
  59. package/dist/lib/waku.d.ts +8 -15
  60. package/dist/lib/waku.js +34 -97
  61. package/dist/lib/waku.js.map +1 -1
  62. package/package.json +50 -61
  63. package/src/index.ts +11 -3
  64. package/src/lib/base_protocol.ts +47 -0
  65. package/src/lib/connection_manager.ts +220 -0
  66. package/src/lib/filter/filter_rpc.ts +10 -10
  67. package/src/lib/filter/index.ts +52 -147
  68. package/src/lib/group_by.ts +1 -1
  69. package/src/lib/keep_alive_manager.ts +89 -0
  70. package/src/lib/light_push/index.ts +17 -78
  71. package/src/lib/light_push/push_rpc.ts +9 -9
  72. package/src/lib/message/topic_only_message.ts +11 -5
  73. package/src/lib/message/version_0.ts +42 -37
  74. package/src/lib/predefined_bootstrap_nodes.ts +1 -1
  75. package/src/lib/relay/index.ts +77 -52
  76. package/src/lib/relay/message_validator.ts +35 -0
  77. package/src/lib/store/history_rpc.ts +12 -12
  78. package/src/lib/store/index.ts +30 -84
  79. package/src/lib/to_proto_message.ts +3 -2
  80. package/src/lib/wait_for_remote_peer.ts +13 -29
  81. package/src/lib/waku.ts +54 -136
  82. package/bundle/peer_exchange-df95c3a7.js +0 -11801
  83. package/dist/lib/random_subset.d.ts +0 -4
  84. package/dist/lib/random_subset.js +0 -25
  85. package/dist/lib/random_subset.js.map +0 -1
  86. package/src/lib/random_subset.ts +0 -30
@@ -1,32 +1,27 @@
1
- import type { Connection } from "@libp2p/interface-connection";
2
- import type { ConnectionManager } from "@libp2p/interface-connection-manager";
1
+ import type { Stream } from "@libp2p/interface-connection";
2
+ import type { Libp2p } from "@libp2p/interface-libp2p";
3
3
  import type { PeerId } from "@libp2p/interface-peer-id";
4
- import type { Peer, PeerStore } from "@libp2p/interface-peer-store";
5
4
  import { sha256 } from "@noble/hashes/sha256";
6
- import { concat, utf8ToBytes } from "@waku/byte-utils";
7
5
  import {
8
6
  Cursor,
9
7
  IDecodedMessage,
10
8
  IDecoder,
11
- Index,
12
9
  IStore,
10
+ ProtocolCreateOptions,
13
11
  } from "@waku/interfaces";
14
- import {
15
- getPeersForProtocol,
16
- selectConnection,
17
- selectPeerForProtocol,
18
- } from "@waku/libp2p-utils";
19
12
  import { proto_store as proto } from "@waku/proto";
13
+ import { concat, utf8ToBytes } from "@waku/utils/bytes";
20
14
  import debug from "debug";
21
15
  import all from "it-all";
22
16
  import * as lp from "it-length-prefixed";
23
17
  import { pipe } from "it-pipe";
24
18
  import { Uint8ArrayList } from "uint8arraylist";
25
19
 
20
+ import { BaseProtocol } from "../base_protocol.js";
26
21
  import { DefaultPubSubTopic } from "../constants.js";
27
22
  import { toProtoMessage } from "../to_proto_message.js";
28
23
 
29
- import { HistoryRPC, PageDirection, Params } from "./history_rpc.js";
24
+ import { HistoryRpc, PageDirection, Params } from "./history_rpc.js";
30
25
 
31
26
  import HistoryError = proto.HistoryResponse.HistoryError;
32
27
 
@@ -38,23 +33,6 @@ export const DefaultPageSize = 10;
38
33
 
39
34
  export { PageDirection };
40
35
 
41
- export interface StoreComponents {
42
- peerStore: PeerStore;
43
- connectionManager: ConnectionManager;
44
- }
45
-
46
- export interface CreateOptions {
47
- /**
48
- * The PubSub Topic to use. Defaults to {@link DefaultPubSubTopic}.
49
- *
50
- * The usage of the default pubsub topic is recommended.
51
- * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details.
52
- *
53
- * @default {@link DefaultPubSubTopic}
54
- */
55
- pubSubTopic?: string;
56
- }
57
-
58
36
  export interface TimeFilter {
59
37
  startTime: Date;
60
38
  endTime: Date;
@@ -65,11 +43,6 @@ export interface QueryOptions {
65
43
  * The peer to query. If undefined, a pseudo-random peer is selected from the connected Waku Store peers.
66
44
  */
67
45
  peerId?: PeerId;
68
- /**
69
- * The pubsub topic to pass to the query.
70
- * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/).
71
- */
72
- pubSubTopic?: string;
73
46
  /**
74
47
  * The direction in which pages are retrieved:
75
48
  * - { @link PageDirection.BACKWARD }: Most recent page first.
@@ -104,11 +77,12 @@ export interface QueryOptions {
104
77
  *
105
78
  * The Waku Store protocol can be used to retrieved historical messages.
106
79
  */
107
- class Store implements IStore {
108
- pubSubTopic: string;
80
+ class Store extends BaseProtocol implements IStore {
81
+ options: ProtocolCreateOptions;
109
82
 
110
- constructor(public components: StoreComponents, options?: CreateOptions) {
111
- this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic;
83
+ constructor(public libp2p: Libp2p, options?: ProtocolCreateOptions) {
84
+ super(StoreCodec, libp2p.peerStore, libp2p.getConnections.bind(libp2p));
85
+ this.options = options ?? {};
112
86
  }
113
87
 
114
88
  /**
@@ -219,6 +193,8 @@ class Store implements IStore {
219
193
  decoders: IDecoder<T>[],
220
194
  options?: QueryOptions
221
195
  ): AsyncGenerator<Promise<T | undefined>[]> {
196
+ const { pubSubTopic = DefaultPubSubTopic } = this.options;
197
+
222
198
  let startTime, endTime;
223
199
 
224
200
  if (options?.timeFilter) {
@@ -240,7 +216,7 @@ class Store implements IStore {
240
216
 
241
217
  const queryOpts = Object.assign(
242
218
  {
243
- pubSubTopic: this.pubSubTopic,
219
+ pubSubTopic: pubSubTopic,
244
220
  pageDirection: PageDirection.BACKWARD,
245
221
  pageSize: DefaultPageSize,
246
222
  },
@@ -253,27 +229,10 @@ class Store implements IStore {
253
229
  peerId: options?.peerId?.toString(),
254
230
  });
255
231
 
256
- const res = await selectPeerForProtocol(
257
- this.components.peerStore,
258
- [StoreCodec],
259
- options?.peerId
260
- );
261
-
262
- if (!res) {
263
- throw new Error("Failed to get a peer");
264
- }
265
- const { peer, protocol } = res;
266
-
267
- const connections = this.components.connectionManager.getConnections(
268
- peer.id
269
- );
270
- const connection = selectConnection(connections);
271
-
272
- if (!connection) throw "Failed to get a connection to the peer";
232
+ const peer = await this.getPeer(options?.peerId);
273
233
 
274
234
  for await (const messages of paginate<T>(
275
- connection,
276
- protocol,
235
+ this.newStream.bind(this, peer),
277
236
  queryOpts,
278
237
  decodersAsMap,
279
238
  options?.cursor
@@ -281,23 +240,10 @@ class Store implements IStore {
281
240
  yield messages;
282
241
  }
283
242
  }
284
-
285
- /**
286
- * Returns known peers from the address book (`libp2p.peerStore`) that support
287
- * store protocol. Waku may or may not be currently connected to these peers.
288
- */
289
- async peers(): Promise<Peer[]> {
290
- return getPeersForProtocol(this.components.peerStore, [StoreCodec]);
291
- }
292
-
293
- get peerStore(): PeerStore {
294
- return this.components.peerStore;
295
- }
296
243
  }
297
244
 
298
245
  async function* paginate<T extends IDecodedMessage>(
299
- connection: Connection,
300
- protocol: string,
246
+ streamFactory: () => Promise<Stream>,
301
247
  queryOpts: Params,
302
248
  decoders: Map<string, IDecoder<T>>,
303
249
  cursor?: Cursor
@@ -315,16 +261,16 @@ async function* paginate<T extends IDecodedMessage>(
315
261
  while (true) {
316
262
  queryOpts.cursor = currentCursor;
317
263
 
318
- const stream = await connection.newStream(protocol);
319
- const historyRpcQuery = HistoryRPC.createQuery(queryOpts);
264
+ const historyRpcQuery = HistoryRpc.createQuery(queryOpts);
320
265
 
321
266
  log(
322
267
  "Querying store peer",
323
- connection.remoteAddr.toString(),
324
268
  `for (${queryOpts.pubSubTopic})`,
325
269
  queryOpts.contentTopics
326
270
  );
327
271
 
272
+ const stream = await streamFactory();
273
+
328
274
  const res = await pipe(
329
275
  [historyRpcQuery.encode()],
330
276
  lp.encode(),
@@ -347,10 +293,7 @@ async function* paginate<T extends IDecodedMessage>(
347
293
 
348
294
  const response = reply.response as proto.HistoryResponse;
349
295
 
350
- if (
351
- response.error &&
352
- response.error !== HistoryError.ERROR_NONE_UNSPECIFIED
353
- ) {
296
+ if (response.error && response.error !== HistoryError.NONE) {
354
297
  throw "History response contains an Error: " + response.error;
355
298
  }
356
299
 
@@ -368,7 +311,10 @@ async function* paginate<T extends IDecodedMessage>(
368
311
  if (typeof contentTopic !== "undefined") {
369
312
  const decoder = decoders.get(contentTopic);
370
313
  if (decoder) {
371
- return decoder.fromProtoObj(toProtoMessage(protoMsg));
314
+ return decoder.fromProtoObj(
315
+ queryOpts.pubSubTopic,
316
+ toProtoMessage(protoMsg)
317
+ );
372
318
  }
373
319
  }
374
320
  return Promise.resolve(undefined);
@@ -406,7 +352,7 @@ export function isDefined<T>(msg: T | undefined): msg is T {
406
352
  export async function createCursor(
407
353
  message: IDecodedMessage,
408
354
  pubsubTopic: string = DefaultPubSubTopic
409
- ): Promise<Index> {
355
+ ): Promise<Cursor> {
410
356
  if (
411
357
  !message ||
412
358
  !message.timestamp ||
@@ -426,12 +372,12 @@ export async function createCursor(
426
372
  digest,
427
373
  pubsubTopic,
428
374
  senderTime: messageTime,
429
- receivedTime: messageTime,
375
+ receiverTime: messageTime,
430
376
  };
431
377
  }
432
378
 
433
379
  export function wakuStore(
434
- init: Partial<CreateOptions> = {}
435
- ): (components: StoreComponents) => IStore {
436
- return (components: StoreComponents) => new Store(components, init);
380
+ init: Partial<ProtocolCreateOptions> = {}
381
+ ): (libp2p: Libp2p) => IStore {
382
+ return (libp2p: Libp2p) => new Store(libp2p, init);
437
383
  }
@@ -2,10 +2,11 @@ import { IProtoMessage } from "@waku/interfaces";
2
2
  import { WakuMessage as WakuMessageProto } from "@waku/proto";
3
3
 
4
4
  const EmptyMessage: IProtoMessage = {
5
- payload: undefined,
6
- contentTopic: undefined,
5
+ payload: new Uint8Array(),
6
+ contentTopic: "",
7
7
  version: undefined,
8
8
  timestamp: undefined,
9
+ meta: undefined,
9
10
  rateLimitProof: undefined,
10
11
  ephemeral: undefined,
11
12
  };
@@ -1,14 +1,9 @@
1
- import { PeerProtocolsChangeData } from "@libp2p/interface-peer-store";
1
+ import type { PeerProtocolsChangeData } from "@libp2p/interface-peer-store";
2
2
  import type { IRelay, PointToPointProtocol, Waku } from "@waku/interfaces";
3
3
  import { Protocols } from "@waku/interfaces";
4
- import { PeerExchangeCodec } from "@waku/peer-exchange";
5
4
  import debug from "debug";
6
5
  import { pEvent } from "p-event";
7
6
 
8
- import { FilterCodec } from "./filter/index.js";
9
- import { LightPushCodec } from "./light_push/index.js";
10
- import { StoreCodec } from "./store/index.js";
11
-
12
7
  const log = debug("waku:wait-for-remote-peer");
13
8
 
14
9
  /**
@@ -50,27 +45,19 @@ export async function waitForRemotePeer(
50
45
  if (protocols.includes(Protocols.Store)) {
51
46
  if (!waku.store)
52
47
  throw new Error("Cannot wait for Store peer: protocol not mounted");
53
- promises.push(waitForConnectedPeer(waku.store, [StoreCodec]));
48
+ promises.push(waitForConnectedPeer(waku.store));
54
49
  }
55
50
 
56
51
  if (protocols.includes(Protocols.LightPush)) {
57
52
  if (!waku.lightPush)
58
53
  throw new Error("Cannot wait for LightPush peer: protocol not mounted");
59
- promises.push(waitForConnectedPeer(waku.lightPush, [LightPushCodec]));
54
+ promises.push(waitForConnectedPeer(waku.lightPush));
60
55
  }
61
56
 
62
57
  if (protocols.includes(Protocols.Filter)) {
63
58
  if (!waku.filter)
64
59
  throw new Error("Cannot wait for Filter peer: protocol not mounted");
65
- promises.push(waitForConnectedPeer(waku.filter, [FilterCodec]));
66
- }
67
-
68
- if (protocols.includes(Protocols.PeerExchange)) {
69
- if (!waku.peerExchange)
70
- throw new Error(
71
- "Cannot wait for Peer Exchange peer: protocol not mounted"
72
- );
73
- promises.push(waitForConnectedPeer(waku.peerExchange, [PeerExchangeCodec]));
60
+ promises.push(waitForConnectedPeer(waku.filter));
74
61
  }
75
62
 
76
63
  if (timeoutMs) {
@@ -88,28 +75,25 @@ export async function waitForRemotePeer(
88
75
  * Wait for a peer with the given protocol to be connected.
89
76
  */
90
77
  async function waitForConnectedPeer(
91
- waku: PointToPointProtocol,
92
- codecs: string[]
78
+ protocol: PointToPointProtocol
93
79
  ): Promise<void> {
94
- const peers = await waku.peers();
80
+ const codec = protocol.multicodec;
81
+ const peers = await protocol.peers();
95
82
 
96
83
  if (peers.length) {
97
- log(`${codecs} peer found: `, peers[0].id.toString());
84
+ log(`${codec} peer found: `, peers[0].id.toString());
98
85
  return;
99
86
  }
100
87
 
101
88
  await new Promise<void>((resolve) => {
102
89
  const cb = (evt: CustomEvent<PeerProtocolsChangeData>): void => {
103
- for (const codec of codecs) {
104
- if (evt.detail.protocols.includes(codec)) {
105
- log("Resolving for", codec, evt.detail.protocols);
106
- waku.peerStore.removeEventListener("change:protocols", cb);
107
- resolve();
108
- break;
109
- }
90
+ if (evt.detail.protocols.includes(codec)) {
91
+ log("Resolving for", codec, evt.detail.protocols);
92
+ protocol.peerStore.removeEventListener("change:protocols", cb);
93
+ resolve();
110
94
  }
111
95
  };
112
- waku.peerStore.addEventListener("change:protocols", cb);
96
+ protocol.peerStore.addEventListener("change:protocols", cb);
113
97
  });
114
98
  }
115
99
 
package/src/lib/waku.ts CHANGED
@@ -1,27 +1,20 @@
1
1
  import type { Stream } from "@libp2p/interface-connection";
2
+ import type { Libp2p } from "@libp2p/interface-libp2p";
2
3
  import type { PeerId } from "@libp2p/interface-peer-id";
3
4
  import type { PubSub } from "@libp2p/interface-pubsub";
4
5
  import type { Multiaddr } from "@multiformats/multiaddr";
5
6
  import type {
6
7
  IFilter,
7
8
  ILightPush,
8
- IPeerExchange,
9
9
  IRelay,
10
10
  IStore,
11
- PeerExchangeComponents,
12
11
  Waku,
13
12
  } from "@waku/interfaces";
14
13
  import { Protocols } from "@waku/interfaces";
15
- import { PeerExchangeCodec } from "@waku/peer-exchange";
16
14
  import debug from "debug";
17
- import type { Libp2p } from "libp2p";
18
15
 
19
- import { FilterCodec, FilterComponents } from "./filter/index.js";
20
- import { LightPushCodec, LightPushComponents } from "./light_push/index.js";
21
- import { createEncoder } from "./message/version_0.js";
16
+ import { ConnectionManager } from "./connection_manager.js";
22
17
  import * as relayConstants from "./relay/constants.js";
23
- import { RelayCodecs, RelayPingContentTopic } from "./relay/constants.js";
24
- import { StoreCodec, StoreComponents } from "./store/index.js";
25
18
 
26
19
  export const DefaultPingKeepAliveValueSecs = 0;
27
20
  export const DefaultRelayKeepAliveValueSecs = 5 * 60;
@@ -34,19 +27,19 @@ export interface WakuOptions {
34
27
  * Set keep alive frequency in seconds: Waku will send a `/ipfs/ping/1.0.0`
35
28
  * request to each peer after the set number of seconds. Set to 0 to disable.
36
29
  *
37
- * @default {@link DefaultPingKeepAliveValueSecs}
30
+ * @default {@link @waku/core.DefaultPingKeepAliveValueSecs}
38
31
  */
39
32
  pingKeepAlive?: number;
40
33
  /**
41
34
  * Set keep alive frequency in seconds: Waku will send a ping message over
42
35
  * relay to each peer after the set number of seconds. Set to 0 to disable.
43
36
  *
44
- * @default {@link DefaultRelayKeepAliveValueSecs}
37
+ * @default {@link @waku/core.DefaultRelayKeepAliveValueSecs}
45
38
  */
46
39
  relayKeepAlive?: number;
47
40
  /**
48
41
  * Set the user agent string to be used in identification of the node.
49
- * @default {@link DefaultUserAgent}
42
+ * @default {@link @waku/core.DefaultUserAgent}
50
43
  */
51
44
  userAgent?: string;
52
45
  }
@@ -57,90 +50,52 @@ export class WakuNode implements Waku {
57
50
  public store?: IStore;
58
51
  public filter?: IFilter;
59
52
  public lightPush?: ILightPush;
60
- public peerExchange?: IPeerExchange;
61
-
62
- private pingKeepAliveTimers: {
63
- [peer: string]: ReturnType<typeof setInterval>;
64
- };
65
- private relayKeepAliveTimers: {
66
- [peer: string]: ReturnType<typeof setInterval>;
67
- };
53
+ public connectionManager: ConnectionManager;
68
54
 
69
55
  constructor(
70
56
  options: WakuOptions,
71
57
  libp2p: Libp2p,
72
- store?: (components: StoreComponents) => IStore,
73
- lightPush?: (components: LightPushComponents) => ILightPush,
74
- filter?: (components: FilterComponents) => IFilter,
75
- peerExchange?: (components: PeerExchangeComponents) => IPeerExchange
58
+ store?: (libp2p: Libp2p) => IStore,
59
+ lightPush?: (libp2p: Libp2p) => ILightPush,
60
+ filter?: (libp2p: Libp2p) => IFilter
76
61
  ) {
77
62
  this.libp2p = libp2p;
78
63
 
79
- const { peerStore, connectionManager, registrar } = libp2p;
80
- const components = { peerStore, connectionManager, registrar };
81
-
82
64
  if (store) {
83
- this.store = store(components);
65
+ this.store = store(libp2p);
84
66
  }
85
67
  if (filter) {
86
- this.filter = filter(components);
68
+ this.filter = filter(libp2p);
87
69
  }
88
70
  if (lightPush) {
89
- this.lightPush = lightPush(components);
90
- }
91
-
92
- if (peerExchange) {
93
- this.peerExchange = peerExchange(components);
71
+ this.lightPush = lightPush(libp2p);
94
72
  }
95
73
 
96
74
  if (isRelay(libp2p.pubsub)) {
97
75
  this.relay = libp2p.pubsub;
98
76
  }
99
77
 
100
- log(
101
- "Waku node created",
102
- this.libp2p.peerId.toString(),
103
- `relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
104
- .lightPush}, filter: ${!!this.filter}, peer exchange: ${!!this
105
- .peerExchange} `
106
- );
107
-
108
- this.pingKeepAliveTimers = {};
109
- this.relayKeepAliveTimers = {};
110
-
111
78
  const pingKeepAlive =
112
79
  options.pingKeepAlive || DefaultPingKeepAliveValueSecs;
113
80
  const relayKeepAlive = this.relay
114
81
  ? options.relayKeepAlive || DefaultRelayKeepAliveValueSecs
115
82
  : 0;
116
83
 
117
- libp2p.connectionManager.addEventListener("peer:connect", (evt) => {
118
- this.startKeepAlive(evt.detail.remotePeer, pingKeepAlive, relayKeepAlive);
119
- });
84
+ const peerId = this.libp2p.peerId.toString();
120
85
 
121
- /**
122
- * NOTE: Event is not being emitted on closing nor losing a connection.
123
- * @see https://github.com/libp2p/js-libp2p/issues/939
124
- * @see https://github.com/status-im/js-waku/issues/252
125
- *
126
- * >This event will be triggered anytime we are disconnected from another peer,
127
- * >regardless of the circumstances of that disconnection.
128
- * >If we happen to have multiple connections to a peer,
129
- * >this event will **only** be triggered when the last connection is closed.
130
- * @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100
131
- */
132
- libp2p.connectionManager.addEventListener("peer:disconnect", (evt) => {
133
- this.stopKeepAlive(evt.detail.remotePeer);
134
- });
86
+ this.connectionManager = ConnectionManager.create(
87
+ peerId,
88
+ libp2p,
89
+ { pingKeepAlive, relayKeepAlive },
90
+ this.relay
91
+ );
135
92
 
136
- // Trivial handling of discovered peers, to be refined.
137
- libp2p.addEventListener("peer:discovery", (evt) => {
138
- const peerId = evt.detail.id;
139
- log(`Found peer ${peerId.toString()}, dialing.`);
140
- libp2p.dial(peerId).catch((err) => {
141
- log(`Fail to dial ${peerId}`, err);
142
- });
143
- });
93
+ log(
94
+ "Waku node created",
95
+ peerId,
96
+ `relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
97
+ .lightPush}, filter: ${!!this.filter}`
98
+ );
144
99
  }
145
100
 
146
101
  /**
@@ -160,25 +115,44 @@ export class WakuNode implements Waku {
160
115
  this.store && _protocols.push(Protocols.Store);
161
116
  this.filter && _protocols.push(Protocols.Filter);
162
117
  this.lightPush && _protocols.push(Protocols.LightPush);
163
- this.peerExchange && _protocols.push(Protocols.PeerExchange);
164
118
  }
165
119
 
166
120
  const codecs: string[] = [];
167
121
  if (_protocols.includes(Protocols.Relay)) {
168
- RelayCodecs.forEach((codec) => codecs.push(codec));
122
+ if (this.relay) {
123
+ this.relay.multicodecs.forEach((codec) => codecs.push(codec));
124
+ } else {
125
+ log(
126
+ "Relay codec not included in dial codec: protocol not mounted locally"
127
+ );
128
+ }
169
129
  }
170
130
  if (_protocols.includes(Protocols.Store)) {
171
- codecs.push(StoreCodec);
131
+ if (this.store) {
132
+ codecs.push(this.store.multicodec);
133
+ } else {
134
+ log(
135
+ "Store codec not included in dial codec: protocol not mounted locally"
136
+ );
137
+ }
172
138
  }
173
139
  if (_protocols.includes(Protocols.LightPush)) {
174
- codecs.push(LightPushCodec);
140
+ if (this.lightPush) {
141
+ codecs.push(this.lightPush.multicodec);
142
+ } else {
143
+ log(
144
+ "Light Push codec not included in dial codec: protocol not mounted locally"
145
+ );
146
+ }
175
147
  }
176
148
  if (_protocols.includes(Protocols.Filter)) {
177
- codecs.push(FilterCodec);
178
- }
179
-
180
- if (_protocols.includes(Protocols.PeerExchange)) {
181
- codecs.push(PeerExchangeCodec);
149
+ if (this.filter) {
150
+ codecs.push(this.filter.multicodec);
151
+ } else {
152
+ log(
153
+ "Filter codec not included in dial codec: protocol not mounted locally"
154
+ );
155
+ }
182
156
  }
183
157
 
184
158
  log(`Dialing to ${peer.toString()} with protocols ${_protocols}`);
@@ -191,7 +165,7 @@ export class WakuNode implements Waku {
191
165
  }
192
166
 
193
167
  async stop(): Promise<void> {
194
- this.stopAllKeepAlives();
168
+ this.connectionManager.stop();
195
169
  await this.libp2p.stop();
196
170
  }
197
171
 
@@ -213,62 +187,6 @@ export class WakuNode implements Waku {
213
187
  }
214
188
  return localMultiaddr + "/p2p/" + this.libp2p.peerId.toString();
215
189
  }
216
-
217
- private startKeepAlive(
218
- peerId: PeerId,
219
- pingPeriodSecs: number,
220
- relayPeriodSecs: number
221
- ): void {
222
- // Just in case a timer already exist for this peer
223
- this.stopKeepAlive(peerId);
224
-
225
- const peerIdStr = peerId.toString();
226
-
227
- if (pingPeriodSecs !== 0) {
228
- this.pingKeepAliveTimers[peerIdStr] = setInterval(() => {
229
- this.libp2p.ping(peerId).catch((e) => {
230
- log(`Ping failed (${peerIdStr})`, e);
231
- });
232
- }, pingPeriodSecs * 1000);
233
- }
234
-
235
- const relay = this.relay;
236
- if (relay && relayPeriodSecs !== 0) {
237
- const encoder = createEncoder(RelayPingContentTopic, true);
238
- this.relayKeepAliveTimers[peerIdStr] = setInterval(() => {
239
- log("Sending Waku Relay ping message");
240
- relay
241
- .send(encoder, { payload: new Uint8Array() })
242
- .catch((e) => log("Failed to send relay ping", e));
243
- }, relayPeriodSecs * 1000);
244
- }
245
- }
246
-
247
- private stopKeepAlive(peerId: PeerId): void {
248
- const peerIdStr = peerId.toString();
249
-
250
- if (this.pingKeepAliveTimers[peerIdStr]) {
251
- clearInterval(this.pingKeepAliveTimers[peerIdStr]);
252
- delete this.pingKeepAliveTimers[peerIdStr];
253
- }
254
-
255
- if (this.relayKeepAliveTimers[peerIdStr]) {
256
- clearInterval(this.relayKeepAliveTimers[peerIdStr]);
257
- delete this.relayKeepAliveTimers[peerIdStr];
258
- }
259
- }
260
-
261
- private stopAllKeepAlives(): void {
262
- for (const timer of [
263
- ...Object.values(this.pingKeepAliveTimers),
264
- ...Object.values(this.relayKeepAliveTimers),
265
- ]) {
266
- clearInterval(timer);
267
- }
268
-
269
- this.pingKeepAliveTimers = {};
270
- this.relayKeepAliveTimers = {};
271
- }
272
190
  }
273
191
 
274
192
  function isRelay(pubsub: PubSub): pubsub is IRelay {