@waku/core 0.0.36-10590da.0 → 0.0.36-3730abc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/bundle/index.js +495 -55
  2. package/bundle/lib/message/version_0.js +1 -1
  3. package/bundle/{version_0-CiYGrPc2.js → version_0-y7BmRolm.js} +919 -184
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/connection_manager/connection_manager.d.ts +1 -1
  9. package/dist/lib/connection_manager/connection_manager.js +1 -1
  10. package/dist/lib/filter/filter.d.ts +4 -2
  11. package/dist/lib/filter/filter.js +21 -3
  12. package/dist/lib/filter/filter.js.map +1 -1
  13. package/dist/lib/light_push/index.d.ts +5 -1
  14. package/dist/lib/light_push/index.js +5 -1
  15. package/dist/lib/light_push/index.js.map +1 -1
  16. package/dist/lib/light_push/light_push.d.ts +3 -4
  17. package/dist/lib/light_push/light_push.js +18 -19
  18. package/dist/lib/light_push/light_push.js.map +1 -1
  19. package/dist/lib/light_push/light_push_v3.d.ts +10 -0
  20. package/dist/lib/light_push/light_push_v3.js +172 -0
  21. package/dist/lib/light_push/light_push_v3.js.map +1 -0
  22. package/dist/lib/light_push/push_rpc.d.ts +1 -1
  23. package/dist/lib/light_push/push_rpc.js.map +1 -1
  24. package/dist/lib/light_push/push_rpc_v2.d.ts +11 -0
  25. package/dist/lib/light_push/push_rpc_v2.js +32 -0
  26. package/dist/lib/light_push/push_rpc_v2.js.map +1 -0
  27. package/dist/lib/light_push/push_rpc_v3.d.ts +11 -0
  28. package/dist/lib/light_push/push_rpc_v3.js +33 -0
  29. package/dist/lib/light_push/push_rpc_v3.js.map +1 -0
  30. package/dist/lib/light_push/status_codes.d.ts +14 -0
  31. package/dist/lib/light_push/status_codes.js +49 -0
  32. package/dist/lib/light_push/status_codes.js.map +1 -0
  33. package/dist/lib/light_push/status_codes_v3.d.ts +17 -0
  34. package/dist/lib/light_push/status_codes_v3.js +69 -0
  35. package/dist/lib/light_push/status_codes_v3.js.map +1 -0
  36. package/dist/lib/message/version_0.d.ts +2 -3
  37. package/dist/lib/message/version_0.js +1 -4
  38. package/dist/lib/message/version_0.js.map +1 -1
  39. package/dist/lib/message_hash/index.d.ts +1 -0
  40. package/dist/lib/message_hash/index.js +2 -0
  41. package/dist/lib/message_hash/index.js.map +1 -0
  42. package/dist/lib/message_hash/message_hash.d.ts +52 -0
  43. package/dist/lib/message_hash/message_hash.js +84 -0
  44. package/dist/lib/message_hash/message_hash.js.map +1 -0
  45. package/dist/lib/store/rpc.js +16 -10
  46. package/dist/lib/store/rpc.js.map +1 -1
  47. package/dist/lib/store/store.js +12 -2
  48. package/dist/lib/store/store.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/index.ts +11 -0
  51. package/src/lib/connection_manager/connection_manager.ts +1 -1
  52. package/src/lib/filter/filter.ts +33 -6
  53. package/src/lib/light_push/index.ts +24 -1
  54. package/src/lib/light_push/light_push.ts +25 -23
  55. package/src/lib/light_push/light_push_v3.ts +233 -0
  56. package/src/lib/light_push/push_rpc.ts +1 -1
  57. package/src/lib/light_push/push_rpc_v2.ts +38 -0
  58. package/src/lib/light_push/push_rpc_v3.ts +46 -0
  59. package/src/lib/light_push/status_codes.ts +71 -0
  60. package/src/lib/light_push/status_codes_v3.ts +97 -0
  61. package/src/lib/message/version_0.ts +3 -7
  62. package/src/lib/message_hash/index.ts +1 -0
  63. package/src/lib/message_hash/message_hash.ts +106 -0
  64. package/src/lib/store/rpc.ts +23 -19
  65. package/src/lib/store/store.ts +13 -1
package/bundle/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { v as version_0, a as allocUnsafe, b as alloc, e as encodingLength$1, c as encode$2, d as decode$4, F as FilterSubscribeRequest, f as FilterSubscribeResponse$1, M as MessagePush, P as PushRpc$1, g as PushResponse, S as StoreQueryRequest$1, h as StoreQueryResponse$1, t as toString$1, i as bases, j as fromString, u as utf8ToBytes, k as createEncoder, p as pubsubTopicToSingleShardInfo, l as bytesToUtf8, s as shardInfoToPubsubTopics, W as WakuMetadataRequest, m as pubsubTopicsToShardInfo, n as WakuMetadataResponse } from './version_0-CiYGrPc2.js';
2
- export { o as createDecoder } from './version_0-CiYGrPc2.js';
1
+ import { v as version_0, a as allocUnsafe, b as alloc, e as encodingLength$1, c as encode$2, d as decode$4, F as FilterSubscribeRequest, f as FilterSubscribeResponse$1, M as MessagePush, P as PushRpc, L as LightpushResponse, g as LightpushRequest, h as PushResponse, S as StoreQueryRequest$1, i as StoreQueryResponse$1, t as toString$1, j as bases, k as fromString, u as utf8ToBytes, l as createEncoder, p as pubsubTopicToSingleShardInfo, m as bytesToUtf8, s as shardInfoToPubsubTopics, W as WakuMetadataRequest, n as pubsubTopicsToShardInfo, o as WakuMetadataResponse, q as concat$1, r as sha256, w as bytesToHex, x as numberToBytes } from './version_0-y7BmRolm.js';
2
+ export { y as createDecoder } from './version_0-y7BmRolm.js';
3
3
  import { e as equals$2, c as coerce, b as base32, a as base58btc, d as base36, L as Logger, P as ProtocolError, T as Tags, E as EPeersByDiscoveryEvents, f as EConnectionStateEvents } from './index-CTo1my9M.js';
