diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e7dcc8bcc..c18548745a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- **Breaking**: Options passed to `Waku.create` used to be passed to `Libp2p.create`; + Now, only the `libp2p` property is passed to `Libp2p.create`, allowing for a cleaner interface. + ### Added - Enable access to `WakuMessage.timestamp`. - Examples (web chat): Use `WakuMessage.timestamp` as unique key for list items. diff --git a/examples/cli-chat/src/chat.ts b/examples/cli-chat/src/chat.ts index 32d286740e..0f29881e73 100644 --- a/examples/cli-chat/src/chat.ts +++ b/examples/cli-chat/src/chat.ts @@ -27,8 +27,10 @@ export default async function startChat(): Promise { } const waku = await Waku.create({ - listenAddresses: [opts.listenAddr], - modules: { transport: [TCP] }, + libp2p: { + addresses: { listen: [opts.listenAddr] }, + modules: { transport: [TCP] }, + }, }); console.log('PeerId: ', waku.libp2p.peerId.toB58String()); console.log('Listening on '); diff --git a/examples/web-chat/src/App.tsx b/examples/web-chat/src/App.tsx index db8a8df8db..24115bfeb9 100644 --- a/examples/web-chat/src/App.tsx +++ b/examples/web-chat/src/App.tsx @@ -181,10 +181,12 @@ export default function App() { async function initWaku(setter: (waku: Waku) => void) { try { const waku = await Waku.create({ - config: { - pubsub: { - enabled: true, - emitSelf: true, + libp2p: { + config: { + pubsub: { + enabled: true, + emitSelf: true, + }, }, }, }); diff --git a/src/lib/waku.spec.ts b/src/lib/waku.spec.ts index c0fe3b982a..635ace2655 100644 --- a/src/lib/waku.spec.ts +++ b/src/lib/waku.spec.ts @@ -17,7 +17,7 @@ describe('Waku Dial', function () { const [waku1, waku2] = await Promise.all([ Waku.create({ staticNoiseKey: NOISE_KEY_1, - listenAddresses: ['/ip4/0.0.0.0/tcp/0/wss'], + libp2p: { addresses: { listen: ['/ip4/0.0.0.0/tcp/0/wss'] } }, }), Waku.create({ staticNoiseKey: NOISE_KEY_2 }), ]); @@ -39,8 +39,10 @@ describe('Waku Dial', function () { this.timeout(10_000); const waku = await Waku.create({ staticNoiseKey: NOISE_KEY_1, - listenAddresses: ['/ip4/0.0.0.0/tcp/0'], - modules: { transport: [TCP] }, + libp2p: { + addresses: { listen: ['/ip4/0.0.0.0/tcp/0'] }, + modules: { transport: [TCP] }, + }, }); const multiAddrWithId = waku.getLocalMultiaddrWithID(); diff --git a/src/lib/waku.ts b/src/lib/waku.ts index 4184d092d5..5cdf4e855c 100644 --- a/src/lib/waku.ts +++ b/src/lib/waku.ts @@ -1,4 +1,4 @@ -import Libp2p, { Libp2pConfig, Libp2pModules, Libp2pOptions } from 'libp2p'; +import Libp2p, { Libp2pModules, Libp2pOptions } from 'libp2p'; import Mplex from 'libp2p-mplex'; import { bytes } from 'libp2p-noise/dist/src/@types/basic'; import { Noise } from 'libp2p-noise/dist/src/noise'; @@ -11,16 +11,26 @@ import { WakuLightPush } from './waku_light_push'; import { RelayCodec, WakuRelay } from './waku_relay'; import { StoreCodec, WakuStore } from './waku_store'; -const transportKey = Websockets.prototype[Symbol.toStringTag]; +const websocketsTransportKey = Websockets.prototype[Symbol.toStringTag]; -export type CreateOptions = - | { - listenAddresses: string[] | undefined; - staticNoiseKey: bytes | undefined; - modules: Partial; - config: Partial; - } - | (Libp2pOptions & import('libp2p').CreateOptions); +export interface CreateOptions { + /** + * You can pass options to the `Libp2p` instance used by {@link Waku} using the {@link CreateOptions.libp2p} property. + * This property is the same type than the one passed to [`Libp2p.create`](https://github.com/libp2p/js-libp2p/blob/master/doc/API.md#create) + * apart that we made the `modules` property optional and partial, + * allowing its omission and letting Waku set good defaults. + * Notes that some values are overridden by {@link Waku} to ensure it implements the Waku protocol. + */ + libp2p?: Omit & { + modules?: Partial; + }; + /** + * Byte array used as key for the noise protocol used for connection encryption + * by [`Libp2p.create`](https://github.com/libp2p/js-libp2p/blob/master/doc/API.md#create) + * This is only used for test purposes to not run out of entropy during CI runs. + */ + staticNoiseKey?: bytes; +} export class Waku { public libp2p: Libp2p; @@ -44,52 +54,45 @@ export class Waku { * * @param options Takes the same options than `Libp2p`. */ - static async create(options: Partial): Promise { - const opts = Object.assign( - { - listenAddresses: [], - staticNoiseKey: undefined, - }, - options - ); + static async create(options?: CreateOptions): Promise { + // Get an object in case options or libp2p are undefined + const libp2pOpts = Object.assign({}, options?.libp2p); - opts.config = Object.assign( + // Default for Websocket filter is `all`: + // Returns all TCP and DNS based addresses, both with ws or wss. + libp2pOpts.config = Object.assign( { transport: { - [transportKey]: { + [websocketsTransportKey]: { filter: filters.all, }, }, }, - options.config + options?.libp2p?.config ); - opts.modules = Object.assign({}, options.modules); + libp2pOpts.modules = Object.assign({}, options?.libp2p?.modules); - let transport = [Websockets]; - if (opts.modules?.transport) { - transport = transport.concat(opts.modules?.transport); - } + // Default transport for libp2p is Websockets + libp2pOpts.modules = Object.assign( + { + transport: [Websockets], + }, + options?.libp2p?.modules + ); - // FIXME: By controlling the creation of libp2p we have to think about what - // needs to be exposed and what does not. Ideally, we should be able to let - // the user create the WakuStore, WakuRelay instances and pass them when - // creating the libp2p instance. - const libp2p = await Libp2p.create({ - addresses: { - listen: opts.listenAddresses, - }, - modules: { - transport, - streamMuxer: [Mplex], - connEncryption: [new Noise(opts.staticNoiseKey)], - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore: Type needs update - pubsub: WakuRelay, - }, - config: opts.config, + // streamMuxer, connection encryption and pubsub are overridden + // as those are the only ones currently supported by Waku nodes. + libp2pOpts.modules = Object.assign(libp2pOpts.modules, { + streamMuxer: [Mplex], + connEncryption: [new Noise(options?.staticNoiseKey)], + pubsub: WakuRelay, }); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore: modules property is correctly set thanks to voodoo + const libp2p = await Libp2p.create(libp2pOpts); + const wakuStore = new WakuStore(libp2p); const wakuLightPush = new WakuLightPush(libp2p); diff --git a/src/lib/waku_light_push/index.spec.ts b/src/lib/waku_light_push/index.spec.ts index a6f0450498..620dc815b8 100644 --- a/src/lib/waku_light_push/index.spec.ts +++ b/src/lib/waku_light_push/index.spec.ts @@ -23,7 +23,7 @@ describe('Waku Light Push', () => { waku = await Waku.create({ staticNoiseKey: NOISE_KEY_1, - modules: { transport: [TCP] }, + libp2p: { modules: { transport: [TCP] } }, }); await waku.dial(await nimWaku.getMultiaddrWithId()); diff --git a/src/lib/waku_relay/index.spec.ts b/src/lib/waku_relay/index.spec.ts index d05eef324f..bc826744b6 100644 --- a/src/lib/waku_relay/index.spec.ts +++ b/src/lib/waku_relay/index.spec.ts @@ -31,7 +31,7 @@ describe('Waku Relay', () => { Waku.create({ staticNoiseKey: NOISE_KEY_1 }), Waku.create({ staticNoiseKey: NOISE_KEY_2, - listenAddresses: ['/ip4/0.0.0.0/tcp/0/wss'], + libp2p: { addresses: { listen: ['/ip4/0.0.0.0/tcp/0/wss'] } }, }), ]); @@ -153,8 +153,10 @@ describe('Waku Relay', () => { log('Create waku node'); waku = await Waku.create({ staticNoiseKey: NOISE_KEY_1, - listenAddresses: ['/ip4/0.0.0.0/tcp/0'], - modules: { transport: [TCP] }, + libp2p: { + addresses: { listen: ['/ip4/0.0.0.0/tcp/0'] }, + modules: { transport: [TCP] }, + }, }); const multiAddrWithId = waku.getLocalMultiaddrWithID(); @@ -231,7 +233,7 @@ describe('Waku Relay', () => { this.timeout(30_000); waku = await Waku.create({ staticNoiseKey: NOISE_KEY_1, - modules: { transport: [TCP] }, + libp2p: { modules: { transport: [TCP] } }, }); nimWaku = new NimWaku(this.test?.ctx?.currentTest?.title + ''); @@ -328,11 +330,11 @@ describe('Waku Relay', () => { [waku1, waku2] = await Promise.all([ Waku.create({ staticNoiseKey: NOISE_KEY_1, - modules: { transport: [TCP] }, + libp2p: { modules: { transport: [TCP] } }, }), Waku.create({ staticNoiseKey: NOISE_KEY_2, - modules: { transport: [TCP] }, + libp2p: { modules: { transport: [TCP] } }, }), ]); diff --git a/src/lib/waku_store/index.spec.ts b/src/lib/waku_store/index.spec.ts index 81eb4acbe6..f27a51d9ae 100644 --- a/src/lib/waku_store/index.spec.ts +++ b/src/lib/waku_store/index.spec.ts @@ -30,7 +30,7 @@ describe('Waku Store', () => { waku = await Waku.create({ staticNoiseKey: NOISE_KEY_1, - modules: { transport: [TCP] }, + libp2p: { modules: { transport: [TCP] } }, }); await waku.dial(await nimWaku.getMultiaddrWithId()); @@ -67,7 +67,7 @@ describe('Waku Store', () => { waku = await Waku.create({ staticNoiseKey: NOISE_KEY_1, - modules: { transport: [TCP] }, + libp2p: { modules: { transport: [TCP] } }, }); await waku.dial(await nimWaku.getMultiaddrWithId());