@waku/core 0.0.19 → 0.0.21

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 (60) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/bundle/index.js +404 -350
  3. package/bundle/lib/base_protocol.js +11 -6
  4. package/bundle/lib/message/version_0.js +1 -1
  5. package/bundle/lib/predefined_bootstrap_nodes.js +6 -6
  6. package/bundle/{version_0-9c941081.js → version_0-86411fdf.js} +3 -3
  7. package/dist/index.d.ts +2 -4
  8. package/dist/index.js +2 -4
  9. package/dist/index.js.map +1 -1
  10. package/dist/lib/base_protocol.d.ts +9 -5
  11. package/dist/lib/base_protocol.js +11 -6
  12. package/dist/lib/base_protocol.js.map +1 -1
  13. package/dist/lib/connection_manager.d.ts +14 -4
  14. package/dist/lib/connection_manager.js +174 -28
  15. package/dist/lib/connection_manager.js.map +1 -1
  16. package/dist/lib/filter/filter_rpc.js.map +1 -0
  17. package/dist/lib/filter/index.d.ts +2 -0
  18. package/dist/lib/filter/{v2/index.js → index.js} +14 -19
  19. package/dist/lib/filter/index.js.map +1 -0
  20. package/dist/lib/keep_alive_manager.d.ts +2 -2
  21. package/dist/lib/keep_alive_manager.js +1 -1
  22. package/dist/lib/keep_alive_manager.js.map +1 -1
  23. package/dist/lib/light_push/index.d.ts +1 -2
  24. package/dist/lib/light_push/index.js +1 -3
  25. package/dist/lib/light_push/index.js.map +1 -1
  26. package/dist/lib/predefined_bootstrap_nodes.js +6 -6
  27. package/dist/lib/predefined_bootstrap_nodes.js.map +1 -1
  28. package/dist/lib/store/index.d.ts +1 -2
  29. package/dist/lib/store/index.js +1 -3
  30. package/dist/lib/store/index.js.map +1 -1
  31. package/dist/lib/wait_for_remote_peer.d.ts +1 -1
  32. package/dist/lib/wait_for_remote_peer.js +4 -4
  33. package/dist/lib/wait_for_remote_peer.js.map +1 -1
  34. package/dist/lib/waku.d.ts +3 -4
  35. package/dist/lib/waku.js.map +1 -1
  36. package/package.json +11 -19
  37. package/src/index.ts +2 -5
  38. package/src/lib/base_protocol.ts +23 -9
  39. package/src/lib/connection_manager.ts +230 -42
  40. package/src/lib/filter/{v2/index.ts → index.ts} +19 -26
  41. package/src/lib/keep_alive_manager.ts +3 -3
  42. package/src/lib/light_push/index.ts +3 -3
  43. package/src/lib/predefined_bootstrap_nodes.ts +6 -6
  44. package/src/lib/store/index.ts +3 -3
  45. package/src/lib/wait_for_remote_peer.ts +8 -10
  46. package/src/lib/waku.ts +3 -4
  47. package/dist/lib/filter/v1/filter_rpc.d.ts +0 -23
  48. package/dist/lib/filter/v1/filter_rpc.js +0 -45
  49. package/dist/lib/filter/v1/filter_rpc.js.map +0 -1
  50. package/dist/lib/filter/v1/index.d.ts +0 -6
  51. package/dist/lib/filter/v1/index.js +0 -153
  52. package/dist/lib/filter/v1/index.js.map +0 -1
  53. package/dist/lib/filter/v2/filter_rpc.js.map +0 -1
  54. package/dist/lib/filter/v2/index.d.ts +0 -3
  55. package/dist/lib/filter/v2/index.js.map +0 -1
  56. package/src/lib/filter/v1/filter_rpc.ts +0 -53
  57. package/src/lib/filter/v1/index.ts +0 -248
  58. /package/dist/lib/filter/{v2/filter_rpc.d.ts → filter_rpc.d.ts} +0 -0
  59. /package/dist/lib/filter/{v2/filter_rpc.js → filter_rpc.js} +0 -0
  60. /package/src/lib/filter/{v2/filter_rpc.ts → filter_rpc.ts} +0 -0
package/bundle/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { g as getDefaultExportFromCjs, d as debug } from './browser-bde977a3.js';
2
- import { c as createEncoder, v as version_0, F as FilterRpc$1, M as MessagePush, a as FilterSubscribeRequest, b as FilterSubscribeResponse$1, P as PushRpc$1, d as PushResponse, H as HistoryRpc$1, e as PagingInfo, f as HistoryResponse } from './version_0-9c941081.js';
3
- export { g as createDecoder } from './version_0-9c941081.js';
2
+ import { c as createEncoder, v as version_0, M as MessagePush, F as FilterSubscribeRequest, a as FilterSubscribeResponse$1, P as PushRpc$1, b as PushResponse, H as HistoryRpc$1, d as PagingInfo, e as HistoryResponse } from './version_0-86411fdf.js';
3
+ export { f as createDecoder } from './version_0-86411fdf.js';
4
4
  import { BaseProtocol } from './lib/base_protocol.js';
5
5
 
6
6
  const symbol$2 = Symbol.for('@libp2p/peer-id');
@@ -1891,7 +1891,7 @@ const BASES = {
1891
1891
  'utf-8': string,
1892
1892
  hex: bases.base16,
1893
1893
  latin1: ascii,
1894
- ascii: ascii,
1894
+ ascii,
1895
1895
  binary: ascii,
1896
1896
  ...bases
1897
1897
  };