4
4
  import { B as BaseProtocol } from './base_protocol-DvQrudwy.js';
5
5
  export { S as StreamManager } from './base_protocol-DvQrudwy.js';
@@ -514,6 +514,10 @@ function encodeCID(version, code, multihash) {
514
514
  }
515
515
  const cidSymbol = Symbol.for('@ipld/js-cid/CID');
516
516
 
517
+ function isDefined(value) {
518
+ return Boolean(value);
519
+ }
520
+
517
521
  const MB = 1024 ** 2;
518
522
  const SIZE_CAP_IN_MB = 1;
519
523
  /**
@@ -2294,24 +2298,42 @@ class FilterSubscribeResponse {
2294
2298
  }
2295
2299
  }
2296
2300
 
2297
- const log$5 = new Logger("filter:v2");
2301
+ const log$6 = new Logger("filter:v2");
2298
2302
  const FilterCodecs = {
2299
2303
  SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
2300
2304
  PUSH: "/vac/waku/filter-push/2.0.0-beta1"
2301
2305
  };
2302
2306
  class FilterCore extends BaseProtocol {
2303
- handleIncomingMessage;
2304
2307
  pubsubTopics;
2308
+ static handleIncomingMessage;
2305
2309
  constructor(handleIncomingMessage, pubsubTopics, libp2p) {
2306
2310
  super(FilterCodecs.SUBSCRIBE, libp2p.components, pubsubTopics);
2307
- this.handleIncomingMessage = handleIncomingMessage;
2308
2311
  this.pubsubTopics = pubsubTopics;
2312
+ // TODO(weboko): remove when @waku/sdk 0.0.33 is released
2313
+ const prevHandler = FilterCore.handleIncomingMessage;
2314
+ FilterCore.handleIncomingMessage = !prevHandler
2315
+ ? handleIncomingMessage
2316
+ : async (pubsubTopic, message, peerIdStr) => {
2317
+ try {
2318
+ await prevHandler(pubsubTopic, message, peerIdStr);
2319
+ }
2320
+ catch (e) {
2321
+ log$6.error("Previous FilterCore incoming message handler failed ", e);
2322
+ }
2323
+ try {
2324
+ await handleIncomingMessage(pubsubTopic, message, peerIdStr);
2325
+ }
2326
+ catch (e) {
2327
+ log$6.error("Present FilterCore incoming message handler failed ", e);
2328
+ }
2329
+ return;
2330
+ };
2309
2331
  libp2p
2310
2332
  .handle(FilterCodecs.PUSH, this.onRequest.bind(this), {
2311
2333
  maxInboundStreams: 100
2312
2334
  })
2313
2335
  .catch((e) => {
2314
- log$5.error("Failed to register ", FilterCodecs.PUSH, e);
2336
+ log$6.error("Failed to register ", FilterCodecs.PUSH, e);
2315
2337
  });
2316
2338
  }
2317
2339
  async subscribe(pubsubTopic, peerId, contentTopics) {
@@ -2322,7 +2344,7 @@ class FilterCore extends BaseProtocol {
2322
2344
  res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
2323
2345
  }
2324
2346
  catch (error) {
2325
- log$5.error("Failed to send subscribe request", error);
2347
+ log$6.error("Failed to send subscribe request", error);
2326
2348
  return {
2327
2349
  success: null,
2328
2350
  failure: {
@@ -2333,7 +2355,7 @@ class FilterCore extends BaseProtocol {
2333
2355
  }
2334
2356
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
2335
2357
  if (statusCode < 200 || statusCode >= 300) {
2336
- log$5.error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
2358
+ log$6.error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
2337
2359
  return {
2338
2360
  failure: {
2339
2361
  error: ProtocolError.REMOTE_PEER_REJECTED,
@@ -2353,7 +2375,7 @@ class FilterCore extends BaseProtocol {
2353
2375
  stream = await this.getStream(peerId);
2354
2376
  }
2355
2377
  catch (error) {
2356
- log$5.error(`Failed to get a stream for remote peer${peerId.toString()}`, error);
2378
+ log$6.error(`Failed to get a stream for remote peer${peerId.toString()}`, error);
2357
2379
  return {
2358
2380
  success: null,
2359
2381
  failure: {
@@ -2367,7 +2389,7 @@ class FilterCore extends BaseProtocol {
2367
2389
  await pipe([unsubscribeRequest.encode()], encode, stream.sink);
2368
2390
  }
2369
2391
  catch (error) {
2370
- log$5.error("Failed to send unsubscribe request", error);
2392
+ log$6.error("Failed to send unsubscribe request", error);
2371
2393
  return {
2372
2394
  success: null,
2373
2395
  failure: {
@@ -2396,7 +2418,7 @@ class FilterCore extends BaseProtocol {
2396
2418
  }
2397
2419
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
2398
2420
  if (statusCode < 200 || statusCode >= 300) {
2399
- log$5.error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
2421
+ log$6.error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
2400
2422
  return {
2401
2423
  failure: {
2402
2424
  error: ProtocolError.REMOTE_PEER_REJECTED,
@@ -2416,7 +2438,7 @@ class FilterCore extends BaseProtocol {
2416
2438
  stream = await this.getStream(peerId);
2417
2439
  }
2418
2440
  catch (error) {
2419
- log$5.error(`Failed to get a stream for remote peer${peerId.toString()}`, error);
2441
+ log$6.error(`Failed to get a stream for remote peer${peerId.toString()}`, error);
2420
2442
  return {
2421
2443
  success: null,
2422
2444
  failure: {
@@ -2431,7 +2453,7 @@ class FilterCore extends BaseProtocol {
2431
2453
  res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
2432
2454
  }
2433
2455
  catch (error) {
2434
- log$5.error("Failed to send ping request", error);
2456
+ log$6.error("Failed to send ping request", error);
2435
2457
  return {
2436
2458
  success: null,
2437
2459
  failure: {
@@ -2451,7 +2473,7 @@ class FilterCore extends BaseProtocol {
2451
2473
  }
2452
2474
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
2453
2475
  if (statusCode < 200 || statusCode >= 300) {
2454
- log$5.error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
2476
+ log$6.error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
2455
2477
  return {
2456
2478
  success: null,
2457
2479
  failure: {
@@ -2468,30 +2490,30 @@ class FilterCore extends BaseProtocol {
2468
2490
  onRequest(streamData) {
2469
2491
  const { connection, stream } = streamData;
2470
2492
  const { remotePeer } = connection;
2471
- log$5.info(`Received message from ${remotePeer.toString()}`);
2493
+ log$6.info(`Received message from ${remotePeer.toString()}`);
2472
2494
  try {
2473
2495
  pipe(stream, decode, async (source) => {
2474
2496
  for await (const bytes of source) {
2475
2497
  const response = FilterPushRpc.decode(bytes.slice());
2476
2498
  const { pubsubTopic, wakuMessage } = response;
2477
2499
  if (!wakuMessage) {
2478
- log$5.error("Received empty message");
2500
+ log$6.error("Received empty message");
2479
2501
  return;
2480
2502
  }
2481
2503
  if (!pubsubTopic) {
2482
- log$5.error("Pubsub topic missing from push message");
2504
+ log$6.error("Pubsub topic missing from push message");
2483
2505
  return;
2484
2506
  }
2485
- await this.handleIncomingMessage(pubsubTopic, wakuMessage, connection.remotePeer.toString());
2507
+ await FilterCore.handleIncomingMessage?.(pubsubTopic, wakuMessage, connection.remotePeer.toString());
2486
2508
  }
2487
2509
  }).then(() => {
2488
- log$5.info("Receiving pipe closed.");
2510
+ log$6.info("Receiving pipe closed.");
2489
2511
  }, async (e) => {
2490
- log$5.error(`Error with receiving pipe on peer:${connection.remotePeer.toString()} -- stream:${stream.id} -- protocol:${stream.protocol}: `, e);
2512
+ log$6.error(`Error with receiving pipe on peer:${connection.remotePeer.toString()} -- stream:${stream.id} -- protocol:${stream.protocol}: `, e);
2491
2513
  });
2492
2514
  }
2493
2515
  catch (e) {
2494
- log$5.error("Error decoding message", e);
2516
+ log$6.error("Error decoding message", e);
2495
2517
  }
2496
2518
  }
2497
2519
  }
@@ -2502,13 +2524,13 @@ var index$2 = /*#__PURE__*/Object.freeze({
2502
2524
  FilterCore: FilterCore
2503
2525
  });
