@waku/core 0.0.36-a7f52e4.0 → 0.0.36-a8ca168.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.
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$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, o as concat$1, q as sha256, r as bytesToHex, w as numberToBytes } from './version_0-CyeTW0Vr.js';
2
+ export { x as createDecoder } from './version_0-CyeTW0Vr.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
  /**
@@ -2300,12 +2304,30 @@ const FilterCodecs = {
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$5.error("Previous FilterCore incoming message handler failed ", e);
2322
+ }
2323
+ try {
2324
+ await handleIncomingMessage(pubsubTopic, message, peerIdStr);
2325
+ }
2326
+ catch (e) {
2327
+ log$5.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
@@ -2482,7 +2504,7 @@ class FilterCore extends BaseProtocol {
2482
2504
  log$5.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
2510
  log$5.info("Receiving pipe closed.");
@@ -2714,6 +2736,7 @@ class StoreQueryRequest {
2714
2736
  static create(params) {
2715
2737
  const request = new StoreQueryRequest({
2716
2738
  ...params,
2739
+ contentTopics: params.contentTopics || [],
2717
2740
  requestId: v4(),
2718
2741
  timeStart: params.timeStart
2719
2742
  ? BigInt(params.timeStart.getTime() * ONE_MILLION)
@@ -2726,17 +2749,22 @@ class StoreQueryRequest {
2726
2749
  ? BigInt(params.paginationLimit)
2727
2750
  : undefined
2728
2751
  });
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");
2752
+ const isHashQuery = params.messageHashes && params.messageHashes.length > 0;
2753
+ const hasContentTopics = params.contentTopics && params.contentTopics.length > 0;
2754
+ const hasTimeFilter = params.timeStart || params.timeEnd;
2755
+ if (isHashQuery) {
2756
+ if (hasContentTopics || hasTimeFilter) {
2757
+ throw new Error("Message hash lookup queries cannot include content filter criteria (contentTopics, timeStart, or timeEnd)");
2758
+ }
2759
+ }
2760
+ else {
2761
+ if ((params.pubsubTopic &&
2762
+ (!params.contentTopics || params.contentTopics.length === 0)) ||
2763
+ (!params.pubsubTopic &&
2764
+ params.contentTopics &&
2765
+ params.contentTopics.length > 0)) {
2766
+ throw new Error("Both pubsubTopic and contentTopics must be set together for content-filtered queries");
2767
+ }
2740
2768
  }
2741
2769
  return request;
2742
2770
  }
@@ -2783,8 +2811,12 @@ class StoreCore extends BaseProtocol {
2783
2811
  this.pubsubTopics = pubsubTopics;
2784
2812
  }
2785
2813
  async *queryPerPage(queryOpts, decoders, peerId) {
2786
- if (queryOpts.contentTopics.toString() !==
2787
- Array.from(decoders.keys()).toString()) {
2814
+ // Only validate decoder content topics for content-filtered queries
2815
+ const isHashQuery = queryOpts.messageHashes && queryOpts.messageHashes.length > 0;
2816
+ if (!isHashQuery &&
2817
+ queryOpts.contentTopics &&
2818
+ queryOpts.contentTopics.toString() !==
2819
+ Array.from(decoders.keys()).toString()) {
2788
2820
  throw new Error("Internal error, the decoders should match the query's content topics");
2789
2821
  }
2790
2822
  let currentCursor = queryOpts.paginationCursor;
@@ -2793,6 +2825,12 @@ class StoreCore extends BaseProtocol {
2793
2825
  ...queryOpts,
2794
2826
  paginationCursor: currentCursor
2795
2827
  });
2828
+ log$3.info("Sending store query request:", {
2829
+ hasMessageHashes: !!queryOpts.messageHashes?.length,
2830
+ messageHashCount: queryOpts.messageHashes?.length,
2831
+ pubsubTopic: queryOpts.pubsubTopic,
2832
+ contentTopics: queryOpts.contentTopics
2833
+ });
2796
2834
  let stream;
2797
2835
  try {
2798
2836
  stream = await this.getStream(peerId);
@@ -4854,4 +4892,85 @@ function wakuMetadata(pubsubTopics) {
4854
4892
  return (components) => new Metadata(pubsubTopics, components);
4855
4893
  }
4856
4894
 
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 };
4895
+ /**
4896
+ * Deterministic Message Hashing as defined in
4897
+ * [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/#deterministic-message-hashing)
4898
+ *
4899
+ * Computes a SHA-256 hash of the concatenation of pubsub topic, payload, content topic, meta, and timestamp.
4900
+ *
4901
+ * @param pubsubTopic - The pubsub topic string
4902
+ * @param message - The message to be hashed
4903
+ * @returns A Uint8Array containing the SHA-256 hash
4904
+ *
4905
+ * @example
4906
+ * ```typescript
4907
+ * import { messageHash } from "@waku/core";
4908
+ *
4909
+ * const pubsubTopic = "/waku/2/default-waku/proto";
4910
+ * const message = {
4911
+ * payload: new Uint8Array([1, 2, 3, 4]),
4912
+ * contentTopic: "/waku/2/default-content/proto",
4913
+ * meta: new Uint8Array([5, 6, 7, 8]),
4914
+ * timestamp: new Date()
4915
+ * };
4916
+ *
4917
+ * const hash = messageHash(pubsubTopic, message);
4918
+ * ```
4919
+ */
4920
+ function messageHash(pubsubTopic, message) {
4921
+ const pubsubTopicBytes = utf8ToBytes(pubsubTopic);
4922
+ const contentTopicBytes = utf8ToBytes(message.contentTopic);
4923
+ const timestampBytes = tryConvertTimestampToBytes(message.timestamp);
4924
+ const bytes = concat$1([
4925
+ pubsubTopicBytes,
4926
+ message.payload,
4927
+ contentTopicBytes,
4928
+ message.meta,
4929
+ timestampBytes
4930
+ ].filter(isDefined));
4931
+ return sha256(bytes);
4932
+ }
4933
+ function tryConvertTimestampToBytes(timestamp) {
4934
+ if (!timestamp) {
4935
+ return;
4936
+ }
4937
+ let bigIntTimestamp;
4938
+ if (typeof timestamp === "bigint") {
4939
+ bigIntTimestamp = timestamp;
4940
+ }
4941
+ else {
4942
+ bigIntTimestamp = BigInt(timestamp.valueOf()) * 1000000n;
4943
+ }
4944
+ return numberToBytes(bigIntTimestamp);
4945
+ }
4946
+ /**
4947
+ * Computes a deterministic message hash and returns it as a hexadecimal string.
4948
+ * This is a convenience wrapper around messageHash that converts the result to a hex string.
4949
+ *
4950
+ * @param pubsubTopic - The pubsub topic string
4951
+ * @param message - The message to be hashed
4952
+ * @returns A string containing the hex representation of the SHA-256 hash
4953
+ *
4954
+ * @example
4955
+ * ```typescript
4956
+ * import { messageHashStr } from "@waku/core";
4957
+ *
4958
+ * const pubsubTopic = "/waku/2/default-waku/proto";
4959
+ * const message = {
4960
+ * payload: new Uint8Array([1, 2, 3, 4]),
4961
+ * contentTopic: "/waku/2/default-content/proto",
4962
+ * meta: new Uint8Array([5, 6, 7, 8]),
4963
+ * timestamp: new Date()
4964
+ * };
4965
+ *
4966
+ * const hashString = messageHashStr(pubsubTopic, message);
4967
+ * console.log(hashString); // e.g. "a1b2c3d4..."
4968
+ * ```
4969
+ */
4970
+ function messageHashStr(pubsubTopic, message) {
4971
+ const hash = messageHash(pubsubTopic, message);
4972
+ const hashStr = bytesToHex(hash);
4973
+ return hashStr;
4974
+ }
4975
+
4976
+ export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCore, MetadataCodec, StoreCodec, StoreCore, createEncoder, index$3 as message, messageHash, messageHashStr, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
@@ -1,2 +1,2 @@
1
- export { D as DecodedMessage, r as Decoder, E as Encoder, V as Version, o as createDecoder, k as createEncoder, q as proto } from '../../version_0-CiYGrPc2.js';
1
+ export { D as DecodedMessage, z as Decoder, E as Encoder, V as Version, x as createDecoder, k as createEncoder, y as proto } from '../../version_0-CyeTW0Vr.js';
2
2
  import '../../index-CTo1my9M.js';
