@waku/core 0.0.36-16328a3.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 (61) hide show
  1. package/bundle/index.js +476 -54
  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/light_push/index.d.ts +5 -1
  11. package/dist/lib/light_push/index.js +5 -1
  12. package/dist/lib/light_push/index.js.map +1 -1
  13. package/dist/lib/light_push/light_push.d.ts +3 -4
  14. package/dist/lib/light_push/light_push.js +18 -19
  15. package/dist/lib/light_push/light_push.js.map +1 -1
  16. package/dist/lib/light_push/light_push_v3.d.ts +10 -0
  17. package/dist/lib/light_push/light_push_v3.js +172 -0
  18. package/dist/lib/light_push/light_push_v3.js.map +1 -0
  19. package/dist/lib/light_push/push_rpc.d.ts +1 -1
  20. package/dist/lib/light_push/push_rpc.js.map +1 -1
  21. package/dist/lib/light_push/push_rpc_v2.d.ts +11 -0
  22. package/dist/lib/light_push/push_rpc_v2.js +32 -0
  23. package/dist/lib/light_push/push_rpc_v2.js.map +1 -0
  24. package/dist/lib/light_push/push_rpc_v3.d.ts +11 -0
  25. package/dist/lib/light_push/push_rpc_v3.js +33 -0
  26. package/dist/lib/light_push/push_rpc_v3.js.map +1 -0
  27. package/dist/lib/light_push/status_codes.d.ts +14 -0
  28. package/dist/lib/light_push/status_codes.js +49 -0
  29. package/dist/lib/light_push/status_codes.js.map +1 -0
  30. package/dist/lib/light_push/status_codes_v3.d.ts +17 -0
  31. package/dist/lib/light_push/status_codes_v3.js +69 -0
  32. package/dist/lib/light_push/status_codes_v3.js.map +1 -0
  33. package/dist/lib/message/version_0.d.ts +2 -3
  34. package/dist/lib/message/version_0.js +1 -4
  35. package/dist/lib/message/version_0.js.map +1 -1
  36. package/dist/lib/message_hash/index.d.ts +1 -0
  37. package/dist/lib/message_hash/index.js +2 -0
  38. package/dist/lib/message_hash/index.js.map +1 -0
  39. package/dist/lib/message_hash/message_hash.d.ts +52 -0
  40. package/dist/lib/message_hash/message_hash.js +84 -0
  41. package/dist/lib/message_hash/message_hash.js.map +1 -0
  42. package/dist/lib/store/rpc.js +16 -10
  43. package/dist/lib/store/rpc.js.map +1 -1
  44. package/dist/lib/store/store.js +12 -2
  45. package/dist/lib/store/store.js.map +1 -1
  46. package/package.json +1 -1
  47. package/src/index.ts +11 -0
  48. package/src/lib/connection_manager/connection_manager.ts +1 -1
  49. package/src/lib/light_push/index.ts +24 -1
  50. package/src/lib/light_push/light_push.ts +25 -23
  51. package/src/lib/light_push/light_push_v3.ts +233 -0
  52. package/src/lib/light_push/push_rpc.ts +1 -1
  53. package/src/lib/light_push/push_rpc_v2.ts +38 -0
  54. package/src/lib/light_push/push_rpc_v3.ts +46 -0
  55. package/src/lib/light_push/status_codes.ts +71 -0
  56. package/src/lib/light_push/status_codes_v3.ts +97 -0
  57. package/src/lib/message/version_0.ts +3 -7
  58. package/src/lib/message_hash/index.ts +1 -0
  59. package/src/lib/message_hash/message_hash.ts +106 -0
  60. package/src/lib/store/rpc.ts +23 -19
  61. 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,7 +2298,7 @@ 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"
@@ -2314,13 +2318,13 @@ class FilterCore extends BaseProtocol {
2314
2318
  await prevHandler(pubsubTopic, message, peerIdStr);
2315
2319
  }
2316
2320
  catch (e) {
2317
- log$5.error("Previous FilterCore incoming message handler failed ", e);
2321
+ log$6.error("Previous FilterCore incoming message handler failed ", e);
2318
2322
  }
2319
2323
  try {
2320
2324
  await handleIncomingMessage(pubsubTopic, message, peerIdStr);
2321
2325
  }
2322
2326
  catch (e) {
2323
- log$5.error("Present FilterCore incoming message handler failed ", e);
2327
+ log$6.error("Present FilterCore incoming message handler failed ", e);
2324
2328
  }
