diff --git a/packages/interfaces/src/filter.ts b/packages/interfaces/src/filter.ts new file mode 100644 index 0000000000..5e5736a94e --- /dev/null +++ b/packages/interfaces/src/filter.ts @@ -0,0 +1,14 @@ +import type { DecodedMessage, Decoder } from "./message.js"; +import type { + Callback, + PointToPointProtocol, + ProtocolOptions, +} from "./protocols.js"; + +export interface Filter extends PointToPointProtocol { + subscribe: ( + decoders: Decoder[], + callback: Callback, + opts?: ProtocolOptions + ) => Promise<() => Promise>; +} diff --git a/packages/interfaces/src/index.ts b/packages/interfaces/src/index.ts index b9598d6f6f..3e9c3f3948 100644 --- a/packages/interfaces/src/index.ts +++ b/packages/interfaces/src/index.ts @@ -1,247 +1,8 @@ -import type { GossipSub } from "@chainsafe/libp2p-gossipsub"; -import type { Stream } from "@libp2p/interface-connection"; -import type { ConnectionManager } from "@libp2p/interface-connection-manager"; -import type { PeerId } from "@libp2p/interface-peer-id"; -import type { Peer } from "@libp2p/interface-peer-store"; -import type { PeerStore } from "@libp2p/interface-peer-store"; -import type { Registrar } from "@libp2p/interface-registrar"; -import type { Multiaddr } from "@multiformats/multiaddr"; -import { ENR } from "@waku/enr"; -import type { Libp2p } from "libp2p"; - -export enum Protocols { - Relay = "relay", - Store = "store", - LightPush = "lightpush", - Filter = "filter", - PeerExchange = "peer-exchange", -} - -export interface PointToPointProtocol { - peerStore: PeerStore; - peers: () => Promise; -} -export interface Index { - digest?: Uint8Array; - receivedTime?: bigint; - senderTime?: bigint; - pubsubTopic?: string; -} - -export type ProtocolOptions = { - pubSubTopic?: string; - /** - * Optionally specify an PeerId for the protocol request. If not included, will use a random peer. - */ - peerId?: PeerId; -}; - -export type Callback = (msg: T) => void | Promise; - -export interface Filter extends PointToPointProtocol { - subscribe: ( - decoders: Decoder[], - callback: Callback, - opts?: ProtocolOptions - ) => Promise<() => Promise>; -} - -export interface LightPush extends PointToPointProtocol { - push: ( - encoder: Encoder, - message: Message, - opts?: ProtocolOptions - ) => Promise; -} - -export interface PeerExchange extends PointToPointProtocol { - query( - params: PeerExchangeQueryParams, - callback: (response: PeerExchangeResponse) => Promise | void - ): Promise; -} - -export interface PeerExchangeQueryParams { - numPeers: number; -} - -export interface PeerExchangeResponse { - peerInfos: PeerInfo[]; -} - -export interface PeerInfo { - ENR?: ENR; -} - -export enum PageDirection { - BACKWARD = "backward", - FORWARD = "forward", -} - -export interface TimeFilter { - startTime: Date; - endTime: Date; -} - -export interface PeerExchangeComponents { - connectionManager: ConnectionManager; - peerStore: PeerStore; - registrar: Registrar; -} -export type Cursor = { - digest?: Uint8Array; - senderTime?: bigint; - pubsubTopic?: string; -}; - -export type StoreQueryOptions = { - /** - * The direction in which pages are retrieved: - * - { @link PageDirection.BACKWARD }: Most recent page first. - * - { @link PageDirection.FORWARD }: Oldest page first. - * - * Note: This does not affect the ordering of messages with the page - * (the oldest message is always first). - * - * @default { @link PageDirection.BACKWARD } - */ - pageDirection?: PageDirection; - /** - * The number of message per page. - */ - pageSize?: number; - /** - * Retrieve messages with a timestamp within the provided values. - */ - timeFilter?: TimeFilter; - /** - * Cursor as an index to start a query from. - */ - cursor?: Cursor; -} & ProtocolOptions; - -export interface Store extends PointToPointProtocol { - queryOrderedCallback: ( - decoders: Decoder[], - callback: (message: T) => Promise | boolean | void, - options?: StoreQueryOptions - ) => Promise; - queryCallbackOnPromise: ( - decoders: Decoder[], - callback: ( - message: Promise - ) => Promise | boolean | void, - options?: StoreQueryOptions - ) => Promise; - queryGenerator: ( - decoders: Decoder[], - options?: StoreQueryOptions - ) => AsyncGenerator[]>; -} - -export interface Relay extends GossipSub { - send: (encoder: Encoder, message: Message) => Promise; - addObserver: ( - decoder: Decoder, - callback: Callback - ) => () => void; - getMeshPeers: () => string[]; -} - -export interface Waku { - libp2p: Libp2p; - relay?: Relay; - store?: Store; - filter?: Filter; - lightPush?: LightPush; - peerExchange?: PeerExchange; - - dial(peer: PeerId | Multiaddr, protocols?: Protocols[]): Promise; - - start(): Promise; - - stop(): Promise; - - isStarted(): boolean; -} - -export interface WakuLight extends Waku { - relay: undefined; - store: Store; - filter: Filter; - lightPush: LightPush; - peerExchange: PeerExchange; -} - -export interface WakuPrivacy extends Waku { - relay: Relay; - store: undefined; - filter: undefined; - lightPush: undefined; - peerExchange: undefined; -} - -export interface WakuFull extends Waku { - relay: Relay; - store: Store; - filter: Filter; - lightPush: LightPush; - peerExchange: PeerExchange; -} - -export interface RateLimitProof { - proof: Uint8Array; - merkleRoot: Uint8Array; - epoch: Uint8Array; - shareX: Uint8Array; - shareY: Uint8Array; - nullifier: Uint8Array; - rlnIdentifier: Uint8Array; -} - -/** - * Interface matching the protobuf library. - * Field types matches the protobuf type over the wire - */ -export interface ProtoMessage { - payload: Uint8Array | undefined; - contentTopic: string | undefined; - version: number | undefined; - timestamp: bigint | undefined; - rateLimitProof: RateLimitProof | undefined; - ephemeral: boolean | undefined; -} - -/** - * Interface for messages to encode and send. - */ -export interface Message { - payload?: Uint8Array; - timestamp?: Date; - rateLimitProof?: RateLimitProof; -} - -export interface Encoder { - contentTopic: string; - ephemeral: boolean; - toWire: (message: Message) => Promise; - toProtoObj: (message: Message) => Promise; -} - -export interface DecodedMessage { - payload: Uint8Array | undefined; - contentTopic: string | undefined; - timestamp: Date | undefined; - rateLimitProof: RateLimitProof | undefined; - ephemeral: boolean | undefined; -} - -export interface Decoder { - contentTopic: string; - fromWireToProtoObj: (bytes: Uint8Array) => Promise; - fromProtoObj: (proto: ProtoMessage) => Promise; -} - -export interface SendResult { - recipients: PeerId[]; -} +export * from "./filter.js"; +export * from "./light_push.js"; +export * from "./message.js"; +export * from "./peer_exchange.js"; +export * from "./protocols.js"; +export * from "./relay.js"; +export * from "./store.js"; +export * from "./waku.js"; diff --git a/packages/interfaces/src/light_push.ts b/packages/interfaces/src/light_push.ts new file mode 100644 index 0000000000..7d63ce0023 --- /dev/null +++ b/packages/interfaces/src/light_push.ts @@ -0,0 +1,14 @@ +import type { Encoder, Message } from "./message.js"; +import type { + PointToPointProtocol, + ProtocolOptions, + SendResult, +} from "./protocols.js"; + +export interface LightPush extends PointToPointProtocol { + push: ( + encoder: Encoder, + message: Message, + opts?: ProtocolOptions + ) => Promise; +} diff --git a/packages/interfaces/src/message.ts b/packages/interfaces/src/message.ts new file mode 100644 index 0000000000..08f1ec6e33 --- /dev/null +++ b/packages/interfaces/src/message.ts @@ -0,0 +1,52 @@ +export interface RateLimitProof { + proof: Uint8Array; + merkleRoot: Uint8Array; + epoch: Uint8Array; + shareX: Uint8Array; + shareY: Uint8Array; + nullifier: Uint8Array; + rlnIdentifier: Uint8Array; +} + +/** + * Interface matching the protobuf library. + * Field types matches the protobuf type over the wire + */ +export interface ProtoMessage { + payload: Uint8Array | undefined; + contentTopic: string | undefined; + version: number | undefined; + timestamp: bigint | undefined; + rateLimitProof: RateLimitProof | undefined; + ephemeral: boolean | undefined; +} + +/** + * Interface for messages to encode and send. + */ +export interface Message { + payload?: Uint8Array; + timestamp?: Date; + rateLimitProof?: RateLimitProof; +} + +export interface Encoder { + contentTopic: string; + ephemeral: boolean; + toWire: (message: Message) => Promise; + toProtoObj: (message: Message) => Promise; +} + +export interface DecodedMessage { + payload: Uint8Array | undefined; + contentTopic: string | undefined; + timestamp: Date | undefined; + rateLimitProof: RateLimitProof | undefined; + ephemeral: boolean | undefined; +} + +export interface Decoder { + contentTopic: string; + fromWireToProtoObj: (bytes: Uint8Array) => Promise; + fromProtoObj: (proto: ProtoMessage) => Promise; +} diff --git a/packages/interfaces/src/peer_exchange.ts b/packages/interfaces/src/peer_exchange.ts new file mode 100644 index 0000000000..05359e25da --- /dev/null +++ b/packages/interfaces/src/peer_exchange.ts @@ -0,0 +1,31 @@ +import type { ConnectionManager } from "@libp2p/interface-connection-manager"; +import type { PeerStore } from "@libp2p/interface-peer-store"; +import type { Registrar } from "@libp2p/interface-registrar"; +import { ENR } from "@waku/enr"; + +import { PointToPointProtocol } from "./protocols.js"; + +export interface PeerExchange extends PointToPointProtocol { + query( + params: PeerExchangeQueryParams, + callback: (response: PeerExchangeResponse) => Promise | void + ): Promise; +} + +export interface PeerExchangeQueryParams { + numPeers: number; +} + +export interface PeerExchangeResponse { + peerInfos: PeerInfo[]; +} + +export interface PeerInfo { + ENR?: ENR; +} + +export interface PeerExchangeComponents { + connectionManager: ConnectionManager; + peerStore: PeerStore; + registrar: Registrar; +} diff --git a/packages/interfaces/src/protocols.ts b/packages/interfaces/src/protocols.ts new file mode 100644 index 0000000000..2e97985477 --- /dev/null +++ b/packages/interfaces/src/protocols.ts @@ -0,0 +1,31 @@ +import type { PeerId } from "@libp2p/interface-peer-id"; +import type { Peer, PeerStore } from "@libp2p/interface-peer-store"; + +import type { Message } from "./message.js"; + +export enum Protocols { + Relay = "relay", + Store = "store", + LightPush = "lightpush", + Filter = "filter", + PeerExchange = "peer-exchange", +} + +export interface PointToPointProtocol { + peerStore: PeerStore; + peers: () => Promise; +} + +export type ProtocolOptions = { + pubSubTopic?: string; + /** + * Optionally specify an PeerId for the protocol request. If not included, will use a random peer. + */ + peerId?: PeerId; +}; + +export type Callback = (msg: T) => void | Promise; + +export interface SendResult { + recipients: PeerId[]; +} diff --git a/packages/interfaces/src/relay.ts b/packages/interfaces/src/relay.ts new file mode 100644 index 0000000000..f1b33e3501 --- /dev/null +++ b/packages/interfaces/src/relay.ts @@ -0,0 +1,13 @@ +import type { GossipSub } from "@chainsafe/libp2p-gossipsub"; + +import type { DecodedMessage, Decoder, Encoder, Message } from "./message.js"; +import type { Callback, SendResult } from "./protocols.js"; + +export interface Relay extends GossipSub { + send: (encoder: Encoder, message: Message) => Promise; + addObserver: ( + decoder: Decoder, + callback: Callback + ) => () => void; + getMeshPeers: () => string[]; +} diff --git a/packages/interfaces/src/store.ts b/packages/interfaces/src/store.ts new file mode 100644 index 0000000000..0eacd2dc90 --- /dev/null +++ b/packages/interfaces/src/store.ts @@ -0,0 +1,70 @@ +import type { DecodedMessage, Decoder } from "./message.js"; +import type { PointToPointProtocol, ProtocolOptions } from "./protocols.js"; + +export enum PageDirection { + BACKWARD = "backward", + FORWARD = "forward", +} + +export interface TimeFilter { + startTime: Date; + endTime: Date; +} + +export interface Index { + digest?: Uint8Array; + receivedTime?: bigint; + senderTime?: bigint; + pubsubTopic?: string; +} + +export type Cursor = { + digest?: Uint8Array; + senderTime?: bigint; + pubsubTopic?: string; +}; + +export type StoreQueryOptions = { + /** + * The direction in which pages are retrieved: + * - { @link PageDirection.BACKWARD }: Most recent page first. + * - { @link PageDirection.FORWARD }: Oldest page first. + * + * Note: This does not affect the ordering of messages with the page + * (the oldest message is always first). + * + * @default { @link PageDirection.BACKWARD } + */ + pageDirection?: PageDirection; + /** + * The number of message per page. + */ + pageSize?: number; + /** + * Retrieve messages with a timestamp within the provided values. + */ + timeFilter?: TimeFilter; + /** + * Cursor as an index to start a query from. + */ + cursor?: Cursor; +} & ProtocolOptions; + +export interface Store extends PointToPointProtocol { + queryOrderedCallback: ( + decoders: Decoder[], + callback: (message: T) => Promise | boolean | void, + options?: StoreQueryOptions + ) => Promise; + queryCallbackOnPromise: ( + decoders: Decoder[], + callback: ( + message: Promise + ) => Promise | boolean | void, + options?: StoreQueryOptions + ) => Promise; + queryGenerator: ( + decoders: Decoder[], + options?: StoreQueryOptions + ) => AsyncGenerator[]>; +} diff --git a/packages/interfaces/src/waku.ts b/packages/interfaces/src/waku.ts new file mode 100644 index 0000000000..19e0e429ff --- /dev/null +++ b/packages/interfaces/src/waku.ts @@ -0,0 +1,52 @@ +import type { Stream } from "@libp2p/interface-connection"; +import type { PeerId } from "@libp2p/interface-peer-id"; +import type { Multiaddr } from "@multiformats/multiaddr"; +import type { Libp2p } from "libp2p"; + +import type { Filter } from "./filter.js"; +import type { LightPush } from "./light_push.js"; +import type { PeerExchange } from "./peer_exchange.js"; +import { Protocols } from "./protocols.js"; +import type { Relay } from "./relay.js"; +import type { Store } from "./store.js"; + +export interface Waku { + libp2p: Libp2p; + relay?: Relay; + store?: Store; + filter?: Filter; + lightPush?: LightPush; + peerExchange?: PeerExchange; + + dial(peer: PeerId | Multiaddr, protocols?: Protocols[]): Promise; + + start(): Promise; + + stop(): Promise; + + isStarted(): boolean; +} + +export interface WakuLight extends Waku { + relay: undefined; + store: Store; + filter: Filter; + lightPush: LightPush; + peerExchange: PeerExchange; +} + +export interface WakuPrivacy extends Waku { + relay: Relay; + store: undefined; + filter: undefined; + lightPush: undefined; + peerExchange: undefined; +} + +export interface WakuFull extends Waku { + relay: Relay; + store: Store; + filter: Filter; + lightPush: LightPush; + peerExchange: PeerExchange; +}