2022-08-01 15:43:43 +10:00
|
|
|
import { Noise } from "@chainsafe/libp2p-noise";
|
2022-11-16 15:49:43 +11:00
|
|
|
import { bootstrap } from "@libp2p/bootstrap";
|
|
|
|
|
import type { BootstrapComponents } from "@libp2p/bootstrap";
|
2022-08-03 15:08:12 +10:00
|
|
|
import type { PeerDiscovery } from "@libp2p/interface-peer-discovery";
|
2022-08-01 15:43:43 +10:00
|
|
|
import { Mplex } from "@libp2p/mplex";
|
|
|
|
|
import { WebSockets } from "@libp2p/websockets";
|
2022-08-03 15:00:09 +10:00
|
|
|
import { all as filterAll } from "@libp2p/websockets/filters";
|
2022-10-31 14:56:29 +11:00
|
|
|
import {
|
|
|
|
|
waku,
|
|
|
|
|
waku_relay,
|
|
|
|
|
WakuFilter,
|
|
|
|
|
WakuLightPush,
|
|
|
|
|
WakuNode,
|
|
|
|
|
WakuRelay,
|
|
|
|
|
WakuStore,
|
|
|
|
|
} from "@waku/core";
|
2022-10-31 14:49:39 +11:00
|
|
|
import { getPredefinedBootstrapNodes } from "@waku/core/lib/predefined_bootstrap_nodes";
|
2022-11-01 14:48:52 +11:00
|
|
|
import type { WakuFull, WakuLight, WakuPrivacy } from "@waku/interfaces";
|
2022-08-03 15:08:12 +10:00
|
|
|
import type { Libp2p } from "libp2p";
|
2022-10-31 14:49:39 +11:00
|
|
|
import { createLibp2p, Libp2pOptions } from "libp2p";
|
2022-08-01 15:43:43 +10:00
|
|
|
|
2022-10-31 14:56:29 +11:00
|
|
|
type WakuOptions = waku.WakuOptions;
|
|
|
|
|
type RelayCreateOptions = waku_relay.CreateOptions;
|
|
|
|
|
|
2022-08-01 15:43:43 +10:00
|
|
|
export interface CreateOptions {
|
|
|
|
|
/**
|
2022-08-25 15:50:07 +10:00
|
|
|
* The PubSub Topic to use.
|
2022-08-01 15:43:43 +10:00
|
|
|
*
|
|
|
|
|
* 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;
|
|
|
|
|
/**
|
2022-09-06 12:25:28 +10:00
|
|
|
* You can pass options to the `Libp2p` instance used by {@link index.waku.WakuNode} using the {@link CreateOptions.libp2p} property.
|
2022-08-01 15:43:43 +10:00
|
|
|
* 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.
|
2022-09-06 12:25:28 +10:00
|
|
|
* Notes that some values are overridden by {@link index.waku.WakuNode} to ensure it implements the Waku protocol.
|
2022-08-01 15:43:43 +10:00
|
|
|
*/
|
|
|
|
|
libp2p?: Partial<Libp2pOptions>;
|
|
|
|
|
/**
|
|
|
|
|
* 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?: Uint8Array;
|
|
|
|
|
/**
|
2022-08-05 23:47:38 +10:00
|
|
|
* Use recommended bootstrap method to discovery and connect to new nodes.
|
2022-08-01 15:43:43 +10:00
|
|
|
*/
|
2022-08-03 15:08:12 +10:00
|
|
|
defaultBootstrap?: boolean;
|
2022-08-01 15:43:43 +10:00
|
|
|
}
|
|
|
|
|
|
2022-09-07 16:51:43 +10:00
|
|
|
/**
|
|
|
|
|
* Create a Waku node that uses Waku Light Push, Filter and Store to send and
|
|
|
|
|
* receive messages, enabling low resource consumption.
|
2022-09-08 18:44:16 +10:00
|
|
|
* **Note: This is NOT compatible with nwaku v0.11**
|
|
|
|
|
*
|
|
|
|
|
* @see https://github.com/status-im/nwaku/issues/1085
|
2022-09-07 16:51:43 +10:00
|
|
|
*/
|
|
|
|
|
export async function createLightNode(
|
|
|
|
|
options?: CreateOptions & WakuOptions
|
|
|
|
|
): Promise<WakuLight> {
|
|
|
|
|
const libp2pOptions = options?.libp2p ?? {};
|
|
|
|
|
const peerDiscovery = libp2pOptions.peerDiscovery ?? [];
|
|
|
|
|
if (options?.defaultBootstrap) {
|
|
|
|
|
peerDiscovery.push(defaultPeerDiscovery());
|
|
|
|
|
Object.assign(libp2pOptions, { peerDiscovery });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const libp2p = await defaultLibp2p(undefined, libp2pOptions);
|
|
|
|
|
|
|
|
|
|
const wakuStore = new WakuStore(libp2p, options);
|
|
|
|
|
const wakuLightPush = new WakuLightPush(libp2p, options);
|
|
|
|
|
const wakuFilter = new WakuFilter(libp2p, options);
|
|
|
|
|
|
|
|
|
|
return new WakuNode(
|
|
|
|
|
options ?? {},
|
|
|
|
|
libp2p,
|
|
|
|
|
wakuStore,
|
|
|
|
|
wakuLightPush,
|
|
|
|
|
wakuFilter
|
|
|
|
|
) as WakuLight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a Waku node that uses Waku Relay to send and receive messages,
|
|
|
|
|
* enabling some privacy preserving properties.
|
|
|
|
|
*/
|
|
|
|
|
export async function createPrivacyNode(
|
2022-09-14 22:24:00 +10:00
|
|
|
options?: CreateOptions & WakuOptions & Partial<RelayCreateOptions>
|
2022-09-07 16:51:43 +10:00
|
|
|
): Promise<WakuPrivacy> {
|
|
|
|
|
const libp2pOptions = options?.libp2p ?? {};
|
|
|
|
|
const peerDiscovery = libp2pOptions.peerDiscovery ?? [];
|
|
|
|
|
if (options?.defaultBootstrap) {
|
|
|
|
|
peerDiscovery.push(defaultPeerDiscovery());
|
|
|
|
|
Object.assign(libp2pOptions, { peerDiscovery });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const libp2p = await defaultLibp2p(new WakuRelay(options), libp2pOptions);
|
|
|
|
|
|
|
|
|
|
return new WakuNode(options ?? {}, libp2p) as WakuPrivacy;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-08 11:25:18 +10:00
|
|
|
/**
|
|
|
|
|
* Create a Waku node that uses all Waku protocols.
|
|
|
|
|
*
|
|
|
|
|
* This helper is not recommended except if:
|
|
|
|
|
* - you are interfacing with nwaku v0.11 or below
|
|
|
|
|
* - you are doing some form of testing
|
|
|
|
|
*
|
|
|
|
|
* If you are building a full node, it is recommended to use
|
|
|
|
|
* [nwaku](github.com/status-im/nwaku) and its JSON RPC API or wip REST API.
|
|
|
|
|
*
|
|
|
|
|
* @see https://github.com/status-im/nwaku/issues/1085
|
|
|
|
|
* @internal
|
|
|
|
|
*/
|
|
|
|
|
export async function createFullNode(
|
2022-09-14 22:24:00 +10:00
|
|
|
options?: CreateOptions & WakuOptions & Partial<RelayCreateOptions>
|
2022-09-08 11:25:18 +10:00
|
|
|
): Promise<WakuFull> {
|
|
|
|
|
const libp2pOptions = options?.libp2p ?? {};
|
|
|
|
|
const peerDiscovery = libp2pOptions.peerDiscovery ?? [];
|
|
|
|
|
if (options?.defaultBootstrap) {
|
|
|
|
|
peerDiscovery.push(defaultPeerDiscovery());
|
|
|
|
|
Object.assign(libp2pOptions, { peerDiscovery });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const libp2p = await defaultLibp2p(new WakuRelay(options), libp2pOptions);
|
|
|
|
|
|
|
|
|
|
const wakuStore = new WakuStore(libp2p, options);
|
|
|
|
|
const wakuLightPush = new WakuLightPush(libp2p, options);
|
|
|
|
|
const wakuFilter = new WakuFilter(libp2p, options);
|
|
|
|
|
|
|
|
|
|
return new WakuNode(
|
|
|
|
|
options ?? {},
|
|
|
|
|
libp2p,
|
|
|
|
|
wakuStore,
|
|
|
|
|
wakuLightPush,
|
|
|
|
|
wakuFilter
|
|
|
|
|
) as WakuFull;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-16 15:49:43 +11:00
|
|
|
export function defaultPeerDiscovery(): (
|
|
|
|
|
components: BootstrapComponents
|
|
|
|
|
) => PeerDiscovery {
|
|
|
|
|
return bootstrap({ list: getPredefinedBootstrapNodes() });
|
2022-08-03 15:08:12 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function defaultLibp2p(
|
2022-09-07 16:51:43 +10:00
|
|
|
wakuRelay?: WakuRelay,
|
2022-08-03 15:08:12 +10:00
|
|
|
options?: Partial<Libp2pOptions>
|
|
|
|
|
): Promise<Libp2p> {
|
2022-08-01 15:43:43 +10:00
|
|
|
const libp2pOpts = Object.assign(
|
|
|
|
|
{
|
|
|
|
|
transports: [new WebSockets({ filter: filterAll })],
|
|
|
|
|
streamMuxers: [new Mplex()],
|
|
|
|
|
connectionEncryption: [new Noise()],
|
|
|
|
|
},
|
2022-09-07 16:51:43 +10:00
|
|
|
wakuRelay ? { pubsub: wakuRelay } : {},
|
2022-08-03 15:08:12 +10:00
|
|
|
options ?? {}
|
2022-08-01 15:43:43 +10:00
|
|
|
);
|
|
|
|
|
|
2022-08-03 15:08:12 +10:00
|
|
|
return createLibp2p(libp2pOpts);
|
2022-08-01 15:43:43 +10:00
|
|
|
}
|