2504
2526
 
2505
- class PushRpc {
2527
+ class PushRpcV2 {
2506
2528
  proto;
2507
2529
  constructor(proto) {
2508
2530
  this.proto = proto;
2509
2531
  }
2510
2532
  static createRequest(message, pubsubTopic) {
2511
- return new PushRpc({
2533
+ return new PushRpcV2({
2512
2534
  requestId: v4(),
2513
2535
  request: {
2514
2536
  message: message,
@@ -2518,11 +2540,11 @@ class PushRpc {
2518
2540
  });
2519
2541
  }
2520
2542
  static decode(bytes) {
2521
- const res = PushRpc$1.decode(bytes);
2522
- return new PushRpc(res);
2543
+ const res = PushRpc.decode(bytes);
2544
+ return new PushRpcV2(res);
2523
2545
  }
2524
2546
  encode() {
2525
- return PushRpc$1.encode(this.proto);
2547
+ return PushRpc.encode(this.proto);
2526
2548
  }
2527
2549
  get query() {
2528
2550
  return this.proto.request;
@@ -2550,17 +2572,244 @@ const isRLNResponseError = (info) => {
2550
2572
  info.includes(RLN_REMOTE_VALIDATION));
2551
2573
  };
2552
2574
 
2553
- const log$4 = new Logger("light-push");
2575
+ const log$5 = new Logger("light-push");
2554
2576
  const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
2555
- /**
2556
- * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
2557
- */
2577
+ const LightPushCodecV2 = LightPushCodec;
2558
2578
  class LightPushCore extends BaseProtocol {
2559
2579
  pubsubTopics;
2560
2580
  constructor(pubsubTopics, libp2p) {
2561
2581
  super(LightPushCodec, libp2p.components, pubsubTopics);
2562
2582
  this.pubsubTopics = pubsubTopics;
2563
2583
  }
2584
+ async preparePushMessage(encoder, message) {
2585
+ try {
2586
+ if (!message.payload || message.payload.length === 0) {
2587
+ log$5.error("Failed to send waku light push: payload is empty");
2588
+ return { query: null, error: ProtocolError.EMPTY_PAYLOAD };
2589
+ }
2590
+ if (!(await isMessageSizeUnderCap(encoder, message))) {
2591
+ log$5.error("Failed to send waku light push: message is bigger than 1MB");
2592
+ return { query: null, error: ProtocolError.SIZE_TOO_BIG };
2593
+ }
2594
+ const protoMessage = await encoder.toProtoObj(message);
2595
+ if (!protoMessage) {
2596
+ log$5.error("Failed to encode to protoMessage, aborting push");
2597
+ return {
2598
+ query: null,
2599
+ error: ProtocolError.ENCODE_FAILED
2600
+ };
2601
+ }
2602
+ const query = PushRpcV2.createRequest(protoMessage, encoder.pubsubTopic);
2603
+ return { query, error: null };
2604
+ }
2605
+ catch (error) {
2606
+ log$5.error("Failed to prepare push message", error);
2607
+ return {
2608
+ query: null,
2609
+ error: ProtocolError.GENERIC_FAIL
2610
+ };
2611
+ }
2612
+ }
2613
+ async send(encoder, message, peerId) {
2614
+ const { query, error: preparationError } = await this.preparePushMessage(encoder, message);
2615
+ if (preparationError || !query) {
2616
+ return {
2617
+ success: null,
2618
+ failure: {
2619
+ error: preparationError,
2620
+ peerId
2621
+ }
2622
+ };
2623
+ }
2624
+ let stream;
2625
+ try {
2626
+ stream = await this.getStream(peerId);
2627
+ }
2628
+ catch (error) {
2629
+ log$5.error("Failed to get stream", error);
2630
+ return {
2631
+ success: null,
2632
+ failure: {
2633
+ error: ProtocolError.NO_STREAM_AVAILABLE,
2634
+ peerId: peerId
2635
+ }
2636
+ };
2637
+ }
2638
+ let res;
2639
+ try {
2640
+ res = await pipe([query.encode()], encode, stream, decode, async (source) => await all(source));
2641
+ }
2642
+ catch (err) {
2643
+ log$5.error("Failed to send waku light push request", err);
2644
+ return {
2645
+ success: null,
2646
+ failure: {
2647
+ error: ProtocolError.STREAM_ABORTED,
2648
+ peerId: peerId
2649
+ }
2650
+ };
2651
+ }
2652
+ const bytes = new Uint8ArrayList();
2653
+ res.forEach((chunk) => {
2654
+ bytes.append(chunk);
2655
+ });
2656
+ let response;
2657
+ try {
2658
+ response = PushRpcV2.decode(bytes).response;
2659
+ }
2660
+ catch (err) {
2661
+ log$5.error("Failed to decode push reply", err);
2662
+ return {
2663
+ success: null,
2664
+ failure: {
2665
+ error: ProtocolError.DECODE_FAILED,
2666
+ peerId: peerId
2667
+ }
2668
+ };
2669
+ }
2670
+ if (!response) {
2671
+ log$5.error("Remote peer fault: No response in PushRPC");
2672
+ return {
2673
+ success: null,
2674
+ failure: {
2675
+ error: ProtocolError.NO_RESPONSE,
2676
+ peerId: peerId
2677
+ }
2678
+ };
2679
+ }
2680
+ if (!response.isSuccess) {
2681
+ const errorMessage = response.info || "Message rejected";
2682
+ log$5.error("Remote peer rejected the message: ", errorMessage);
2683
+ if (response.info && isRLNResponseError(response.info)) {
2684
+ log$5.error("Remote peer fault: RLN generation");
2685
+ return {
2686
+ success: null,
2687
+ failure: {
2688
+ error: ProtocolError.RLN_PROOF_GENERATION,
2689
+ peerId: peerId
2690
+ }
2691
+ };
2692
+ }
2693
+ return {
2694
+ success: null,
2695
+ failure: {
2696
+ error: ProtocolError.REMOTE_PEER_REJECTED,
2697
+ peerId: peerId
2698
+ }
2699
+ };
2700
+ }
2701
+ return { success: peerId, failure: null };
2702
+ }
2703
+ }
2704
+ const LightPushCoreV2 = LightPushCore;
2705
+
2706
+ class PushRpcV3 {
2707
+ request;
2708
+ response;
2709
+ constructor(request, response) {
2710
+ this.request = request;
2711
+ this.response = response;
2712
+ }
2713
+ static createRequest(message, pubsubTopic) {
2714
+ const request = {
2715
+ requestId: v4(),
2716
+ message: message,
2717
+ // Only include pubsubTopic if explicitly provided (for nwaku autosharding compatibility)
2718
+ ...(pubsubTopic && { pubsubTopic })
2719
+ };
2720
+ return new PushRpcV3(request, undefined);
2721
+ }
2722
+ static decode(bytes) {
2723
+ const response = LightpushResponse.decode(bytes);
2724
+ return new PushRpcV3(undefined, response);
2725
+ }
2726
+ encode() {
2727
+ if (!this.request) {
2728
+ throw new Error("Cannot encode without a request");
2729
+ }
2730
+ return LightpushRequest.encode(this.request);
2731
+ }
2732
+ get query() {
2733
+ return this.request;
2734
+ }
2735
+ }
2736
+
2737
+ var LightPushStatusCodeV3;
2738
+ (function (LightPushStatusCodeV3) {
2739
+ LightPushStatusCodeV3[LightPushStatusCodeV3["SUCCESS"] = 200] = "SUCCESS";
2740
+ LightPushStatusCodeV3[LightPushStatusCodeV3["BAD_REQUEST"] = 400] = "BAD_REQUEST";
2741
+ LightPushStatusCodeV3[LightPushStatusCodeV3["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
2742
+ LightPushStatusCodeV3[LightPushStatusCodeV3["INVALID_MESSAGE_ERROR"] = 420] = "INVALID_MESSAGE_ERROR";
2743
+ LightPushStatusCodeV3[LightPushStatusCodeV3["UNSUPPORTED_PUBSUB_TOPIC"] = 421] = "UNSUPPORTED_PUBSUB_TOPIC";
2744
+ LightPushStatusCodeV3[LightPushStatusCodeV3["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
2745
+ LightPushStatusCodeV3[LightPushStatusCodeV3["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
2746
+ LightPushStatusCodeV3[LightPushStatusCodeV3["SERVICE_NOT_AVAILABLE"] = 503] = "SERVICE_NOT_AVAILABLE";
2747
+ LightPushStatusCodeV3[LightPushStatusCodeV3["OUT_OF_RLN_PROOF"] = 504] = "OUT_OF_RLN_PROOF";
2748
+ LightPushStatusCodeV3[LightPushStatusCodeV3["NO_PEERS_TO_RELAY"] = 505] = "NO_PEERS_TO_RELAY";
2749
+ })(LightPushStatusCodeV3 || (LightPushStatusCodeV3 = {}));
2750
+ const lightPushStatusDescriptionsV3 = {
2751
+ [LightPushStatusCodeV3.SUCCESS]: "Message sent successfully",
2752
+ [LightPushStatusCodeV3.BAD_REQUEST]: "Bad request format",
2753
+ [LightPushStatusCodeV3.PAYLOAD_TOO_LARGE]: "Message payload exceeds maximum size",
2754
+ [LightPushStatusCodeV3.INVALID_MESSAGE_ERROR]: "Message validation failed",
2755
+ [LightPushStatusCodeV3.UNSUPPORTED_PUBSUB_TOPIC]: "Unsupported pubsub topic",
2756
+ [LightPushStatusCodeV3.TOO_MANY_REQUESTS]: "Rate limit exceeded",
2757
+ [LightPushStatusCodeV3.INTERNAL_SERVER_ERROR]: "Internal server error",
2758
+ [LightPushStatusCodeV3.SERVICE_NOT_AVAILABLE]: "Service temporarily unavailable",
2759
+ [LightPushStatusCodeV3.OUT_OF_RLN_PROOF]: "RLN proof generation failed",
2760
+ [LightPushStatusCodeV3.NO_PEERS_TO_RELAY]: "No relay peers available"
2761
+ };
2762
+ function lightPushStatusCodeToProtocolErrorV3(statusCode) {
2763
+ if (!statusCode) {
2764
+ return ProtocolError.GENERIC_FAIL;
2765
+ }
2766
+ switch (statusCode) {
2767
+ case LightPushStatusCodeV3.SUCCESS:
2768
+ return ProtocolError.GENERIC_FAIL;
2769
+ case LightPushStatusCodeV3.BAD_REQUEST:
2770
+ return ProtocolError.DECODE_FAILED;
2771
+ case LightPushStatusCodeV3.PAYLOAD_TOO_LARGE:
2772
+ return ProtocolError.SIZE_TOO_BIG;
2773
+ case LightPushStatusCodeV3.INVALID_MESSAGE_ERROR:
2774
+ return ProtocolError.EMPTY_PAYLOAD;
2775
+ case LightPushStatusCodeV3.UNSUPPORTED_PUBSUB_TOPIC:
2776
+ return ProtocolError.TOPIC_NOT_CONFIGURED;
2777
+ case LightPushStatusCodeV3.TOO_MANY_REQUESTS:
2778
+ return ProtocolError.REMOTE_PEER_REJECTED;
2779
+ case LightPushStatusCodeV3.INTERNAL_SERVER_ERROR:
2780
+ return ProtocolError.GENERIC_FAIL;
2781
+ case LightPushStatusCodeV3.SERVICE_NOT_AVAILABLE:
2782
+ return ProtocolError.NO_PEER_AVAILABLE;
2783
+ case LightPushStatusCodeV3.OUT_OF_RLN_PROOF:
2784
+ return ProtocolError.RLN_PROOF_GENERATION;
2785
+ case LightPushStatusCodeV3.NO_PEERS_TO_RELAY:
2786
+ return ProtocolError.NO_PEER_AVAILABLE;
2787
+ default:
2788
+ return ProtocolError.REMOTE_PEER_REJECTED;
2789
+ }
2790
+ }
2791
+ function isSuccessStatusCodeV3(statusCode) {
2792
+ return statusCode === LightPushStatusCodeV3.SUCCESS;
2793
+ }
2794
+ function getLightPushStatusDescriptionV3(statusCode, customDesc) {
2795
+ if (customDesc) {
2796
+ return customDesc;
2797
+ }
2798
+ if (!statusCode) {
2799
+ return "Unknown error";
2800
+ }
2801
+ return (lightPushStatusDescriptionsV3[statusCode] ||
2802
+ `Unknown status code: ${statusCode}`);
2803
+ }
2804
+
2805
+ const log$4 = new Logger("light-push-v3");
2806
+ const LightPushCodecV3 = "/vac/waku/lightpush/3.0.0";
2807
+ class LightPushCoreV3 extends BaseProtocol {
2808
+ pubsubTopics;
2809
+ constructor(pubsubTopics, libp2p) {
2810
+ super(LightPushCodecV3, libp2p.components, pubsubTopics);
2811
+ this.pubsubTopics = pubsubTopics;
2812
+ }
2564
2813
  async preparePushMessage(encoder, message) {
2565
2814
  try {
2566
2815
  if (!message.payload || message.payload.length === 0) {
@@ -2579,7 +2828,7 @@ class LightPushCore extends BaseProtocol {
2579
2828
  error: ProtocolError.ENCODE_FAILED
2580
2829
  };
2581
2830
  }
2582
- const query = PushRpc.createRequest(protoMessage, encoder.pubsubTopic);
2831
+ const query = PushRpcV3.createRequest(protoMessage, encoder.pubsubTopic);
2583
2832
  return { query, error: null };
2584
2833
  }
2585
2834
  catch (error) {
@@ -2620,7 +2869,6 @@ class LightPushCore extends BaseProtocol {
2620
2869
  res = await pipe([query.encode()], encode, stream, decode, async (source) => await all(source));
2621
2870
  }
2622
2871
  catch (err) {
2623
- // can fail only because of `stream` abortion
2624
2872
  log$4.error("Failed to send waku light push request", err);
2625
2873
  return {
2626
2874
  success: null,
@@ -2636,10 +2884,10 @@ class LightPushCore extends BaseProtocol {
2636
2884
  });
2637
2885
  let response;
2638
2886
  try {
2639
- response = PushRpc.decode(bytes).response;
2887
+ response = LightpushResponse.decode(bytes);
2640
2888
  }
2641
2889
  catch (err) {
2642
- log$4.error("Failed to decode push reply", err);
2890
+ log$4.error("Failed to decode push response", err);
2643
2891
  return {
2644
2892
  success: null,
2645
2893
  failure: {
@@ -2649,7 +2897,7 @@ class LightPushCore extends BaseProtocol {
2649
2897
  };
2650
2898
  }
2651
2899
  if (!response) {
2652
- log$4.error("Remote peer fault: No response in PushRPC");
2900
+ log$4.error("Remote peer fault: No response received");
2653
2901
  return {
2654
2902
  success: null,
2655
2903
  failure: {
@@ -2658,7 +2906,37 @@ class LightPushCore extends BaseProtocol {
2658
2906
  }
2659
2907
  };
2660
2908
  }
2661
- if (isRLNResponseError(response.info)) {
2909
+ // Validate request ID matches (except for rate limiting responses)
2910
+ if (response.requestId !== query.query?.requestId) {
2911
+ // nwaku sends "N/A" for rate limiting responses
2912
+ if (response.statusCode !== LightPushStatusCodeV3.TOO_MANY_REQUESTS) {
2913
+ log$4.error("Request ID mismatch", {
2914
+ sent: query.query?.requestId,
2915
+ received: response.requestId
2916
+ });
2917
+ return {
2918
+ success: null,
2919
+ failure: {
2920
+ error: ProtocolError.GENERIC_FAIL,
2921
+ peerId: peerId
2922
+ }
2923
+ };
2924
+ }
2925
+ }
2926
+ const statusCode = response.statusCode;
2927
+ const isSuccess = isSuccessStatusCodeV3(statusCode);
2928
+ // Special handling for nwaku rate limiting
2929
+ if (statusCode === LightPushStatusCodeV3.TOO_MANY_REQUESTS) {
2930
+ if (response.requestId === "N/A") {
2931
+ log$4.warn("Rate limited by nwaku node", {
2932
+ statusDesc: response.statusDesc || "Request rejected due to too many requests"
2933
+ });
2934
+ }
2935
+ }
2936
+ if (response.relayPeerCount !== undefined) {
2937
+ log$4.info(`Message relayed to ${response.relayPeerCount} peers`);
2938
+ }
2939
+ if (response.statusDesc && isRLNResponseError(response.statusDesc)) {
2662
2940
  log$4.error("Remote peer fault: RLN generation");
2663
2941
  return {
2664
2942
  success: null,
@@ -2668,12 +2946,14 @@ class LightPushCore extends BaseProtocol {
2668
2946
  }
2669
2947
  };
2670
2948
  }
2671
- if (!response.isSuccess) {
2672
- log$4.error("Remote peer rejected the message: ", response.info);
2949
+ if (!isSuccess) {
2950
+ const errorMessage = getLightPushStatusDescriptionV3(statusCode, response.statusDesc);
2951
+ log$4.error("Remote peer rejected the message: ", errorMessage);
2952
+ const protocolError = lightPushStatusCodeToProtocolErrorV3(statusCode);
2673
2953
  return {
2674
2954
  success: null,
2675
2955
  failure: {
2676
- error: ProtocolError.REMOTE_PEER_REJECTED,
2956
+ error: protocolError,
2677
2957
  peerId: peerId
2678
2958
  }
2679
2959
  };
@@ -2682,11 +2962,74 @@ class LightPushCore extends BaseProtocol {
2682
2962
  }
2683
2963
  }
2684
2964
 
2965
+ var LightPushStatusCode;
2966
+ (function (LightPushStatusCode) {
2967
+ LightPushStatusCode[LightPushStatusCode["SUCCESS"] = 200] = "SUCCESS";
2968
+ LightPushStatusCode[LightPushStatusCode["BAD_REQUEST"] = 400] = "BAD_REQUEST";
2969
+ LightPushStatusCode[LightPushStatusCode["UNSUPPORTED_PUBSUB_TOPIC"] = 404] = "UNSUPPORTED_PUBSUB_TOPIC";
2970
+ LightPushStatusCode[LightPushStatusCode["REQUEST_TOO_LARGE"] = 413] = "REQUEST_TOO_LARGE";
2971
+ LightPushStatusCode[LightPushStatusCode["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
2972
+ LightPushStatusCode[LightPushStatusCode["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
2973
+ LightPushStatusCode[LightPushStatusCode["NO_PEERS_TO_RELAY"] = 503] = "NO_PEERS_TO_RELAY";
2974
+ })(LightPushStatusCode || (LightPushStatusCode = {}));
2975
+ function lightPushStatusCodeToProtocolError(statusCode) {
2976
+ switch (statusCode) {
2977
+ case LightPushStatusCode.SUCCESS:
2978
+ return null;
2979
+ case LightPushStatusCode.BAD_REQUEST:
2980
+ return ProtocolError.GENERIC_FAIL;
2981
+ case LightPushStatusCode.UNSUPPORTED_PUBSUB_TOPIC:
2982
+ return ProtocolError.TOPIC_NOT_CONFIGURED;
2983
+ case LightPushStatusCode.REQUEST_TOO_LARGE:
2984
+ return ProtocolError.SIZE_TOO_BIG;
2985
+ case LightPushStatusCode.TOO_MANY_REQUESTS:
2986
+ return ProtocolError.GENERIC_FAIL;
2987
+ case LightPushStatusCode.INTERNAL_SERVER_ERROR:
2988
+ return ProtocolError.REMOTE_PEER_REJECTED;
2989
+ case LightPushStatusCode.NO_PEERS_TO_RELAY:
2990
+ return ProtocolError.NO_PEER_AVAILABLE;
2991
+ default:
2992
+ return ProtocolError.REMOTE_PEER_REJECTED;
2993
+ }
2994
+ }
2995
+ const lightPushStatusDescriptions = {
2996
+ [LightPushStatusCode.SUCCESS]: "Message pushed successfully",
2997
+ [LightPushStatusCode.BAD_REQUEST]: "Invalid request format or missing required fields",
2998
+ [LightPushStatusCode.UNSUPPORTED_PUBSUB_TOPIC]: "The specified pubsub topic is not supported",
2999
+ [LightPushStatusCode.REQUEST_TOO_LARGE]: "Message size exceeds maximum allowed size",
3000
+ [LightPushStatusCode.TOO_MANY_REQUESTS]: "Rate limit exceeded, too many requests",
3001
+ [LightPushStatusCode.INTERNAL_SERVER_ERROR]: "Internal server error occurred",
3002
+ [LightPushStatusCode.NO_PEERS_TO_RELAY]: "No relay peers available to forward the message"
3003
+ };
3004
+ function isSuccessStatusCode(statusCode) {
3005
+ return statusCode === LightPushStatusCode.SUCCESS;
3006
+ }
3007
+ function getLightPushStatusDescription(statusCode, statusDesc) {
3008
+ return (statusDesc ||
3009
+ lightPushStatusDescriptions[statusCode] ||
3010
+ `Unknown status code: ${statusCode}`);
3011
+ }
3012
+
2685
3013
  var index$1 = /*#__PURE__*/Object.freeze({
2686
3014
  __proto__: null,
2687
3015
  LightPushCodec: LightPushCodec,
3016
+ LightPushCodecV2: LightPushCodecV2,
3017
+ LightPushCodecV3: LightPushCodecV3,
2688
3018
  LightPushCore: LightPushCore,
2689
- get PushResponse () { return PushResponse; }
3019
+ LightPushCoreV2: LightPushCoreV2,
3020
+ LightPushCoreV3: LightPushCoreV3,
3021
+ get LightPushStatusCode () { return LightPushStatusCode; },
3022
+ get LightPushStatusCodeV3 () { return LightPushStatusCodeV3; },
3023
+ get PushResponse () { return PushResponse; },
3024
+ PushRpcV3: PushRpcV3,
3025
+ getLightPushStatusDescription: getLightPushStatusDescription,
3026
+ getLightPushStatusDescriptionV3: getLightPushStatusDescriptionV3,
3027
+ isSuccessStatusCode: isSuccessStatusCode,
3028
+ isSuccessStatusCodeV3: isSuccessStatusCodeV3,
3029
+ lightPushStatusCodeToProtocolError: lightPushStatusCodeToProtocolError,
3030
+ lightPushStatusCodeToProtocolErrorV3: lightPushStatusCodeToProtocolErrorV3,
3031
+ lightPushStatusDescriptions: lightPushStatusDescriptions,
3032
+ lightPushStatusDescriptionsV3: lightPushStatusDescriptionsV3
2690
3033
  });
2691
3034
 
2692
3035
  const EmptyMessage = {
@@ -2714,6 +3057,7 @@ class StoreQueryRequest {
2714
3057
  static create(params) {
2715
3058
  const request = new StoreQueryRequest({
2716
3059
  ...params,
3060
+ contentTopics: params.contentTopics || [],
2717
3061
  requestId: v4(),
2718
3062
  timeStart: params.timeStart
2719
3063
  ? BigInt(params.timeStart.getTime() * ONE_MILLION)
@@ -2726,17 +3070,22 @@ class StoreQueryRequest {
2726
3070
  ? BigInt(params.paginationLimit)
2727
3071
  : undefined
2728
3072
  });
2729
- // Validate request parameters based on RFC
2730
- if ((params.pubsubTopic && !params.contentTopics) ||
2731
- (!params.pubsubTopic && params.contentTopics)) {
2732
- throw new Error("Both pubsubTopic and contentTopics must be set or unset");
2733
- }
2734
- if (params.messageHashes &&
2735
- (params.pubsubTopic ||
2736
- params.contentTopics ||
2737
- params.timeStart ||
2738
- params.timeEnd)) {
2739
- throw new Error("Message hash lookup queries cannot include content filter criteria");
3073
+ const isHashQuery = params.messageHashes && params.messageHashes.length > 0;
3074
+ const hasContentTopics = params.contentTopics && params.contentTopics.length > 0;
3075
+ const hasTimeFilter = params.timeStart || params.timeEnd;
3076
+ if (isHashQuery) {
3077
+ if (hasContentTopics || hasTimeFilter) {
3078
+ throw new Error("Message hash lookup queries cannot include content filter criteria (contentTopics, timeStart, or timeEnd)");
3079
+ }
3080
+ }
3081
+ else {
3082
+ if ((params.pubsubTopic &&
3083
+ (!params.contentTopics || params.contentTopics.length === 0)) ||
3084
+ (!params.pubsubTopic &&
3085
+ params.contentTopics &&
3086
+ params.contentTopics.length > 0)) {
3087
+ throw new Error("Both pubsubTopic and contentTopics must be set together for content-filtered queries");
3088
+ }
2740
3089
  }
2741
3090
  return request;
2742
3091
  }
@@ -2783,8 +3132,12 @@ class StoreCore extends BaseProtocol {
2783
3132
  this.pubsubTopics = pubsubTopics;
2784
3133
  }
2785
3134
  async *queryPerPage(queryOpts, decoders, peerId) {
2786
- if (queryOpts.contentTopics.toString() !==
2787
- Array.from(decoders.keys()).toString()) {
3135
+ // Only validate decoder content topics for content-filtered queries
3136
+ const isHashQuery = queryOpts.messageHashes && queryOpts.messageHashes.length > 0;
3137
+ if (!isHashQuery &&
3138
+ queryOpts.contentTopics &&
3139
+ queryOpts.contentTopics.toString() !==
3140
+ Array.from(decoders.keys()).toString()) {
2788
3141
  throw new Error("Internal error, the decoders should match the query's content topics");
2789
3142
  }
2790
3143
  let currentCursor = queryOpts.paginationCursor;
@@ -2793,6 +3146,12 @@ class StoreCore extends BaseProtocol {
2793
3146
  ...queryOpts,
2794
3147
  paginationCursor: currentCursor
2795
3148
  });
3149
+ log$3.info("Sending store query request:", {
3150
+ hasMessageHashes: !!queryOpts.messageHashes?.length,
3151
+ messageHashCount: queryOpts.messageHashes?.length,
3152
+ pubsubTopic: queryOpts.pubsubTopic,
3153
+ contentTopics: queryOpts.contentTopics
3154
+ });
2796
3155
  let stream;
2797
3156
  try {
2798
3157
  stream = await this.getStream(peerId);
@@ -4386,7 +4745,7 @@ class ConnectionManager extends TypedEventEmitter {
4386
4745
  * // Dial using multiaddr with specific protocols
4387
4746
  * await connectionManager.dialPeer(multiaddr, [
4388
4747
  * "/vac/waku/relay/2.0.0",
4389
- * "/vac/waku/lightpush/2.0.0-beta1"
4748
+ * "/vac/waku/lightpush/3.0.0"
4390
4749
  * ]);
4391
4750
  * ```
4392
4751
  *
@@ -4854,4 +5213,85 @@ function wakuMetadata(pubsubTopics) {
4854
5213
  return (components) => new Metadata(pubsubTopics, components);
4855
5214
  }
4856
5215
 
4857
- export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCore, MetadataCodec, StoreCodec, StoreCore, createEncoder, index$3 as message, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
5216
+ /**
5217
+ * Deterministic Message Hashing as defined in
5218
+ * [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/#deterministic-message-hashing)
5219
+ *
5220
+ * Computes a SHA-256 hash of the concatenation of pubsub topic, payload, content topic, meta, and timestamp.
5221
+ *
5222
+ * @param pubsubTopic - The pubsub topic string
5223
+ * @param message - The message to be hashed
5224
+ * @returns A Uint8Array containing the SHA-256 hash
5225
+ *
5226
+ * @example
5227
+ * ```typescript
5228
+ * import { messageHash } from "@waku/core";
5229
+ *
5230
+ * const pubsubTopic = "/waku/2/default-waku/proto";
5231
+ * const message = {
5232
+ * payload: new Uint8Array([1, 2, 3, 4]),
5233
+ * contentTopic: "/waku/2/default-content/proto",
5234
+ * meta: new Uint8Array([5, 6, 7, 8]),
5235
+ * timestamp: new Date()
5236
+ * };
5237
+ *
5238
+ * const hash = messageHash(pubsubTopic, message);
5239
+ * ```
5240
+ */
5241
+ function messageHash(pubsubTopic, message) {
5242
+ const pubsubTopicBytes = utf8ToBytes(pubsubTopic);
5243
+ const contentTopicBytes = utf8ToBytes(message.contentTopic);
5244
+ const timestampBytes = tryConvertTimestampToBytes(message.timestamp);
5245
+ const bytes = concat$1([
5246
+ pubsubTopicBytes,
5247
+ message.payload,
5248
+ contentTopicBytes,
5249
+ message.meta,
5250
+ timestampBytes
5251
+ ].filter(isDefined));
5252
+ return sha256(bytes);
5253
+ }
5254
+ function tryConvertTimestampToBytes(timestamp) {
5255
+ if (!timestamp) {
5256
+ return;
5257
+ }
5258
+ let bigIntTimestamp;
5259
+ if (typeof timestamp === "bigint") {
5260
+ bigIntTimestamp = timestamp;
5261
+ }
5262
+ else {
5263
+ bigIntTimestamp = BigInt(timestamp.valueOf()) * 1000000n;
5264
+ }
5265
+ return numberToBytes(bigIntTimestamp);
5266
+ }
5267
+ /**
5268
+ * Computes a deterministic message hash and returns it as a hexadecimal string.
5269
+ * This is a convenience wrapper around messageHash that converts the result to a hex string.
5270
+ *
5271
+ * @param pubsubTopic - The pubsub topic string
5272
+ * @param message - The message to be hashed
5273
+ * @returns A string containing the hex representation of the SHA-256 hash
5274
+ *
5275
+ * @example
5276
+ * ```typescript
5277
+ * import { messageHashStr } from "@waku/core";
5278
+ *
5279
+ * const pubsubTopic = "/waku/2/default-waku/proto";
5280
+ * const message = {
5281
+ * payload: new Uint8Array([1, 2, 3, 4]),
5282
+ * contentTopic: "/waku/2/default-content/proto",
5283
+ * meta: new Uint8Array([5, 6, 7, 8]),
5284
+ * timestamp: new Date()
5285
+ * };
5286
+ *
5287
+ * const hashString = messageHashStr(pubsubTopic, message);
5288
+ * console.log(hashString); // e.g. "a1b2c3d4..."
5289
+ * ```
5290
+ */
5291
+ function messageHashStr(pubsubTopic, message) {
5292
+ const hash = messageHash(pubsubTopic, message);
5293
+ const hashStr = bytesToHex(hash);
5294
+ return hashStr;
5295
+ }
5296
+
5297
+ export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCodecV2, LightPushCodecV3, LightPushCore, LightPushCoreV2, LightPushCoreV3, LightPushStatusCodeV3, MetadataCodec, StoreCodec, StoreCore, createEncoder, isSuccessStatusCodeV3, lightPushStatusCodeToProtocolErrorV3, index$3 as message, messageHash, messageHashStr, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };