191 lines
5.7 KiB
TypeScript
Raw Normal View History

import { noise } from "@chainsafe/libp2p-noise";
2022-11-16 15:49:43 +11:00
import { bootstrap } from "@libp2p/bootstrap";
import type { PeerDiscovery } from "@libp2p/interface-peer-discovery";
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,
2022-10-31 14:56:29 +11:00
WakuNode,
wakuRelay,
wakuStore,
2022-10-31 14:56:29 +11:00
} from "@waku/core";
2022-11-14 15:15:53 +05:30
import { DefaultUserAgent } from "@waku/core";
2022-10-31 14:49:39 +11:00
import { getPredefinedBootstrapNodes } from "@waku/core/lib/predefined_bootstrap_nodes";
import type { Relay, WakuFull, WakuLight, WakuPrivacy } from "@waku/interfaces";
import type { Libp2p } from "libp2p";
2022-10-31 14:49:39 +11:00
import { createLibp2p, Libp2pOptions } from "libp2p";
import type { Libp2pComponents } from "./libp2p_components.js";
export { Libp2pComponents };
2022-10-31 14:56:29 +11:00
type WakuOptions = waku.WakuOptions;
type RelayCreateOptions = waku_relay.CreateOptions;
export interface CreateOptions {
/**
2022-08-25 15:50:07 +10:00
* The PubSub Topic to use.
*
* 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.
* 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.
*/
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.
*/
defaultBootstrap?: boolean;
}
/**
* 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
*/
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,
options?.userAgent
);
const store = wakuStore(options);
const lightPush = wakuLightPush(options);
const filter = wakuFilter(options);
return new WakuNode(
options ?? {},
libp2p,
store,
lightPush,
filter
) as WakuLight;
}
/**
* Create a Waku node that uses Waku Relay to send and receive messages,
* enabling some privacy preserving properties.
*/
export async function createPrivacyNode(
options?: CreateOptions & WakuOptions & Partial<RelayCreateOptions>
): Promise<WakuPrivacy> {
const libp2pOptions = options?.libp2p ?? {};
const peerDiscovery = libp2pOptions.peerDiscovery ?? [];
if (options?.defaultBootstrap) {
peerDiscovery.push(defaultPeerDiscovery());
Object.assign(libp2pOptions, { peerDiscovery });
}
const libp2p = await defaultLibp2p(
wakuRelay(options),
libp2pOptions,
options?.userAgent
);
return new WakuNode(options ?? {}, libp2p) as WakuPrivacy;
}
/**
* 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(
options?: CreateOptions & WakuOptions & Partial<RelayCreateOptions>
): Promise<WakuFull> {
const libp2pOptions = options?.libp2p ?? {};
const peerDiscovery = libp2pOptions.peerDiscovery ?? [];
if (options?.defaultBootstrap) {
peerDiscovery.push(defaultPeerDiscovery());
Object.assign(libp2pOptions, { peerDiscovery });
}
const libp2p = await defaultLibp2p(
wakuRelay(options),
libp2pOptions,
options?.userAgent
);
const store = wakuStore(options);
const lightPush = wakuLightPush(options);
const filter = wakuFilter(options);
return new WakuNode(
options ?? {},
libp2p,
store,
lightPush,
filter
) as WakuFull;
}
2022-11-16 15:49:43 +11:00
export function defaultPeerDiscovery(): (
components: Libp2pComponents
2022-11-16 15:49:43 +11:00
) => PeerDiscovery {
return bootstrap({ list: getPredefinedBootstrapNodes() });
}
export async function defaultLibp2p(
wakuRelay?: (components: Libp2pComponents) => Relay,
options?: Partial<Libp2pOptions>,
userAgent?: string
): Promise<Libp2p> {
const libp2pOpts = Object.assign(
{
transports: [webSockets({ filter: filterAll })],
streamMuxers: [mplex()],
connectionEncryption: [noise()],
identify: {
2022-11-17 11:30:07 +11:00
host: {
agentVersion: userAgent ?? DefaultUserAgent,
},
},
} as Libp2pOptions,
wakuRelay ? { pubsub: wakuRelay } : {},
options ?? {}
);
return createLibp2p(libp2pOpts);
}