diff --git a/packages/core/src/lib/filter/index.ts b/packages/core/src/lib/filter/index.ts index 51a0b34de7..9e11840c52 100644 --- a/packages/core/src/lib/filter/index.ts +++ b/packages/core/src/lib/filter/index.ts @@ -11,6 +11,7 @@ import type { IDecoder, IFilter, IMessage, + ProtocolCreateOptions, ProtocolOptions, } from "@waku/interfaces"; import { @@ -43,18 +44,6 @@ export interface FilterComponents { connectionManager: ConnectionManager; } -export interface CreateOptions { - /** - * The PubSub Topic to use. Defaults to {@link DefaultPubSubTopic}. - * - * The usage of the default pubsub topic is recommended. - * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details. - * - * @default {@link DefaultPubSubTopic} - */ - pubSubTopic?: string; -} - export type UnsubscribeFunction = () => Promise; /** @@ -66,18 +55,21 @@ export type UnsubscribeFunction = () => Promise; */ class Filter implements IFilter { multicodec: string; - pubSubTopic: string; + options: ProtocolCreateOptions; private subscriptions: Map>; private decoders: Map< string, // content topic Set> >; - constructor(public components: FilterComponents, options?: CreateOptions) { + constructor( + public components: FilterComponents, + options?: ProtocolCreateOptions + ) { + this.options = options ?? {}; this.multicodec = FilterCodec; this.subscriptions = new Map(); this.decoders = new Map(); - this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic; this.components.registrar .handle(FilterCodec, this.onRequest.bind(this)) .catch((e) => log("Failed to register filter protocol", e)); @@ -94,7 +86,7 @@ class Filter implements IFilter { callback: Callback, opts?: ProtocolOptions ): Promise { - const topic = opts?.pubSubTopic ?? this.pubSubTopic; + const { pubSubTopic = DefaultPubSubTopic } = this.options; const groupedDecoders = groupByContentTopic(decoders); const contentTopics = Array.from(groupedDecoders.keys()); @@ -103,7 +95,7 @@ class Filter implements IFilter { contentTopic, })); const request = FilterRPC.createRequest( - topic, + pubSubTopic, contentFilters, undefined, true @@ -144,7 +136,7 @@ class Filter implements IFilter { this.addCallback(requestId, callback); return async () => { - await this.unsubscribe(topic, contentFilters, requestId, peer); + await this.unsubscribe(pubSubTopic, contentFilters, requestId, peer); this.deleteDecoders(groupedDecoders); this.deleteCallback(requestId); }; @@ -309,7 +301,7 @@ class Filter implements IFilter { } export function wakuFilter( - init: Partial = {} + init: Partial = {} ): (components: FilterComponents) => IFilter { return (components: FilterComponents) => new Filter(components, init); } diff --git a/packages/core/src/lib/light_push/index.ts b/packages/core/src/lib/light_push/index.ts index 6e89cb302c..4583cc23ec 100644 --- a/packages/core/src/lib/light_push/index.ts +++ b/packages/core/src/lib/light_push/index.ts @@ -6,6 +6,7 @@ import type { IEncoder, ILightPush, IMessage, + ProtocolCreateOptions, ProtocolOptions, SendResult, } from "@waku/interfaces"; @@ -36,28 +37,19 @@ export interface LightPushComponents { connectionManager: ConnectionManager; } -export interface CreateOptions { - /** - * The PubSub Topic to use. Defaults to {@link DefaultPubSubTopic}. - * - * The usage of the default pubsub topic is recommended. - * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details. - * - * @default {@link DefaultPubSubTopic} - */ - pubSubTopic?: string; -} - /** * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/). */ class LightPush implements ILightPush { multicodec: string; - pubSubTopic: string; + options: ProtocolCreateOptions; - constructor(public components: LightPushComponents, options?: CreateOptions) { + constructor( + public components: LightPushComponents, + options?: ProtocolCreateOptions + ) { this.multicodec = LightPushCodec; - this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic; + this.options = options || {}; } async push( @@ -65,11 +57,11 @@ class LightPush implements ILightPush { message: IMessage, opts?: ProtocolOptions ): Promise { - const pubSubTopic = opts?.pubSubTopic ? opts.pubSubTopic : this.pubSubTopic; + const { pubSubTopic = DefaultPubSubTopic } = this.options; const res = await selectPeerForProtocol( this.components.peerStore, - [LightPushCodec], + [this.multicodec], opts?.peerId ); @@ -152,7 +144,7 @@ class LightPush implements ILightPush { } export function wakuLightPush( - init: Partial = {} + init: Partial = {} ): (components: LightPushComponents) => ILightPush { return (components: LightPushComponents) => new LightPush(components, init); } diff --git a/packages/core/src/lib/relay/index.ts b/packages/core/src/lib/relay/index.ts index 6366a6151c..cf0d2b9116 100644 --- a/packages/core/src/lib/relay/index.ts +++ b/packages/core/src/lib/relay/index.ts @@ -12,6 +12,7 @@ import type { IEncoder, IMessage, IRelay, + ProtocolCreateOptions, SendResult, } from "@waku/interfaces"; import { IDecodedMessage } from "@waku/interfaces"; @@ -30,22 +31,7 @@ export type Observer = { callback: Callback; }; -export interface RelayCreateOptions extends GossipsubOpts { - /** - * The PubSub Topic to use. Defaults to {@link DefaultPubSubTopic}. - * - * One and only one pubsub topic is used by Waku. This is used by: - * - WakuRelay to receive, route and send messages, - * - WakuLightPush to send messages, - * - WakuStore to retrieve messages. - * - * The usage of the default pubsub topic is recommended. - * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details. - * - * @default {@link DefaultPubSubTopic} - */ - pubSubTopic?: string; -} +export type RelayCreateOptions = ProtocolCreateOptions & GossipsubOpts; /** * Implements the [Waku v2 Relay protocol](https://rfc.vac.dev/spec/11/). @@ -54,7 +40,7 @@ export interface RelayCreateOptions extends GossipsubOpts { * @implements {require('libp2p-interfaces/src/pubsub')} */ class Relay extends GossipSub implements IRelay { - pubSubTopic: string; + options: Partial; defaultDecoder: IDecoder; public static multicodec: string = constants.RelayCodecs[0]; @@ -73,12 +59,13 @@ class Relay extends GossipSub implements IRelay { globalSignaturePolicy: SignaturePolicy.StrictNoSign, fallbackToFloodsub: false, }); + super(components, options); this.multicodecs = constants.RelayCodecs; this.observers = new Map(); - this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic; + this.options = options ?? {}; // TODO: User might want to decide what decoder should be used (e.g. for RLN) this.defaultDecoder = new TopicOnlyDecoder(); @@ -92,20 +79,24 @@ class Relay extends GossipSub implements IRelay { * @returns {void} */ public async start(): Promise { + const { pubSubTopic = DefaultPubSubTopic } = this.options; await super.start(); - this.subscribe(this.pubSubTopic); + this.subscribe(pubSubTopic); } /** * Send Waku message. */ public async send(encoder: IEncoder, message: IMessage): Promise { + const { pubSubTopic = DefaultPubSubTopic } = this.options; + const msg = await encoder.toWire(message); if (!msg) { log("Failed to encode message, aborting publish"); return { recipients: [] }; } - return this.publish(this.pubSubTopic, msg); + + return this.publish(pubSubTopic, msg); } /** @@ -181,7 +172,8 @@ class Relay extends GossipSub implements IRelay { } getMeshPeers(topic?: TopicStr): PeerIdStr[] { - return super.getMeshPeers(topic ?? this.pubSubTopic); + const { pubSubTopic = DefaultPubSubTopic } = this.options; + return super.getMeshPeers(topic ?? pubSubTopic); } } diff --git a/packages/core/src/lib/store/index.ts b/packages/core/src/lib/store/index.ts index 22faca1c33..6ab67db46a 100644 --- a/packages/core/src/lib/store/index.ts +++ b/packages/core/src/lib/store/index.ts @@ -10,6 +10,7 @@ import { IDecoder, Index, IStore, + ProtocolCreateOptions, } from "@waku/interfaces"; import { getPeersForProtocol, @@ -43,18 +44,6 @@ export interface StoreComponents { connectionManager: ConnectionManager; } -export interface CreateOptions { - /** - * The PubSub Topic to use. Defaults to {@link DefaultPubSubTopic}. - * - * The usage of the default pubsub topic is recommended. - * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details. - * - * @default {@link DefaultPubSubTopic} - */ - pubSubTopic?: string; -} - export interface TimeFilter { startTime: Date; endTime: Date; @@ -65,11 +54,6 @@ export interface QueryOptions { * The peer to query. If undefined, a pseudo-random peer is selected from the connected Waku Store peers. */ peerId?: PeerId; - /** - * The pubsub topic to pass to the query. - * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/). - */ - pubSubTopic?: string; /** * The direction in which pages are retrieved: * - { @link PageDirection.BACKWARD }: Most recent page first. @@ -106,11 +90,14 @@ export interface QueryOptions { */ class Store implements IStore { multicodec: string; - pubSubTopic: string; + options: ProtocolCreateOptions; - constructor(public components: StoreComponents, options?: CreateOptions) { + constructor( + public components: StoreComponents, + options?: ProtocolCreateOptions + ) { this.multicodec = StoreCodec; - this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic; + this.options = options ?? {}; } /** @@ -221,6 +208,8 @@ class Store implements IStore { decoders: IDecoder[], options?: QueryOptions ): AsyncGenerator[]> { + const { pubSubTopic = DefaultPubSubTopic } = this.options; + let startTime, endTime; if (options?.timeFilter) { @@ -242,7 +231,7 @@ class Store implements IStore { const queryOpts = Object.assign( { - pubSubTopic: this.pubSubTopic, + pubSubTopic: pubSubTopic, pageDirection: PageDirection.BACKWARD, pageSize: DefaultPageSize, }, @@ -433,7 +422,7 @@ export async function createCursor( } export function wakuStore( - init: Partial = {} + init: Partial = {} ): (components: StoreComponents) => IStore { return (components: StoreComponents) => new Store(components, init); } diff --git a/packages/create/src/index.ts b/packages/create/src/index.ts index 7e16df48e5..0e8bf5165a 100644 --- a/packages/create/src/index.ts +++ b/packages/create/src/index.ts @@ -88,7 +88,8 @@ export async function createLightNode( const store = wakuStore(options); const lightPush = wakuLightPush(options); const filter = wakuFilter(options); - const peerExchange = wakuPeerExchange(options); + + const peerExchange = wakuPeerExchange(); return new WakuNode( options ?? {}, @@ -155,7 +156,8 @@ export async function createFullNode( const store = wakuStore(options); const lightPush = wakuLightPush(options); const filter = wakuFilter(options); - const peerExchange = wakuPeerExchange(options); + + const peerExchange = wakuPeerExchange(); return new WakuNode( options ?? {}, diff --git a/packages/interfaces/src/protocols.ts b/packages/interfaces/src/protocols.ts index 2c3e670fc6..10af541eba 100644 --- a/packages/interfaces/src/protocols.ts +++ b/packages/interfaces/src/protocols.ts @@ -17,8 +17,26 @@ export interface PointToPointProtocol { peers: () => Promise; } -export type ProtocolOptions = { +export type ProtocolCreateOptions = { + /** + * The PubSub Topic to use. Defaults to {@link @waku/core/DefaultPubSubTopic }. + * + * One and only one pubsub topic is used by Waku. This is used by: + * - WakuRelay to receive, route and send messages, + * - WakuLightPush to send messages, + * - WakuStore to retrieve messages. + * + * The usage of the default pubsub topic is recommended. + * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details. + * + */ pubSubTopic?: string; +}; + +//TODO +// we can probably move `peerId` into `ProtocolCreateOptions` and remove `ProtocolOptions` and pass it in the constructor +// however, filter protocol can use multiple peers, so we need to think about this +export type ProtocolOptions = { /** * Optionally specify an PeerId for the protocol request. If not included, will use a random peer. */ diff --git a/packages/peer-exchange/src/waku_peer_exchange.ts b/packages/peer-exchange/src/waku_peer_exchange.ts index 49a2f1103a..d5a94c2fbf 100644 --- a/packages/peer-exchange/src/waku_peer_exchange.ts +++ b/packages/peer-exchange/src/waku_peer_exchange.ts @@ -8,7 +8,6 @@ import type { PeerExchangeComponents, PeerExchangeQueryParams, PeerExchangeResponse, - ProtocolOptions, } from "@waku/interfaces"; import { getPeersForProtocol, @@ -37,12 +36,8 @@ export class WakuPeerExchange implements IPeerExchange { /** * @param components - libp2p components - * @param createOptions - Options for the protocol */ - constructor( - public components: PeerExchangeComponents, - public createOptions?: ProtocolOptions - ) { + constructor(public components: PeerExchangeComponents) { this.multicodec = PeerExchangeCodec; this.components.registrar .handle(PeerExchangeCodec, this.handler.bind(this)) @@ -159,12 +154,11 @@ export class WakuPeerExchange implements IPeerExchange { /** * - * @param init - Options for the protocol * @returns A function that creates a new peer exchange protocol */ -export function wakuPeerExchange( - init: Partial = {} -): (components: PeerExchangeComponents) => WakuPeerExchange { +export function wakuPeerExchange(): ( + components: PeerExchangeComponents +) => WakuPeerExchange { return (components: PeerExchangeComponents) => - new WakuPeerExchange(components, init); + new WakuPeerExchange(components); } diff --git a/packages/tests/tests/light_push.node.spec.ts b/packages/tests/tests/light_push.node.spec.ts index cd16d7606e..ba8bda1734 100644 --- a/packages/tests/tests/light_push.node.spec.ts +++ b/packages/tests/tests/light_push.node.spec.ts @@ -89,7 +89,6 @@ describe("Waku Light Push [node only]", () => { { payload: utf8ToBytes(messageText) }, { peerId: nimPeerId, - pubSubTopic: customPubSubTopic, } ); log("Ack received", pushResponse);