2325
2329
  return;
2326
2330
  };
@@ -2329,7 +2333,7 @@ class FilterCore extends BaseProtocol {
2329
2333
  maxInboundStreams: 100
2330
2334
  })
2331
2335
  .catch((e) => {
2332
- log$5.error("Failed to register ", FilterCodecs.PUSH, e);
2336
+ log$6.error("Failed to register ", FilterCodecs.PUSH, e);
2333
2337
  });
2334
2338
  }
2335
2339
  async subscribe(pubsubTopic, peerId, contentTopics) {
@@ -2340,7 +2344,7 @@ class FilterCore extends BaseProtocol {
2340
2344
  res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
2341
2345
  }
2342
2346
  catch (error) {
2343
- log$5.error("Failed to send subscribe request", error);
2347
+ log$6.error("Failed to send subscribe request", error);
2344
2348
  return {
2345
2349
  success: null,
2346
2350
  failure: {
@@ -2351,7 +2355,7 @@ class FilterCore extends BaseProtocol {
2351
2355
  }
2352
2356
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
2353
2357
  if (statusCode < 200 || statusCode >= 300) {
2354
- 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}`);
2355
2359
  return {
2356
2360
  failure: {
2357
2361
  error: ProtocolError.REMOTE_PEER_REJECTED,
@@ -2371,7 +2375,7 @@ class FilterCore extends BaseProtocol {
2371
2375
  stream = await this.getStream(peerId);
2372
2376
  }
2373
2377
  catch (error) {
2374
- 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);
2375
2379
  return {
2376
2380
  success: null,
2377
2381
  failure: {
@@ -2385,7 +2389,7 @@ class FilterCore extends BaseProtocol {
2385
2389
  await pipe([unsubscribeRequest.encode()], encode, stream.sink);
2386
2390
  }
2387
2391
  catch (error) {
2388
- log$5.error("Failed to send unsubscribe request", error);
2392
+ log$6.error("Failed to send unsubscribe request", error);
2389
2393
  return {
2390
2394
  success: null,
2391
2395
  failure: {
@@ -2414,7 +2418,7 @@ class FilterCore extends BaseProtocol {
2414
2418
  }
2415
2419
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
2416
2420
  if (statusCode < 200 || statusCode >= 300) {
2417
- 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}`);
2418
2422
  return {
2419
2423
  failure: {
2420
2424
  error: ProtocolError.REMOTE_PEER_REJECTED,
@@ -2434,7 +2438,7 @@ class FilterCore extends BaseProtocol {
2434
2438
  stream = await this.getStream(peerId);
2435
2439
  }
2436
2440
  catch (error) {
2437
- 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);
2438
2442
  return {
2439
2443
  success: null,
2440
2444
  failure: {
@@ -2449,7 +2453,7 @@ class FilterCore extends BaseProtocol {
2449
2453
  res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
2450
2454
  }
2451
2455
  catch (error) {
2452
- log$5.error("Failed to send ping request", error);
2456
+ log$6.error("Failed to send ping request", error);
2453
2457
  return {
2454
2458
  success: null,
2455
2459
  failure: {
@@ -2469,7 +2473,7 @@ class FilterCore extends BaseProtocol {
2469
2473
  }
2470
2474
  const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
2471
2475
  if (statusCode < 200 || statusCode >= 300) {
2472
- 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}`);
2473
2477
  return {
2474
2478
  success: null,
2475
2479
  failure: {
@@ -2486,30 +2490,30 @@ class FilterCore extends BaseProtocol {
2486
2490
  onRequest(streamData) {
2487
2491
  const { connection, stream } = streamData;
2488
2492
  const { remotePeer } = connection;
2489
- log$5.info(`Received message from ${remotePeer.toString()}`);
2493
+ log$6.info(`Received message from ${remotePeer.toString()}`);
2490
2494
  try {
2491
2495
  pipe(stream, decode, async (source) => {
2492
2496
  for await (const bytes of source) {
2493
2497
  const response = FilterPushRpc.decode(bytes.slice());
2494
2498
  const { pubsubTopic, wakuMessage } = response;
2495
2499
  if (!wakuMessage) {
2496
- log$5.error("Received empty message");
2500
+ log$6.error("Received empty message");
2497
2501
  return;
2498
2502
  }
2499
2503
  if (!pubsubTopic) {
2500
- log$5.error("Pubsub topic missing from push message");
2504
+ log$6.error("Pubsub topic missing from push message");
2501
2505
  return;
2502
2506
  }
2503
2507
  await FilterCore.handleIncomingMessage?.(pubsubTopic, wakuMessage, connection.remotePeer.toString());
2504
2508
  }
2505
2509
  }).then(() => {
2506
- log$5.info("Receiving pipe closed.");
2510
+ log$6.info("Receiving pipe closed.");
2507
2511
  }, async (e) => {
2508
- 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);
2509
2513
  });
2510
2514
  }
2511
2515
  catch (e) {
2512
- log$5.error("Error decoding message", e);
2516
+ log$6.error("Error decoding message", e);
2513
2517
  }
2514
2518
  }
2515
2519
  }
@@ -2520,13 +2524,13 @@ var index$2 = /*#__PURE__*/Object.freeze({
2520
2524
  FilterCore: FilterCore
2521
2525
  });
2522
2526
 
2523
- class PushRpc {
2527
+ class PushRpcV2 {
2524
2528
  proto;
2525
2529
  constructor(proto) {
2526
2530
  this.proto = proto;
2527
2531
  }
2528
2532
  static createRequest(message, pubsubTopic) {
2529
- return new PushRpc({
2533
+ return new PushRpcV2({
2530
2534
  requestId: v4(),
2531
2535
  request: {
2532
2536
  message: message,
@@ -2536,11 +2540,11 @@ class PushRpc {
2536
2540
  });
2537
2541
  }
2538
2542
  static decode(bytes) {
2539
- const res = PushRpc$1.decode(bytes);
2540
- return new PushRpc(res);
2543
+ const res = PushRpc.decode(bytes);
2544
+ return new PushRpcV2(res);
2541
2545
  }
2542
2546
  encode() {
2543
- return PushRpc$1.encode(this.proto);
2547
+ return PushRpc.encode(this.proto);
2544
2548
  }
2545
2549
  get query() {
2546
2550
  return this.proto.request;
@@ -2568,17 +2572,244 @@ const isRLNResponseError = (info) => {
2568
2572
  info.includes(RLN_REMOTE_VALIDATION));
2569
2573
  };
2570
2574
 
2571
- const log$4 = new Logger("light-push");
2575
+ const log$5 = new Logger("light-push");
2572
2576
  const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
2573
- /**
2574
- * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
2575
- */
2577
+ const LightPushCodecV2 = LightPushCodec;
2576
2578
  class LightPushCore extends BaseProtocol {
2577
2579
  pubsubTopics;
2578
2580
  constructor(pubsubTopics, libp2p) {
2579
2581
  super(LightPushCodec, libp2p.components, pubsubTopics);
2580
2582
  this.pubsubTopics = pubsubTopics;
2581
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
+ }
2582
2813
  async preparePushMessage(encoder, message) {
2583
2814
  try {
2584
2815
  if (!message.payload || message.payload.length === 0) {
@@ -2597,7 +2828,7 @@ class LightPushCore extends BaseProtocol {
2597
2828
  error: ProtocolError.ENCODE_FAILED
2598
2829
  };
2599
2830
  }
2600
- const query = PushRpc.createRequest(protoMessage, encoder.pubsubTopic);
2831
+ const query = PushRpcV3.createRequest(protoMessage, encoder.pubsubTopic);
2601
2832
  return { query, error: null };
2602
2833
  }
2603
2834
  catch (error) {
@@ -2638,7 +2869,6 @@ class LightPushCore extends BaseProtocol {
2638
2869
  res = await pipe([query.encode()], encode, stream, decode, async (source) => await all(source));
2639
2870
  }
2640
2871
  catch (err) {
2641
- // can fail only because of `stream` abortion
2642
2872
  log$4.error("Failed to send waku light push request", err);
2643
2873
  return {
2644
2874
  success: null,
@@ -2654,10 +2884,10 @@ class LightPushCore extends BaseProtocol {
2654
2884
  });
2655
2885
  let response;
2656
2886
  try {
2657
- response = PushRpc.decode(bytes).response;
2887
+ response = LightpushResponse.decode(bytes);
2658
2888
  }
2659
2889
  catch (err) {
2660
- log$4.error("Failed to decode push reply", err);
2890
+ log$4.error("Failed to decode push response", err);
2661
2891
  return {
2662
2892
  success: null,
2663
2893
  failure: {
@@ -2667,7 +2897,7 @@ class LightPushCore extends BaseProtocol {
2667
2897
  };
2668
2898
  }
2669
2899
  if (!response) {
2670
- log$4.error("Remote peer fault: No response in PushRPC");
2900
+ log$4.error("Remote peer fault: No response received");
2671
2901
  return {
2672
2902
  success: null,
2673
2903
  failure: {
@@ -2676,7 +2906,37 @@ class LightPushCore extends BaseProtocol {
2676
2906
  }
2677
2907
  };
2678
2908
  }
2679
- 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)) {
2680
2940
  log$4.error("Remote peer fault: RLN generation");
2681
2941
  return {
2682
2942
  success: null,
@@ -2686,12 +2946,14 @@ class LightPushCore extends BaseProtocol {
2686
2946
  }
2687
2947
  };
2688
2948
  }
2689
- if (!response.isSuccess) {
2690
- 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);
2691
2953
  return {
2692
2954
  success: null,
2693
2955
  failure: {
2694
- error: ProtocolError.REMOTE_PEER_REJECTED,
2956
+ error: protocolError,
2695
2957
  peerId: peerId
2696
2958
  }
2697
2959
  };
@@ -2700,11 +2962,74 @@ class LightPushCore extends BaseProtocol {
2700
2962
  }
2701
2963
  }
2702
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
+
2703
3013
  var index$1 = /*#__PURE__*/Object.freeze({
2704
3014
  __proto__: null,
2705
3015
  LightPushCodec: LightPushCodec,
3016
+ LightPushCodecV2: LightPushCodecV2,
3017
+ LightPushCodecV3: LightPushCodecV3,
2706
3018
  LightPushCore: LightPushCore,
2707
- 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
2708
3033
  });
2709
3034
 
2710
3035
  const EmptyMessage = {
@@ -2732,6 +3057,7 @@ class StoreQueryRequest {
2732
3057
  static create(params) {
2733
3058
  const request = new StoreQueryRequest({
2734
3059
  ...params,
3060
+ contentTopics: params.contentTopics || [],
2735
3061
  requestId: v4(),
2736
3062
  timeStart: params.timeStart
2737
3063
  ? BigInt(params.timeStart.getTime() * ONE_MILLION)
@@ -2744,17 +3070,22 @@ class StoreQueryRequest {
2744
3070
  ? BigInt(params.paginationLimit)
2745
3071
  : undefined
2746
3072
  });
2747
- // Validate request parameters based on RFC
2748
- if ((params.pubsubTopic && !params.contentTopics) ||
2749
- (!params.pubsubTopic && params.contentTopics)) {
2750
- throw new Error("Both pubsubTopic and contentTopics must be set or unset");
2751
- }
2752
- if (params.messageHashes &&
2753
- (params.pubsubTopic ||
2754
- params.contentTopics ||
2755
- params.timeStart ||
2756
- params.timeEnd)) {
2757
- 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
+ }
2758
3089
  }
2759
3090
  return request;
2760
3091
  }
@@ -2801,8 +3132,12 @@ class StoreCore extends BaseProtocol {
2801
3132
  this.pubsubTopics = pubsubTopics;
2802
3133
  }
2803
3134
  async *queryPerPage(queryOpts, decoders, peerId) {
2804
- if (queryOpts.contentTopics.toString() !==
2805
- 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()) {
2806
3141
  throw new Error("Internal error, the decoders should match the query's content topics");
2807
3142
  }
2808
3143
  let currentCursor = queryOpts.paginationCursor;
@@ -2811,6 +3146,12 @@ class StoreCore extends BaseProtocol {
2811
3146
  ...queryOpts,
2812
3147
  paginationCursor: currentCursor
2813
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
+ });
2814
3155
  let stream;
2815
3156
  try {
2816
3157
  stream = await this.getStream(peerId);
@@ -4404,7 +4745,7 @@ class ConnectionManager extends TypedEventEmitter {
4404
4745
  * // Dial using multiaddr with specific protocols
4405
4746
  * await connectionManager.dialPeer(multiaddr, [
4406
4747
  * "/vac/waku/relay/2.0.0",
4407
- * "/vac/waku/lightpush/2.0.0-beta1"
4748
+ * "/vac/waku/lightpush/3.0.0"
4408
4749
  * ]);
4409
4750
  * ```
4410
4751
  *
@@ -4872,4 +5213,85 @@ function wakuMetadata(pubsubTopics) {
4872
5213
  return (components) => new Metadata(pubsubTopics, components);
4873
5214
  }
4874
5215
 
4875
- 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 };