1- import Libp2p , { Libp2pConfig , Libp2pModules , Libp2pOptions } from 'libp2p' ;
1+ import Libp2p , { Libp2pModules , Libp2pOptions } from 'libp2p' ;
22import Mplex from 'libp2p-mplex' ;
33import { bytes } from 'libp2p-noise/dist/src/@types/basic' ;
44import { Noise } from 'libp2p-noise/dist/src/noise' ;
@@ -11,16 +11,40 @@ import { WakuLightPush } from './waku_light_push';
1111import { RelayCodec , WakuRelay } from './waku_relay' ;
1212import { StoreCodec , WakuStore } from './waku_store' ;
1313
14- const transportKey = Websockets . prototype [ Symbol . toStringTag ] ;
14+ const websocketsTransportKey = Websockets . prototype [ Symbol . toStringTag ] ;
1515
16- export type CreateOptions =
17- | {
18- listenAddresses : string [ ] | undefined ;
19- staticNoiseKey : bytes | undefined ;
20- modules : Partial < Libp2pModules > ;
21- config : Partial < Libp2pConfig > ;
22- }
23- | ( Libp2pOptions & import ( 'libp2p' ) . CreateOptions ) ;
16+ export interface CreateOptions {
17+ /**
18+ * The PubSub Topic to use. Defaults to {@link DefaultPubsubTopic}.
19+ *
20+ * One and only one pubsub topic is used by Waku. This is used by:
21+ * - WakuRelay to receive, route and send messages,
22+ * - WakuLightPush to send messages,
23+ * - WakuStore to retrieve messages.
24+ *
25+ * The usage of the default pubsub topic is recommended.
26+ * See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details.
27+ *
28+ * @default {@link DefaultPubsubTopic }
29+ */
30+ pubsubTopic ?: string ;
31+ /**
32+ * You can pass options to the `Libp2p` instance used by {@link Waku} using the {@link CreateOptions.libp2p} property.
33+ * 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)
34+ * apart that we made the `modules` property optional and partial,
35+ * allowing its omission and letting Waku set good defaults.
36+ * Notes that some values are overridden by {@link Waku} to ensure it implements the Waku protocol.
37+ */
38+ libp2p ?: Omit < Libp2pOptions & import ( 'libp2p' ) . CreateOptions , 'modules' > & {
39+ modules ?: Partial < Libp2pModules > ;
40+ } ;
41+ /**
42+ * Byte array used as key for the noise protocol used for connection encryption
43+ * by [`Libp2p.create`](https://github.com/libp2p/js-libp2p/blob/master/doc/API.md#create)
44+ * This is only used for test purposes to not run out of entropy during CI runs.
45+ */
46+ staticNoiseKey ?: bytes ;
47+ }
2448
2549export class Waku {
2650 public libp2p : Libp2p ;
@@ -44,53 +68,56 @@ export class Waku {
4468 *
4569 * @param options Takes the same options than `Libp2p`.
4670 */
47- static async create ( options : Partial < CreateOptions > ) : Promise < Waku > {
48- const opts = Object . assign (
49- {
50- listenAddresses : [ ] ,
51- staticNoiseKey : undefined ,
52- } ,
53- options
54- ) ;
71+ static async create ( options ?: CreateOptions ) : Promise < Waku > {
72+ // Get an object in case options or libp2p are undefined
73+ const libp2pOpts = Object . assign ( { } , options ?. libp2p ) ;
5574
56- opts . config = Object . assign (
75+ // Default for Websocket filter is `all`:
76+ // Returns all TCP and DNS based addresses, both with ws or wss.
77+ libp2pOpts . config = Object . assign (
5778 {
5879 transport : {
59- [ transportKey ] : {
80+ [ websocketsTransportKey ] : {
6081 filter : filters . all ,
6182 } ,
6283 } ,
6384 } ,
64- options . config
85+ options ?. libp2p ? .config
6586 ) ;
6687
67- opts . modules = Object . assign ( { } , options . modules ) ;
68-
69- let transport = [ Websockets ] ;
70- if ( opts . modules ?. transport ) {
71- transport = transport . concat ( opts . modules ?. transport ) ;
88+ // Pass pubsub topic to relay
89+ if ( options ?. pubsubTopic ) {
90+ libp2pOpts . config . pubsub = Object . assign (
91+ { pubsubTopic : options . pubsubTopic } ,
92+ libp2pOpts . config . pubsub
93+ ) ;
7294 }
7395
74- // FIXME: By controlling the creation of libp2p we have to think about what
75- // needs to be exposed and what does not. Ideally, we should be able to let
76- // the user create the WakuStore, WakuRelay instances and pass them when
77- // creating the libp2p instance.
78- const libp2p = await Libp2p . create ( {
79- addresses : {
80- listen : opts . listenAddresses ,
81- } ,
82- modules : {
83- transport,
84- streamMuxer : [ Mplex ] ,
85- connEncryption : [ new Noise ( opts . staticNoiseKey ) ] ,
86- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
87- // @ts -ignore: Type needs update
88- pubsub : WakuRelay ,
96+ libp2pOpts . modules = Object . assign ( { } , options ?. libp2p ?. modules ) ;
97+
98+ // Default transport for libp2p is Websockets
99+ libp2pOpts . modules = Object . assign (
100+ {
101+ transport : [ Websockets ] ,
89102 } ,
90- config : opts . config ,
103+ options ?. libp2p ?. modules
104+ ) ;
105+
106+ // streamMuxer, connection encryption and pubsub are overridden
107+ // as those are the only ones currently supported by Waku nodes.
108+ libp2pOpts . modules = Object . assign ( libp2pOpts . modules , {
109+ streamMuxer : [ Mplex ] ,
110+ connEncryption : [ new Noise ( options ?. staticNoiseKey ) ] ,
111+ pubsub : WakuRelay ,
91112 } ) ;
92113
93- const wakuStore = new WakuStore ( libp2p ) ;
114+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
115+ // @ts -ignore: modules property is correctly set thanks to voodoo
116+ const libp2p = await Libp2p . create ( libp2pOpts ) ;
117+
118+ const wakuStore = new WakuStore ( libp2p , {
119+ pubsubTopic : options ?. pubsubTopic ,
120+ } ) ;
94121 const wakuLightPush = new WakuLightPush ( libp2p ) ;
95122
96123 await libp2p . start ( ) ;
0 commit comments