@@ -4350,6 +4350,21 @@ function toString(array, encoding = 'utf8') {
4350
4350
  return base.encoder.encode(array).substring(1);
4351
4351
  }
4352
4352
 
4353
+ function numberToBytes(value) {
4354
+ const buffer = new ArrayBuffer(8);
4355
+ const view = new DataView(buffer);
4356
+ if (typeof value === "number") {
4357
+ view.setFloat64(0, value, false);
4358
+ }
4359
+ else {
4360
+ view.setBigInt64(0, value, false);
4361
+ }
4362
+ return new Uint8Array(buffer);
4363
+ }
4364
+ /**
4365
+ * Convert byte array to hex string (no `0x` prefix).
4366
+ */
4367
+ const bytesToHex = (bytes) => toString(bytes, "base16");
4353
4368
  /**
4354
4369
  * Decode byte array to utf-8 string.
4355
4370
  */
@@ -4532,9 +4547,6 @@ class DecodedMessage {
4532
4547
  get contentTopic() {
4533
4548
  return this.proto.contentTopic;
4534
4549
  }
4535
- get _rawTimestamp() {
4536
- return this.proto.timestamp;
4537
- }
4538
4550
  get timestamp() {
4539
4551
  // In the case we receive a value that is bigger than JS's max number,
4540
4552
  // we catch the error and return undefined.
@@ -4556,7 +4568,7 @@ class DecodedMessage {
4556
4568
  get version() {
4557
4569
  // https://rfc.vac.dev/spec/14/
4558
4570
  // > If omitted, the value SHOULD be interpreted as version 0.
4559
- return this.proto.version ?? 0;
4571
+ return this.proto.version ?? Version;
4560
4572
  }
4561
4573
  get rateLimitProof() {
4562
4574
  return this.proto.rateLimitProof;
@@ -4665,4 +4677,4 @@ var version_0 = /*#__PURE__*/Object.freeze({
4665
4677
  proto: message
4666
4678
  });
4667
4679
 
4668
- export { DecodedMessage as D, Encoder as E, FilterSubscribeRequest as F, MessagePush as M, PushRpc$1 as P, StoreQueryRequest$1 as S, Version as V, WakuMetadataRequest as W, allocUnsafe as a, alloc$1 as b, encode as c, decode as d, encodingLength as e, FilterSubscribeResponse$1 as f, PushResponse as g, StoreQueryResponse$1 as h, bases as i, fromString as j, createEncoder as k, bytesToUtf8 as l, pubsubTopicsToShardInfo as m, WakuMetadataResponse as n, createDecoder as o, pubsubTopicToSingleShardInfo as p, message as q, Decoder as r, shardInfoToPubsubTopics as s, toString as t, utf8ToBytes as u, version_0 as v };
4680
+ export { DecodedMessage as D, Encoder as E, FilterSubscribeRequest as F, MessagePush as M, PushRpc$1 as P, StoreQueryRequest$1 as S, Version as V, WakuMetadataRequest as W, allocUnsafe as a, alloc$1 as b, encode as c, decode as d, encodingLength as e, FilterSubscribeResponse$1 as f, PushResponse as g, StoreQueryResponse$1 as h, bases as i, fromString as j, createEncoder as k, bytesToUtf8 as l, pubsubTopicsToShardInfo as m, WakuMetadataResponse as n, concat as o, pubsubTopicToSingleShardInfo as p, sha256 as q, bytesToHex as r, shardInfoToPubsubTopics as s, toString as t, utf8ToBytes as u, version_0 as v, numberToBytes as w, createDecoder as x, message as y, Decoder as z };