@@ -2608,6 +2608,8 @@ function protoFromTuple(tup) {
2608
2608
  * AbortSignal.
2609
2609
  */
2610
2610
  class CodeError extends Error {
2611
+ code;
2612
+ props;
2611
2613
  constructor(message, code, props) {
2612
2614
  super(message);
2613
2615
  this.code = code;
@@ -2973,9 +2975,86 @@ var Tags;
2973
2975
  Tags["BOOTSTRAP"] = "bootstrap";
2974
2976
  Tags["PEER_EXCHANGE"] = "peer-exchange";
2975
2977
  })(Tags || (Tags = {}));
2978
+ var EPeersByDiscoveryEvents;
2979
+ (function (EPeersByDiscoveryEvents) {
2980
+ EPeersByDiscoveryEvents["PEER_DISCOVERY_BOOTSTRAP"] = "peer:discovery:bootstrap";
2981
+ EPeersByDiscoveryEvents["PEER_DISCOVERY_PEER_EXCHANGE"] = "peer:discovery:peer-exchange";
2982
+ EPeersByDiscoveryEvents["PEER_CONNECT_BOOTSTRAP"] = "peer:connected:bootstrap";
2983
+ EPeersByDiscoveryEvents["PEER_CONNECT_PEER_EXCHANGE"] = "peer:connected:peer-exchange";
2984
+ })(EPeersByDiscoveryEvents || (EPeersByDiscoveryEvents = {}));
2985
+
2986
+ /**
2987
+ * Adds types to the EventTarget class. Hopefully this won't be necessary forever.
2988
+ *
2989
+ * https://github.com/microsoft/TypeScript/issues/28357
2990
+ * https://github.com/microsoft/TypeScript/issues/43477
2991
+ * https://github.com/microsoft/TypeScript/issues/299
2992
+ * etc
2993
+ */
2994
+ class EventEmitter extends EventTarget {
2995
+ #listeners = new Map();
2996
+ listenerCount(type) {
2997
+ const listeners = this.#listeners.get(type);
2998
+ if (listeners == null) {
2999
+ return 0;
3000
+ }
3001
+ return listeners.length;
3002
+ }
3003
+ addEventListener(type, listener, options) {
3004
+ super.addEventListener(type, listener, options);
3005
+ let list = this.#listeners.get(type);
3006
+ if (list == null) {
3007
+ list = [];
3008
+ this.#listeners.set(type, list);
3009
+ }
3010
+ list.push({
3011
+ callback: listener,
3012
+ once: (options !== true && options !== false && options?.once) ?? false
3013
+ });
3014
+ }
3015
+ removeEventListener(type, listener, options) {
3016
+ super.removeEventListener(type.toString(), listener ?? null, options);
3017
+ let list = this.#listeners.get(type);
3018
+ if (list == null) {
3019
+ return;
3020
+ }
3021
+ list = list.filter(({ callback }) => callback !== listener);
3022
+ this.#listeners.set(type, list);
3023
+ }
3024
+ dispatchEvent(event) {
3025
+ const result = super.dispatchEvent(event);
3026
+ let list = this.#listeners.get(event.type);
3027
+ if (list == null) {
3028
+ return result;
3029
+ }
3030
+ list = list.filter(({ once }) => !once);
3031
+ this.#listeners.set(event.type, list);
3032
+ return result;
3033
+ }
3034
+ safeDispatchEvent(type, detail) {
3035
+ return this.dispatchEvent(new CustomEvent(type, detail));
3036
+ }
3037
+ }
3038
+ /**
3039
+ * CustomEvent is a standard event but it's not supported by node.
3040
+ *
3041
+ * Remove this when https://github.com/nodejs/node/issues/40678 is closed.
3042
+ *
3043
+ * Ref: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent
3044
+ */
3045
+ class CustomEventPolyfill extends Event {
3046
+ /** Returns any custom data event was created with. Typically used for synthetic events. */
3047
+ detail;
3048
+ constructor(message, data) {
3049
+ super(message, data);
3050
+ // @ts-expect-error could be undefined
3051
+ this.detail = data?.detail;
3052
+ }
3053
+ }
3054
+ const CustomEvent = globalThis.CustomEvent ?? CustomEventPolyfill;
2976
3055
 
2977
3056
  const RelayPingContentTopic = "/relay-ping/1/ping/null";
2978
- const log$7 = debug("waku:keep-alive");
3057
+ const log$6 = debug("waku:keep-alive");
2979
3058
  class KeepAliveManager {
2980
3059
  pingKeepAliveTimers;
2981
3060
  relayKeepAliveTimers;
@@ -2994,8 +3073,8 @@ class KeepAliveManager {
2994
3073
  const peerIdStr = peerId.toString();
2995
3074
  if (pingPeriodSecs !== 0) {
2996
3075
  const interval = setInterval(() => {
2997
- libp2pPing(peerId).catch((e) => {
2998
- log$7(`Ping failed (${peerIdStr})`, e);
3076
+ libp2pPing.ping(peerId).catch((e) => {
3077
+ log$6(`Ping failed (${peerIdStr})`, e);
2999
3078
  });
3000
3079
  }, pingPeriodSecs * 1000);
3001
3080
  this.pingKeepAliveTimers.set(peerIdStr, interval);
@@ -3007,10 +3086,10 @@ class KeepAliveManager {
3007
3086
  ephemeral: true,
3008
3087
  });
3009
3088
  const interval = setInterval(() => {
3010
- log$7("Sending Waku Relay ping message");
3089
+ log$6("Sending Waku Relay ping message");
3011
3090
  relay
3012
3091
  .send(encoder, { payload: new Uint8Array([1]) })
3013
- .catch((e) => log$7("Failed to send relay ping", e));
3092
+ .catch((e) => log$6("Failed to send relay ping", e));
3014
3093
  }, relayPeriodSecs * 1000);
3015
3094
  this.relayKeepAliveTimers.set(peerId, interval);
3016
3095
  }
@@ -3038,16 +3117,19 @@ class KeepAliveManager {
3038
3117
  }
3039
3118
  }
3040
3119
 
3041
- const log$6 = debug("waku:connection-manager");
3120
+ const log$5 = debug("waku:connection-manager");
3042
3121
  const DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED = 1;
3043
3122
  const DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER = 3;
3044
- class ConnectionManager {
3123
+ const DEFAULT_MAX_PARALLEL_DIALS = 3;
3124
+ class ConnectionManager extends EventEmitter {
3045
3125
  static instances = new Map();
3046
3126
  keepAliveManager;
3047
3127
  options;
3048
- libp2pComponents;
3128
+ libp2p;
3049
3129
  dialAttemptsForPeer = new Map();
3050
3130
  dialErrorsForPeer = new Map();
3131
+ currentActiveDialCount = 0;
3132
+ pendingPeerDialQueue = [];
3051
3133
  static create(peerId, libp2p, keepAliveOptions, relay, options) {
3052
3134
  let instance = ConnectionManager.instances.get(peerId);
3053
3135
  if (!instance) {
@@ -3056,17 +3138,77 @@ class ConnectionManager {
3056
3138
  }
3057
3139
  return instance;
3058
3140
  }
3059
- constructor(libp2pComponents, keepAliveOptions, relay, options) {
3060
- this.libp2pComponents = libp2pComponents;
3141
+ async getPeersByDiscovery() {
3142
+ const peersDiscovered = await this.libp2p.peerStore.all();
3143
+ const peersConnected = this.libp2p
3144
+ .getConnections()
3145
+ .map((conn) => conn.remotePeer);
3146
+ const peersDiscoveredByBootstrap = [];
3147
+ const peersDiscoveredByPeerExchange = [];
3148
+ const peersConnectedByBootstrap = [];
3149
+ const peersConnectedByPeerExchange = [];
3150
+ for (const peer of peersDiscovered) {
3151
+ const tags = await this.getTagNamesForPeer(peer.id);
3152
+ if (tags.includes(Tags.BOOTSTRAP)) {
3153
+ peersDiscoveredByBootstrap.push(peer);
3154
+ }
3155
+ else if (tags.includes(Tags.PEER_EXCHANGE)) {
3156
+ peersDiscoveredByPeerExchange.push(peer);
3157
+ }
3158
+ }
3159
+ for (const peerId of peersConnected) {
3160
+ const peer = await this.libp2p.peerStore.get(peerId);
3161
+ const tags = await this.getTagNamesForPeer(peerId);
3162
+ if (tags.includes(Tags.BOOTSTRAP)) {
3163
+ peersConnectedByBootstrap.push(peer);
3164
+ }
3165
+ else if (tags.includes(Tags.PEER_EXCHANGE)) {
3166
+ peersConnectedByPeerExchange.push(peer);
3167
+ }
3168
+ }
3169
+ return {
3170
+ DISCOVERED: {
3171
+ [Tags.BOOTSTRAP]: peersDiscoveredByBootstrap,
3172
+ [Tags.PEER_EXCHANGE]: peersDiscoveredByPeerExchange,
3173
+ },
3174
+ CONNECTED: {
3175
+ [Tags.BOOTSTRAP]: peersConnectedByBootstrap,
3176
+ [Tags.PEER_EXCHANGE]: peersConnectedByPeerExchange,
3177
+ },
3178
+ };
3179
+ }
3180
+ constructor(libp2p, keepAliveOptions, relay, options) {
3181
+ super();
3182
+ this.libp2p = libp2p;
3061
3183
  this.options = {
3062
3184
  maxDialAttemptsForPeer: DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER,
3063
3185
  maxBootstrapPeersAllowed: DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED,
3186
+ maxParallelDials: DEFAULT_MAX_PARALLEL_DIALS,
3064
3187
  ...options,
3065
3188
  };
3066
3189
  this.keepAliveManager = new KeepAliveManager(keepAliveOptions, relay);
3067
3190
  this.run()
3068
- .then(() => log$6(`Connection Manager is now running`))
3069
- .catch((error) => log$6(`Unexpected error while running service`, error));
3191
+ .then(() => log$5(`Connection Manager is now running`))
3192
+ .catch((error) => log$5(`Unexpected error while running service`, error));
3193
+ // libp2p emits `peer:discovery` events during its initialization
3194
+ // which means that before the ConnectionManager is initialized, some peers may have been discovered
3195
+ // we will dial the peers in peerStore ONCE before we start to listen to the `peer:discovery` events within the ConnectionManager
3196
+ this.dialPeerStorePeers().catch((error) => log$5(`Unexpected error while dialing peer store peers`, error));
3197
+ }
3198
+ async dialPeerStorePeers() {
3199
+ const peerInfos = await this.libp2p.peerStore.all();
3200
+ const dialPromises = [];
3201
+ for (const peerInfo of peerInfos) {
3202
+ if (this.libp2p.getConnections().find((c) => c.remotePeer === peerInfo.id))
3203
+ continue;
3204
+ dialPromises.push(this.attemptDial(peerInfo.id));
3205
+ }
3206
+ try {
3207
+ await Promise.all(dialPromises);
3208
+ }
3209
+ catch (error) {
3210
+ log$5(`Unexpected error while dialing peer store peers`, error);
3211
+ }
3070
3212
  }
3071
3213
  async run() {
3072
3214
  // start event listeners
@@ -3076,20 +3218,21 @@ class ConnectionManager {
3076
3218
  }
3077
3219
  stop() {
3078
3220
  this.keepAliveManager.stopAll();
3079
- this.libp2pComponents.removeEventListener("peer:connect", this.onEventHandlers["peer:connect"]);
3080
- this.libp2pComponents.removeEventListener("peer:disconnect", this.onEventHandlers["peer:disconnect"]);
3081
- this.libp2pComponents.removeEventListener("peer:discovery", this.onEventHandlers["peer:discovery"]);
3221
+ this.libp2p.removeEventListener("peer:connect", this.onEventHandlers["peer:connect"]);
3222
+ this.libp2p.removeEventListener("peer:disconnect", this.onEventHandlers["peer:disconnect"]);
3223
+ this.libp2p.removeEventListener("peer:discovery", this.onEventHandlers["peer:discovery"]);
3082
3224
  }
3083
3225
  async dialPeer(peerId) {
3226
+ this.currentActiveDialCount += 1;
3084
3227
  let dialAttempt = 0;
3085
3228
  while (dialAttempt <= this.options.maxDialAttemptsForPeer) {
3086
3229
  try {
3087
- log$6(`Dialing peer ${peerId.toString()}`);
3088
- await this.libp2pComponents.dial(peerId);
3230
+ log$5(`Dialing peer ${peerId.toString()}`);
3231
+ await this.libp2p.dial(peerId);
3089
3232
  const tags = await this.getTagNamesForPeer(peerId);
3090
3233
  // add tag to connection describing discovery mechanism
3091
3234
  // don't add duplicate tags
3092
- this.libp2pComponents
3235
+ this.libp2p
3093
3236
  .getConnections(peerId)
3094
3237
  .forEach((conn) => (conn.tags = Array.from(new Set([...conn.tags, ...tags]))));
3095
3238
  this.dialAttemptsForPeer.delete(peerId.toString());
@@ -3098,29 +3241,54 @@ class ConnectionManager {
3098
3241
  catch (e) {
3099
3242
  const error = e;
3100
3243
  this.dialErrorsForPeer.set(peerId.toString(), error);
3101
- log$6(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
3244
+ log$5(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
3102
3245
  dialAttempt = this.dialAttemptsForPeer.get(peerId.toString()) ?? 1;
3103
3246
  this.dialAttemptsForPeer.set(peerId.toString(), dialAttempt + 1);
3104
3247
  if (dialAttempt <= this.options.maxDialAttemptsForPeer) {
3105
- log$6(`Reattempting dial (${dialAttempt})`);
3248
+ log$5(`Reattempting dial (${dialAttempt})`);
3106
3249
  }
3107
3250
  }
3108
3251
  }
3109
3252
  try {
3110
- log$6(`Deleting undialable peer ${peerId.toString()} from peer store. Error: ${JSON.stringify(this.dialErrorsForPeer.get(peerId.toString()).errors[0])}
3253
+ log$5(`Deleting undialable peer ${peerId.toString()} from peer store. Error: ${JSON.stringify(this.dialErrorsForPeer.get(peerId.toString()).errors[0])}
3111
3254
  }`);
3112
3255
  this.dialErrorsForPeer.delete(peerId.toString());
3113
- return await this.libp2pComponents.peerStore.delete(peerId);
3256
+ return await this.libp2p.peerStore.delete(peerId);
3114
3257
  }
3115
3258
  catch (error) {
3116
3259
  throw `Error deleting undialable peer ${peerId.toString()} from peer store - ${error}`;
3117
3260
  }
3261
+ finally {
3262
+ this.currentActiveDialCount -= 1;
3263
+ this.processDialQueue();
3264
+ }
3265
+ }
3266
+ async dropConnection(peerId) {
3267
+ try {
3268
+ this.keepAliveManager.stop(peerId);
3269
+ await this.libp2p.hangUp(peerId);
3270
+ log$5(`Dropped connection with peer ${peerId.toString()}`);
3271
+ }
3272
+ catch (error) {
3273
+ log$5(`Error dropping connection with peer ${peerId.toString()} - ${error}`);
3274
+ }
3275
+ }
3276
+ processDialQueue() {
3277
+ if (this.pendingPeerDialQueue.length > 0 &&
3278
+ this.currentActiveDialCount < this.options.maxParallelDials) {
3279
+ const peerId = this.pendingPeerDialQueue.shift();
3280
+ if (!peerId)
3281
+ return;
3282
+ this.attemptDial(peerId).catch((error) => {
3283
+ log$5(error);
3284
+ });
3285
+ }
3118
3286
  }
3119
3287
  startPeerDiscoveryListener() {
3120
- this.libp2pComponents.peerStore.addEventListener("peer", this.onEventHandlers["peer:discovery"]);
3288
+ this.libp2p.addEventListener("peer:discovery", this.onEventHandlers["peer:discovery"]);
3121
3289
  }
3122
3290
  startPeerConnectionListener() {
3123
- this.libp2pComponents.addEventListener("peer:connect", this.onEventHandlers["peer:connect"]);
3291
+ this.libp2p.addEventListener("peer:connect", this.onEventHandlers["peer:connect"]);
3124
3292
  }
3125
3293
  startPeerDisconnectionListener() {
3126
3294
  // TODO: ensure that these following issues are updated and confirmed
@@ -3135,23 +3303,71 @@ class ConnectionManager {
3135
3303
  * >this event will **only** be triggered when the last connection is closed.
3136
3304
  * @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100
3137
3305
  */
3138
- this.libp2pComponents.addEventListener("peer:disconnect", this.onEventHandlers["peer:disconnect"]);
3306
+ this.libp2p.addEventListener("peer:disconnect", this.onEventHandlers["peer:disconnect"]);
3307
+ }
3308
+ async attemptDial(peerId) {
3309
+ if (this.currentActiveDialCount >= this.options.maxParallelDials) {
3310
+ this.pendingPeerDialQueue.push(peerId);
3311
+ return;
3312
+ }
3313
+ if (!(await this.shouldDialPeer(peerId)))
3314
+ return;
3315
+ this.dialPeer(peerId).catch((err) => {
3316
+ throw `Error dialing peer ${peerId.toString()} : ${err}`;
3317
+ });
3139
3318
  }
3140
3319
  onEventHandlers = {
3141
- "peer:discovery": async (evt) => {
3142
- const { id: peerId } = evt.detail;
3143
- if (!(await this.shouldDialPeer(peerId)))
3144
- return;
3145
- this.dialPeer(peerId).catch((err) => log$6(`Error dialing peer ${peerId.toString()} : ${err}`));
3320
+ "peer:discovery": (evt) => {
3321
+ void (async () => {
3322
+ const { id: peerId } = evt.detail;
3323
+ const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(Tags.BOOTSTRAP);
3324
+ if (isBootstrap) {
3325
+ this.dispatchEvent(new CustomEvent(EPeersByDiscoveryEvents.PEER_DISCOVERY_BOOTSTRAP, {
3326
+ detail: peerId,
3327
+ }));
3328
+ }
3329
+ else {
3330
+ this.dispatchEvent(new CustomEvent(EPeersByDiscoveryEvents.PEER_DISCOVERY_PEER_EXCHANGE, {
3331
+ detail: peerId,
3332
+ }));
3333
+ }
3334
+ try {
3335
+ await this.attemptDial(peerId);
3336
+ }
3337
+ catch (error) {
3338
+ log$5(`Error dialing peer ${peerId.toString()} : ${error}`);
3339
+ }
3340
+ })();
3146
3341
  },
3147
3342
  "peer:connect": (evt) => {
3148
- {
3149
- this.keepAliveManager.start(evt.detail.remotePeer, this.libp2pComponents.ping.bind(this));
3150
- }
3343
+ void (async () => {
3344
+ const peerId = evt.detail;
3345
+ this.keepAliveManager.start(peerId, this.libp2p.services.ping);
3346
+ const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(Tags.BOOTSTRAP);
3347
+ if (isBootstrap) {
3348
+ const bootstrapConnections = this.libp2p
3349
+ .getConnections()
3350
+ .filter((conn) => conn.tags.includes(Tags.BOOTSTRAP));
3351
+ // If we have too many bootstrap connections, drop one
3352
+ if (bootstrapConnections.length > this.options.maxBootstrapPeersAllowed) {
3353
+ await this.dropConnection(peerId);
3354
+ }
3355
+ else {
3356
+ this.dispatchEvent(new CustomEvent(EPeersByDiscoveryEvents.PEER_CONNECT_BOOTSTRAP, {
3357
+ detail: peerId,
3358
+ }));
3359
+ }
3360
+ }
3361
+ else {
3362
+ this.dispatchEvent(new CustomEvent(EPeersByDiscoveryEvents.PEER_CONNECT_PEER_EXCHANGE, {
3363
+ detail: peerId,
3364
+ }));
3365
+ }
3366
+ })();
3151
3367
  },
3152
3368
  "peer:disconnect": () => {
3153
3369
  return (evt) => {
3154
- this.keepAliveManager.stop(evt.detail.remotePeer);
3370
+ this.keepAliveManager.stop(evt.detail);
3155
3371
  };
3156
3372
  },
3157
3373
  };
@@ -3161,15 +3377,16 @@ class ConnectionManager {
3161
3377
  * 2. If the peer is not a bootstrap peer
3162
3378
  */
3163
3379
  async shouldDialPeer(peerId) {
3164
- const isConnected = this.libp2pComponents.getConnections(peerId).length > 0;
3380
+ const isConnected = this.libp2p.getConnections(peerId).length > 0;
3165
3381
  if (isConnected)
3166
3382
  return false;
3167
- const isBootstrap = (await this.getTagNamesForPeer(peerId)).some((tagName) => tagName === Tags.BOOTSTRAP);
3383
+ const tagNames = await this.getTagNamesForPeer(peerId);
3384
+ const isBootstrap = tagNames.some((tagName) => tagName === Tags.BOOTSTRAP);
3168
3385
  if (isBootstrap) {
3169
- const currentBootstrapConnections = this.libp2pComponents
3386
+ const currentBootstrapConnections = this.libp2p
3170
3387
  .getConnections()
3171
3388
  .filter((conn) => {
3172
- conn.tags.find((name) => name === Tags.BOOTSTRAP);
3389
+ return conn.tags.find((name) => name === Tags.BOOTSTRAP);
3173
3390
  }).length;
3174
3391
  if (currentBootstrapConnections < this.options.maxBootstrapPeersAllowed)
3175
3392
  return true;
@@ -3183,15 +3400,21 @@ class ConnectionManager {
3183
3400
  * Fetches the tag names for a given peer
3184
3401
  */
3185
3402
  async getTagNamesForPeer(peerId) {
3186
- const tags = (await this.libp2pComponents.peerStore.getTags(peerId)).map((tag) => tag.name);
3187
- return tags;
3403
+ try {
3404
+ const peer = await this.libp2p.peerStore.get(peerId);
3405
+ return Array.from(peer.tags.keys());
3406
+ }
3407
+ catch (error) {
3408
+ log$5(`Failed to get peer ${peerId}, error: ${error}`);
3409
+ return [];
3410
+ }
3188
3411
  }
3189
3412
  }
3190
3413
 
3191
3414
  const DefaultPingKeepAliveValueSecs = 0;
3192
3415
  const DefaultRelayKeepAliveValueSecs = 5 * 60;
3193
3416
  const DefaultUserAgent = "js-waku";
3194
- const log$5 = debug("waku:waku");
3417
+ const log$4 = debug("waku:waku");
3195
3418
  class WakuNode {
3196
3419
  libp2p;
3197
3420
  relay;
@@ -3219,7 +3442,7 @@ class WakuNode {
3219
3442
  : 0;
3220
3443
  const peerId = this.libp2p.peerId.toString();
3221
3444
  this.connectionManager = ConnectionManager.create(peerId, libp2p, { pingKeepAlive, relayKeepAlive }, this.relay);
3222
- log$5("Waku node created", peerId, `relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
3445
+ log$4("Waku node created", peerId, `relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
3223
3446
  .lightPush}, filter: ${!!this.filter}`);
3224
3447
  }
3225
3448
  /**
@@ -3243,7 +3466,7 @@ class WakuNode {
3243
3466
  this.relay.gossipSub.multicodecs.forEach((codec) => codecs.push(codec));
3244
3467
  }
3245
3468
  else {
3246
- log$5("Relay codec not included in dial codec: protocol not mounted locally");
3469
+ log$4("Relay codec not included in dial codec: protocol not mounted locally");
3247
3470
  }
3248
3471
  }
3249
3472
  if (_protocols.includes(Protocols.Store)) {
@@ -3251,7 +3474,7 @@ class WakuNode {
3251
3474
  codecs.push(this.store.multicodec);
3252
3475
  }
3253
3476
  else {
3254
- log$5("Store codec not included in dial codec: protocol not mounted locally");
3477
+ log$4("Store codec not included in dial codec: protocol not mounted locally");
3255
3478
  }
3256
3479
  }
3257
3480
  if (_protocols.includes(Protocols.LightPush)) {
@@ -3259,7 +3482,7 @@ class WakuNode {
3259
3482
  codecs.push(this.lightPush.multicodec);
3260
3483
  }
3261
3484
  else {
3262
- log$5("Light Push codec not included in dial codec: protocol not mounted locally");
3485
+ log$4("Light Push codec not included in dial codec: protocol not mounted locally");
3263
3486
  }
3264
3487
  }
3265
3488
  if (_protocols.includes(Protocols.Filter)) {
@@ -3267,10 +3490,10 @@ class WakuNode {
3267
3490
  codecs.push(this.filter.multicodec);
3268
3491
  }
3269
3492
  else {
3270
- log$5("Filter codec not included in dial codec: protocol not mounted locally");
3493
+ log$4("Filter codec not included in dial codec: protocol not mounted locally");
3271
3494
  }
3272
3495
  }
3273
- log$5(`Dialing to ${peerId.toString()} with protocols ${_protocols}`);
3496
+ log$4(`Dialing to ${peerId.toString()} with protocols ${_protocols}`);
3274
3497
  return this.libp2p.dialProtocol(peerId, codecs);
3275
3498
  }
3276
3499
  async start() {
@@ -3315,7 +3538,7 @@ var waku = /*#__PURE__*/Object.freeze({
3315
3538
  */
3316
3539
  const DefaultPubSubTopic = "/waku/2/default-waku/proto";
3317
3540
 
3318
- var index$4 = /*#__PURE__*/Object.freeze({
3541
+ var index$3 = /*#__PURE__*/Object.freeze({
3319
3542
  __proto__: null,
3320
3543
  version_0: version_0
3321
3544
  });
@@ -3397,11 +3620,11 @@ const isSizeValid = (payload) => {
3397
3620
  return true;
3398
3621
  };
3399
3622
 
3400
- function isAsyncIterable$1(thing) {
3623
+ function isAsyncIterable$3(thing) {
3401
3624
  return thing[Symbol.asyncIterator] != null;
3402
3625
  }
3403
3626
  function all(source) {
3404
- if (isAsyncIterable$1(source)) {
3627
+ if (isAsyncIterable$3(source)) {
3405
3628
  return (async () => {
3406
3629
  const arr = [];
3407
3630
  for await (const entry of source) {
@@ -4158,7 +4381,7 @@ const unsigned = {
4158
4381
  }
4159
4382
  };
4160
4383
 
4161
- function isAsyncIterable(thing) {
4384
+ function isAsyncIterable$2(thing) {
4162
4385
  return thing[Symbol.asyncIterator] != null;
4163
4386
  }
4164
4387
 
@@ -4191,7 +4414,7 @@ function encode(source, options) {
4191
4414
  yield* chunk;
4192
4415
  }
4193
4416
  }
4194
- if (isAsyncIterable(source)) {
4417
+ if (isAsyncIterable$2(source)) {
4195
4418
  return (async function* () {
4196
4419
  for await (const chunk of source) {
4197
4420
  yield* maybeYield(chunk);
@@ -4347,7 +4570,7 @@ function decode(source, options) {
4347
4570
  }
4348
4571
  }
4349
4572
  }
4350
- if (isAsyncIterable(source)) {
4573
+ if (isAsyncIterable$2(source)) {
4351
4574
  return (async function* () {
4352
4575
  for await (const buf of source) {
4353
4576
  buffer.append(buf);
@@ -4662,77 +4885,56 @@ function _pushable(getNext, options) {
4662
4885
  return pushable;
4663
4886
  }
4664
4887
 
4665
- /**
4666
- * Treat one or more iterables as a single iterable.
4667
- *
4668
- * Nb. sources are iterated over in parallel so the
4669
- * order of emitted items is not guaranteed.
4670
- */
4671
- async function* merge(...sources) {
4672
- const output = pushable({
4673
- objectMode: true
4674
- });
4675
- void Promise.resolve().then(async () => {
4676
- try {
4677
- await Promise.all(sources.map(async (source) => {
4678
- for await (const item of source) {
4679
- output.push(item);
4680
- }
4681
- }));
4682
- output.end();
4683
- }
4684
- catch (err) {
4685
- output.end(err);
4888
+ function isAsyncIterable$1(thing) {
4889
+ return thing[Symbol.asyncIterator] != null;
4890
+ }
4891
+ function merge(...sources) {
4892
+ const syncSources = [];
4893
+ for (const source of sources) {
4894
+ if (!isAsyncIterable$1(source)) {
4895
+ syncSources.push(source);
4686
4896
  }
4687
- });
4688
- yield* output;
4897
+ }
4898
+ if (syncSources.length === sources.length) {
4899
+ // all sources are synchronous
4900
+ return (function* () {
4901
+ for (const source of syncSources) {
4902
+ yield* source;
4903
+ }
4904
+ })();
4905
+ }
4906
+ return (async function* () {
4907
+ const output = pushable({
4908
+ objectMode: true
4909
+ });
4910
+ void Promise.resolve().then(async () => {
4911
+ try {
4912
+ await Promise.all(sources.map(async (source) => {
4913
+ for await (const item of source) {
4914
+ output.push(item);
4915
+ }
4916
+ }));
4917
+ output.end();
4918
+ }
4919
+ catch (err) {
4920
+ output.end(err);
4921
+ }
4922
+ });
4923
+ yield* output;
4924
+ })();
4689
4925
  }
4690
4926
 
4691
- const rawPipe = (...fns) => {
4692
- let res;
4693
- while (fns.length > 0) {
4694
- res = fns.shift()(res);
4695
- }
4696
- return res;
4697
- };
4698
- const isIterable = (obj) => {
4699
- return obj != null && (typeof obj[Symbol.asyncIterator] === 'function' ||
4700
- typeof obj[Symbol.iterator] === 'function' ||
4701
- typeof obj.next === 'function' // Probably, right?
4702
- );
4703
- };
4704
- const isDuplex = (obj) => {
4705
- return obj != null && typeof obj.sink === 'function' && isIterable(obj.source);
4706
- };
4707
- const duplexPipelineFn = (duplex) => {
4708
- return (source) => {
4709
- const p = duplex.sink(source);
4710
- if (p.then != null) {
4711
- const stream = pushable({
4712
- objectMode: true
4713
- });
4714
- p.then(() => {
4715
- stream.end();
4716
- }, (err) => {
4717
- stream.end(err);
4718
- });
4719
- const sourceWrap = async function* () {
4720
- yield* duplex.source;
4721
- stream.end();
4722
- };
4723
- return merge(stream, sourceWrap());
4724
- }
4725
- return duplex.source;
4726
- };
4727
- };
4728
4927
  function pipe(first, ...rest) {
4928
+ if (first == null) {
4929
+ throw new Error('Empty pipeline');
4930
+ }
4729
4931
  // Duplex at start: wrap in function and return duplex source
4730
4932
  if (isDuplex(first)) {
4731
4933
  const duplex = first;
4732
4934
  first = () => duplex.source;
4733
4935
  // Iterable at start: wrap in function
4734
4936
  }
4735
- else if (isIterable(first)) {
4937
+ else if (isIterable(first) || isAsyncIterable(first)) {
4736
4938
  const source = first;
4737
4939
  first = () => source;
4738
4940
  }
@@ -4753,19 +4955,59 @@ function pipe(first, ...rest) {
4753
4955
  }
4754
4956
  return rawPipe(...fns);
4755
4957
  }
4756
-
4757
- const EmptyMessage = {
4758
- payload: new Uint8Array(),
4759
- contentTopic: "",
4760
- version: undefined,
4761
- timestamp: undefined,
4762
- meta: undefined,
4763
- rateLimitProof: undefined,
4764
- ephemeral: undefined,
4958
+ const rawPipe = (...fns) => {
4959
+ let res;
4960
+ while (fns.length > 0) {
4961
+ res = fns.shift()(res);
4962
+ }
4963
+ return res;
4964
+ };
4965
+ const isAsyncIterable = (obj) => {
4966
+ return obj?.[Symbol.asyncIterator] != null;
4967
+ };
4968
+ const isIterable = (obj) => {
4969
+ return obj?.[Symbol.iterator] != null;
4970
+ };
4971
+ const isDuplex = (obj) => {
4972
+ if (obj == null) {
4973
+ return false;
4974
+ }
4975
+ return obj.sink != null && obj.source != null;
4976
+ };
4977
+ const duplexPipelineFn = (duplex) => {
4978
+ return (source) => {
4979
+ const p = duplex.sink(source);
4980
+ if (p?.then != null) {
4981
+ const stream = pushable({
4982
+ objectMode: true
4983
+ });
4984
+ p.then(() => {
4985
+ stream.end();
4986
+ }, (err) => {
4987
+ stream.end(err);
4988
+ });
4989
+ let sourceWrap;
4990
+ const source = duplex.source;
4991
+ if (isAsyncIterable(source)) {
4992
+ sourceWrap = async function* () {
4993
+ yield* source;
4994
+ stream.end();
4995
+ };
4996
+ }
4997
+ else if (isIterable(source)) {
4998
+ sourceWrap = function* () {
4999
+ yield* source;
5000
+ stream.end();
5001
+ };
5002
+ }
5003
+ else {
5004
+ throw new Error('Unknown duplex source type - must be Iterable or AsyncIterable');
5005
+ }
5006
+ return merge(stream, sourceWrap());
5007
+ }
5008
+ return duplex.source;
5009
+ };
4765
5010
  };
4766
- function toProtoMessage(wire) {
4767
- return { ...EmptyMessage, ...wire };
4768
- }
4769
5011
 
4770
5012
  // Unique ID creation requires a high quality random # generator. In the browser we therefore
4771
5013
  // require the crypto API and do not support built-in fallback to lower quality random number
@@ -4832,198 +5074,6 @@ function v4(options, buf, offset) {
4832
5074
  return unsafeStringify(rnds);
4833
5075
  }
4834
5076
 
4835
- /**
4836
- * FilterRPC represents a message conforming to the Waku Filter protocol
4837
- */
4838
- class FilterRpc {
4839
- proto;
4840
- constructor(proto) {
4841
- this.proto = proto;
4842
- }
4843
- static createRequest(topic, contentFilters, requestId, subscribe = true) {
4844
- return new FilterRpc({
4845
- requestId: requestId || v4(),
4846
- request: {
4847
- subscribe,
4848
- topic,
4849
- contentFilters,
4850
- },
4851
- push: undefined,
4852
- });
4853
- }
4854
- /**
4855
- *
4856
- * @param bytes Uint8Array of bytes from a FilterRPC message
4857
- * @returns FilterRpc
4858
- */
4859
- static decode(bytes) {
4860
- const res = FilterRpc$1.decode(bytes);
4861
- return new FilterRpc(res);
4862
- }
4863
- /**
4864
- * Encode the current FilterRPC request to bytes
4865
- * @returns Uint8Array
4866
- */
4867
- encode() {
4868
- return FilterRpc$1.encode(this.proto);
4869
- }
4870
- get push() {
4871
- return this.proto.push;
4872
- }
4873
- get requestId() {
4874
- return this.proto.requestId;
4875
- }
4876
- }
4877
-
4878
- const FilterCodec = "/vac/waku/filter/2.0.0-beta1";
4879
- const log$4 = debug("waku:filter");
4880
- /**
4881
- * Implements client side of the [Waku v2 Filter protocol](https://rfc.vac.dev/spec/12/).
4882
- *
4883
- * Note this currently only works in NodeJS when the Waku node is listening on a port, see:
4884
- * - https://github.com/status-im/go-waku/issues/245
4885
- * - https://github.com/status-im/nwaku/issues/948
4886
- */
4887
- class Filter extends BaseProtocol {
4888
- libp2p;
4889
- options;
4890
- subscriptions;
4891
- constructor(libp2p, options) {
4892
- super(FilterCodec, libp2p.peerStore, libp2p.getConnections.bind(libp2p));
4893
- this.libp2p = libp2p;
4894
- this.options = options ?? {};
4895
- this.subscriptions = new Map();
4896
- this.libp2p
4897
- .handle(this.multicodec, this.onRequest.bind(this))
4898
- .catch((e) => log$4("Failed to register filter protocol", e));
4899
- }
4900
- /**
4901
- * @param decoders Decoder or array of Decoders to use to decode messages, it also specifies the content topics.
4902
- * @param callback A function that will be called on each message returned by the filter.
4903
- * @param opts The FilterSubscriptionOpts used to narrow which messages are returned, and which peer to connect to.
4904
- * @returns Unsubscribe function that can be used to end the subscription.
4905
- */
4906
- async subscribe(decoders, callback, opts) {
4907
- const decodersArray = Array.isArray(decoders) ? decoders : [decoders];
4908
- const { pubSubTopic = DefaultPubSubTopic } = this.options;
4909
- const contentTopics = Array.from(groupByContentTopic(decodersArray).keys());
4910
- const contentFilters = contentTopics.map((contentTopic) => ({
4911
- contentTopic,
4912
- }));
4913
- const request = FilterRpc.createRequest(pubSubTopic, contentFilters, undefined, true);
4914
- const requestId = request.requestId;
4915
- const peer = await this.getPeer(opts?.peerId);
4916
- const stream = await this.newStream(peer);
4917
- try {
4918
- const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
4919
- log$4("response", res);
4920
- }
4921
- catch (e) {
4922
- log$4("Error subscribing to peer ", peer.id.toString(), "for content topics", contentTopics, ": ", e);
4923
- throw e;
4924
- }
4925
- const subscription = {
4926
- callback,
4927
- decoders: decodersArray,
4928
- pubSubTopic,
4929
- };
4930
- this.subscriptions.set(requestId, subscription);
4931
- return async () => {
4932
- await this.unsubscribe(pubSubTopic, contentFilters, requestId, peer);
4933
- this.subscriptions.delete(requestId);
4934
- };
4935
- }
4936
- toSubscriptionIterator(decoders, opts) {
4937
- return toAsyncIterator(this, decoders, opts);
4938
- }
4939
- getActiveSubscriptions() {
4940
- const map = new Map();
4941
- const subscriptions = this.subscriptions;
4942
- for (const item of subscriptions.values()) {
4943
- const values = map.get(item.pubSubTopic) || [];
4944
- const nextValues = item.decoders.map((decoder) => decoder.contentTopic);
4945
- map.set(item.pubSubTopic, [...values, ...nextValues]);
4946
- }
4947
- return map;
4948
- }
4949
- onRequest(streamData) {
4950
- log$4("Receiving message push");
4951
- try {
4952
- pipe(streamData.stream, decode, async (source) => {
4953
- for await (const bytes of source) {
4954
- const res = FilterRpc.decode(bytes.slice());
4955
- if (res.requestId && res.push?.messages?.length) {
4956
- await this.pushMessages(res.requestId, res.push.messages);
4957
- }
4958
- }
4959
- }).then(() => {
4960
- log$4("Receiving pipe closed.");
4961
- }, (e) => {
4962
- log$4("Error with receiving pipe", e);
4963
- });
4964
- }
4965
- catch (e) {
4966
- log$4("Error decoding message", e);
4967
- }
4968
- }
4969
- async pushMessages(requestId, messages) {
4970
- const subscription = this.subscriptions.get(requestId);
4971
- if (!subscription) {
4972
- log$4(`No subscription locally registered for request ID ${requestId}`);
4973
- return;
4974
- }
4975
- const { decoders, callback, pubSubTopic } = subscription;
4976
- if (!decoders || !decoders.length) {
4977
- log$4(`No decoder registered for request ID ${requestId}`);
4978
- return;
4979
- }
4980
- for (const protoMessage of messages) {
4981
- const contentTopic = protoMessage.contentTopic;
4982
- if (!contentTopic) {
4983
- log$4("Message has no content topic, skipping");
4984
- return;
4985
- }
4986
- let didDecodeMsg = false;
4987
- // We don't want to wait for decoding failure, just attempt to decode
4988
- // all messages and do the call back on the one that works
4989
- // noinspection ES6MissingAwait
4990
- decoders.forEach(async (dec) => {
4991
- if (didDecodeMsg)
4992
- return;
4993
- const decoded = await dec.fromProtoObj(pubSubTopic, toProtoMessage(protoMessage));
4994
- if (!decoded) {
4995
- log$4("Not able to decode message");
4996
- return;
4997
- }
4998
- // This is just to prevent more decoding attempt
4999
- // TODO: Could be better if we were to abort promises
5000
- didDecodeMsg = Boolean(decoded);
5001
- await callback(decoded);
5002
- });
5003
- }
5004
- }
5005
- async unsubscribe(topic, contentFilters, requestId, peer) {
5006
- const unsubscribeRequest = FilterRpc.createRequest(topic, contentFilters, requestId, false);
5007
- const stream = await this.newStream(peer);
5008
- try {
5009
- await pipe([unsubscribeRequest.encode()], encode, stream.sink);
5010
- }
5011
- catch (e) {
5012
- log$4("Error unsubscribing", e);
5013
- throw e;
5014
- }
5015
- }
5016
- }
5017
- function wakuFilter(init = {}) {
5018
- return (libp2p) => new Filter(libp2p, init);
5019
- }
5020
-
5021
- var index$3 = /*#__PURE__*/Object.freeze({
5022
- __proto__: null,
5023
- FilterCodec: FilterCodec,
5024
- wakuFilter: wakuFilter
5025
- });
5026
-
5027
5077
  /**
5028
5078
  * FilterPushRPC represents a message conforming to the Waku FilterPush protocol.
5029
5079
  * Protocol documentation: https://rfc.vac.dev/spec/12/
@@ -5132,7 +5182,7 @@ class FilterSubscribeResponse {
5132
5182
  }
5133
5183
 
5134
5184
  const log$3 = debug("waku:filter:v2");
5135
- const FilterV2Codecs = {
5185
+ const FilterCodecs = {
5136
5186
  SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
5137
5187
  PUSH: "/vac/waku/filter-push/2.0.0-beta1",
5138
5188
  };
@@ -5239,8 +5289,7 @@ class Subscription {
5239
5289
  await pushMessage(subscriptionCallback, this.pubSubTopic, message);
5240
5290
  }
5241
5291
  }
5242
- class FilterV2 extends BaseProtocol {
5243
- libp2p;
5292
+ class Filter extends BaseProtocol {
5244
5293
  options;
5245
5294
  activeSubscriptions = new Map();
5246
5295
  getActiveSubscription(pubSubTopic, peerIdStr) {
@@ -5251,12 +5300,9 @@ class FilterV2 extends BaseProtocol {
5251
5300
  return subscription;
5252
5301
  }
5253
5302
  constructor(libp2p, options) {
5254
- super(FilterV2Codecs.SUBSCRIBE, libp2p.peerStore, libp2p.getConnections.bind(libp2p));
5255
- this.libp2p = libp2p;
5256
- this.libp2p
5257
- .handle(FilterV2Codecs.PUSH, this.onRequest.bind(this))
5258
- .catch((e) => {
5259
- log$3("Failed to register ", FilterV2Codecs.PUSH, e);
5303
+ super(FilterCodecs.SUBSCRIBE, libp2p.components);
5304
+ libp2p.handle(FilterCodecs.PUSH, this.onRequest.bind(this)).catch((e) => {
5305
+ log$3("Failed to register ", FilterCodecs.PUSH, e);
5260
5306
  });
5261
5307
  this.activeSubscriptions = new Map();
5262
5308
  this.options = options ?? {};
@@ -5288,7 +5334,7 @@ class FilterV2 extends BaseProtocol {
5288
5334
  */
5289
5335
  async subscribe(decoders, callback, opts) {
5290
5336
  const subscription = await this.createSubscription(undefined, opts?.peerId);
5291
- subscription.subscribe(decoders, callback);
5337
+ await subscription.subscribe(decoders, callback);
5292
5338
  const contentTopics = Array.from(groupByContentTopic(Array.isArray(decoders) ? decoders : [decoders]).keys());
5293
5339
  return async () => {
5294
5340
  await subscription.unsubscribe(contentTopics);
@@ -5328,8 +5374,8 @@ class FilterV2 extends BaseProtocol {
5328
5374
  }
5329
5375
  }
5330
5376
  }
5331
- function wakuFilterV2(init = {}) {
5332
- return (libp2p) => new FilterV2(libp2p, init);
5377
+ function wakuFilter(init = {}) {
5378
+ return (libp2p) => new Filter(libp2p, init);
5333
5379
  }
5334
5380
  async function pushMessage(subscriptionCallback, pubSubTopic, message) {
5335
5381
  const { decoders, callback } = subscriptionCallback;
@@ -5342,25 +5388,24 @@ async function pushMessage(subscriptionCallback, pubSubTopic, message) {
5342
5388
  // We don't want to wait for decoding failure, just attempt to decode
5343
5389
  // all messages and do the call back on the one that works
5344
5390
  // noinspection ES6MissingAwait
5345
- decoders.forEach(async (dec) => {
5391
+ for (const dec of decoders) {
5346
5392
  if (didDecodeMsg)
5347
- return;
5393
+ break;
5348
5394
  const decoded = await dec.fromProtoObj(pubSubTopic, message);
5349
- // const decoded = await dec.fromProtoObj(pubSubTopic, message);
5350
5395
  if (!decoded) {
5351
5396
  log$3("Not able to decode message");
5352
- return;
5397
+ continue;
5353
5398
  }
5354
5399
  // This is just to prevent more decoding attempt
5355
5400
  // TODO: Could be better if we were to abort promises
5356
5401
  didDecodeMsg = Boolean(decoded);
5357
5402
  await callback(decoded);
5358
- });
5403
+ }
5359
5404
  }
5360
5405
 
5361
5406
  var index$2 = /*#__PURE__*/Object.freeze({
5362
5407
  __proto__: null,
5363
- wakuFilterV2: wakuFilterV2
5408
+ wakuFilter: wakuFilter
5364
5409
  });
5365
5410
 
5366
5411
  class PushRpc {
@@ -5399,11 +5444,9 @@ const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
5399
5444
  * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
5400
5445
  */
5401
5446
  class LightPush extends BaseProtocol {
5402
- libp2p;
5403
5447
  options;
5404
5448
  constructor(libp2p, options) {
5405
- super(LightPushCodec, libp2p.peerStore, libp2p.getConnections.bind(libp2p));
5406
- this.libp2p = libp2p;
5449
+ super(LightPushCodec, libp2p.components);
5407
5450
  this.options = options || {};
5408
5451
  }
5409
5452
  async send(encoder, message, opts) {
@@ -5804,6 +5847,19 @@ function concat(byteArrays, totalLength) {
5804
5847
  return res;
5805
5848
  }
5806
5849
 
5850
+ const EmptyMessage = {
5851
+ payload: new Uint8Array(),
5852
+ contentTopic: "",
5853
+ version: undefined,
5854
+ timestamp: undefined,
5855
+ meta: undefined,
5856
+ rateLimitProof: undefined,
5857
+ ephemeral: undefined,
5858
+ };
5859
+ function toProtoMessage(wire) {
5860
+ return { ...EmptyMessage, ...wire };
5861
+ }
5862
+
5807
5863
  const OneMillion = BigInt(1000000);
5808
5864
  var PageDirection;
5809
5865
  (function (PageDirection) {
@@ -5884,11 +5940,9 @@ const DefaultPageSize = 10;
5884
5940
  * The Waku Store protocol can be used to retrieved historical messages.
5885
5941
  */
5886
5942
  class Store extends BaseProtocol {
5887
- libp2p;
5888
5943
  options;
5889
5944
  constructor(libp2p, options) {
5890
- super(StoreCodec, libp2p.peerStore, libp2p.getConnections.bind(libp2p));
5891
- this.libp2p = libp2p;
5945
+ super(StoreCodec, libp2p.components);
5892
5946
  this.options = options ?? {};
5893
5947
  }
5894
5948
  /**
@@ -6313,7 +6367,7 @@ const log = debug("waku:wait-for-remote-peer");
6313
6367
  * Wait for a remote peer to be ready given the passed protocols.
6314
6368
  * Must be used after attempting to connect to nodes, using
6315
6369
  * {@link @waku/core.WakuNode.dial} or a bootstrap method with
6316
- * {@link @waku/create.createLightNode}.
6370
+ * {@link @waku/sdk.createLightNode}.
6317
6371
  *
6318
6372
  * If the passed protocols is a GossipSub protocol, then it resolves only once
6319
6373
  * a peer is in a mesh, to help ensure that other peers will send and receive
@@ -6372,13 +6426,13 @@ async function waitForConnectedPeer(protocol) {
6372
6426
  }
6373
6427
  await new Promise((resolve) => {
6374
6428
  const cb = (evt) => {
6375
- if (evt.detail.protocols.includes(codec)) {
6429
+ if (evt.detail?.protocols?.includes(codec)) {
6376
6430
  log("Resolving for", codec, evt.detail.protocols);
6377
- protocol.peerStore.removeEventListener("change:protocols", cb);
6431
+ protocol.removeLibp2pEventListener("peer:identify", cb);
6378
6432
  resolve();
6379
6433
  }
6380
6434
  };
6381
- protocol.peerStore.addEventListener("change:protocols", cb);
6435
+ protocol.addLibp2pEventListener("peer:identify", cb);
6382
6436
  });
6383
6437
  }
6384
6438
  /**
@@ -6413,4 +6467,4 @@ function getEnabledProtocols(waku) {
6413
6467
  return protocols;
6414
6468
  }
6415
6469
 
6416
- export { ConnectionManager, DefaultPubSubTopic, DefaultUserAgent, KeepAliveManager, LightPushCodec, PageDirection, StoreCodec, WakuNode, createCursor, createEncoder, index$4 as message, waitForRemotePeer, waku, wakuFilter as wakuFilterV1, wakuFilterV2, wakuLightPush, wakuStore, index$3 as waku_filter_v1, index$2 as waku_filter_v2, index$1 as waku_light_push, index as waku_store };
6470
+ export { ConnectionManager, DefaultPubSubTopic, DefaultUserAgent, KeepAliveManager, LightPushCodec, PageDirection, StoreCodec, WakuNode, createCursor, createEncoder, index$3 as message, waitForRemotePeer, waku, wakuFilter, wakuLightPush, wakuStore, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };