2023-03-31 03:17:41 +02:00
|
|
|
import type { GossipSub } from "@chainsafe/libp2p-gossipsub";
|
2022-11-16 20:30:48 +11:00
|
|
|
import { noise } from "@chainsafe/libp2p-noise";
|
2023-08-16 20:18:13 +05:30
|
|
|
import type { PeerDiscovery } from "@libp2p/interface/peer-discovery";
|
2022-11-16 20:30:48 +11: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 {
|
2023-02-17 13:27:37 +05:30
|
|
|
DefaultUserAgent,
|
2023-07-26 11:30:48 +05:30
|
|
|
wakuFilter,
|
2022-11-17 11:01:27 +11:00
|
|
|
wakuLightPush,
|
2022-10-31 14:56:29 +11:00
|
|
|
WakuNode,
|
2022-12-21 00:48:16 +11:00
|
|
|
WakuOptions,
|
2023-08-16 20:18:13 +05:30
|
|
|
wakuStore
|
2022-10-31 14:56:29 +11:00
|
|
|
} from "@waku/core";
|
2023-01-31 19:47:46 +05:30
|
|
|
import { enrTree, wakuDnsDiscovery } from "@waku/dns-discovery";
|
2023-02-09 13:15:23 +05:30
|
|
|
import type {
|
2023-11-28 00:40:59 +01:00
|
|
|
CreateLibp2pOptions,
|
2023-02-09 13:15:23 +05:30
|
|
|
FullNode,
|
2023-07-25 02:17:52 +02:00
|
|
|
Libp2p,
|
|
|
|
|
Libp2pComponents,
|
2023-02-09 13:15:23 +05:30
|
|
|
LightNode,
|
|
|
|
|
ProtocolCreateOptions,
|
2023-08-16 20:18:13 +05:30
|
|
|
RelayNode
|
2023-02-09 13:15:23 +05:30
|
|
|
} from "@waku/interfaces";
|
2023-09-07 13:15:49 +05:30
|
|
|
import { wakuPeerExchangeDiscovery } from "@waku/peer-exchange";
|
2023-05-11 14:08:00 +05:30
|
|
|
import { RelayCreateOptions, wakuGossipSub, wakuRelay } from "@waku/relay";
|
2023-11-28 00:40:59 +01:00
|
|
|
import { createLibp2p } from "libp2p";
|
2023-07-25 02:17:52 +02:00
|
|
|
import { identifyService } from "libp2p/identify";
|
|
|
|
|
import { pingService } from "libp2p/ping";
|
2022-12-02 15:43:46 +11:00
|
|
|
|
2023-01-31 19:47:46 +05:30
|
|
|
const DEFAULT_NODE_REQUIREMENTS = {
|
|
|
|
|
lightPush: 1,
|
|
|
|
|
filter: 1,
|
2023-08-16 20:18:13 +05:30
|
|
|
store: 1
|
2023-01-31 19:47:46 +05:30
|
|
|
};
|
|
|
|
|
|
2022-12-02 15:43:46 +11:00
|
|
|
export { Libp2pComponents };
|
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.
|
2023-07-26 11:30:48 +05:30
|
|
|
* Uses Waku Filter V2 by default.
|
2022-09-07 16:51:43 +10:00
|
|
|
*/
|
|
|
|
|
export async function createLightNode(
|
2023-08-16 20:18:13 +05:30
|
|
|
options?: ProtocolCreateOptions & WakuOptions
|
2022-12-06 13:18:32 +11:00
|
|
|
): Promise<LightNode> {
|
2023-10-10 20:18:02 +05:30
|
|
|
options = options ?? {};
|
|
|
|
|
|
2022-09-07 16:51:43 +10:00
|
|
|
const libp2pOptions = options?.libp2p ?? {};
|
|
|
|
|
const peerDiscovery = libp2pOptions.peerDiscovery ?? [];
|
|
|
|
|
if (options?.defaultBootstrap) {
|
2023-09-07 13:15:49 +05:30
|
|
|
peerDiscovery.push(...defaultPeerDiscoveries());
|
2022-09-07 16:51:43 +10:00
|
|
|
Object.assign(libp2pOptions, { peerDiscovery });
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-10 22:44:53 +05:30
|
|
|
const libp2p = await defaultLibp2p(
|
|
|
|
|
undefined,
|
|
|
|
|
libp2pOptions,
|
2023-08-16 20:18:13 +05:30
|
|
|
options?.userAgent
|
2022-11-10 22:44:53 +05:30
|
|
|
);
|
2022-09-07 16:51:43 +10:00
|
|
|
|
2022-11-17 11:01:27 +11:00
|
|
|
const store = wakuStore(options);
|
|
|
|
|
const lightPush = wakuLightPush(options);
|
2023-07-26 11:30:48 +05:30
|
|
|
const filter = wakuFilter(options);
|
2023-02-02 08:02:06 +05:30
|
|
|
|
2022-09-07 16:51:43 +10:00
|
|
|
return new WakuNode(
|
|
|
|
|
options ?? {},
|
|
|
|
|
libp2p,
|
2023-11-28 15:57:18 +05:30
|
|
|
options.shardInfo,
|
2022-11-17 11:01:27 +11:00
|
|
|
store,
|
|
|
|
|
lightPush,
|
2023-08-16 20:18:13 +05:30
|
|
|
filter
|
2022-12-06 13:18:32 +11:00
|
|
|
) as LightNode;
|
2022-09-07 16:51:43 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a Waku node that uses Waku Relay to send and receive messages,
|
|
|
|
|
* enabling some privacy preserving properties.
|
|
|
|
|
*/
|
2022-12-06 13:18:32 +11:00
|
|
|
export async function createRelayNode(
|
2023-08-16 20:18:13 +05:30
|
|
|
options?: ProtocolCreateOptions & WakuOptions & Partial<RelayCreateOptions>
|
2022-12-06 13:18:32 +11:00
|
|
|
): Promise<RelayNode> {
|
2023-10-10 20:18:02 +05:30
|
|
|
options = options ?? {};
|
|
|
|
|
|
2022-09-07 16:51:43 +10:00
|
|
|
const libp2pOptions = options?.libp2p ?? {};
|
|
|
|
|
const peerDiscovery = libp2pOptions.peerDiscovery ?? [];
|
|
|
|
|
if (options?.defaultBootstrap) {
|
2023-09-07 13:15:49 +05:30
|
|
|
peerDiscovery.push(...defaultPeerDiscoveries());
|
2022-09-07 16:51:43 +10:00
|
|
|
Object.assign(libp2pOptions, { peerDiscovery });
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-10 22:44:53 +05:30
|
|
|
const libp2p = await defaultLibp2p(
|
2023-03-31 03:17:41 +02:00
|
|
|
wakuGossipSub(options),
|
2022-11-10 22:44:53 +05:30
|
|
|
libp2pOptions,
|
2023-08-16 20:18:13 +05:30
|
|
|
options?.userAgent
|
2022-11-10 22:44:53 +05:30
|
|
|
);
|
2022-09-07 16:51:43 +10:00
|
|
|
|
2023-03-31 03:17:41 +02:00
|
|
|
const relay = wakuRelay(options);
|
|
|
|
|
|
|
|
|
|
return new WakuNode(
|
2023-10-10 20:18:02 +05:30
|
|
|
options,
|
2023-03-31 03:17:41 +02:00
|
|
|
libp2p,
|
2023-11-28 15:57:18 +05:30
|
|
|
options.shardInfo,
|
2023-03-31 03:17:41 +02:00
|
|
|
undefined,
|
|
|
|
|
undefined,
|
|
|
|
|
undefined,
|
2023-08-16 20:18:13 +05:30
|
|
|
relay
|
2023-03-31 03:17:41 +02:00
|
|
|
) as RelayNode;
|
2022-09-07 16:51:43 +10:00
|
|
|
}
|
|
|
|
|
|
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(
|
2023-08-16 20:18:13 +05:30
|
|
|
options?: ProtocolCreateOptions & WakuOptions & Partial<RelayCreateOptions>
|
2022-12-06 13:18:32 +11:00
|
|
|
): Promise<FullNode> {
|
2023-10-10 20:18:02 +05:30
|
|
|
options = options ?? {};
|
|
|
|
|
|
2022-09-08 11:25:18 +10:00
|
|
|
const libp2pOptions = options?.libp2p ?? {};
|
|
|
|
|
const peerDiscovery = libp2pOptions.peerDiscovery ?? [];
|
|
|
|
|
if (options?.defaultBootstrap) {
|
2023-09-07 13:15:49 +05:30
|
|
|
peerDiscovery.push(...defaultPeerDiscoveries());
|
2022-09-08 11:25:18 +10:00
|
|
|
Object.assign(libp2pOptions, { peerDiscovery });
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-10 22:44:53 +05:30
|
|
|
const libp2p = await defaultLibp2p(
|
2023-03-31 03:17:41 +02:00
|
|
|
wakuGossipSub(options),
|
2022-11-10 22:44:53 +05:30
|
|
|
libp2pOptions,
|
2023-08-16 20:18:13 +05:30
|
|
|
options?.userAgent
|
2022-11-10 22:44:53 +05:30
|
|
|
);
|
2022-09-08 11:25:18 +10:00
|
|
|
|
2022-11-17 11:01:27 +11:00
|
|
|
const store = wakuStore(options);
|
|
|
|
|
const lightPush = wakuLightPush(options);
|
2023-07-26 11:30:48 +05:30
|
|
|
const filter = wakuFilter(options);
|
2023-03-31 03:17:41 +02:00
|
|
|
const relay = wakuRelay(options);
|
2023-02-02 08:02:06 +05:30
|
|
|
|
2022-09-08 11:25:18 +10:00
|
|
|
return new WakuNode(
|
|
|
|
|
options ?? {},
|
|
|
|
|
libp2p,
|
2023-11-28 15:57:18 +05:30
|
|
|
options.shardInfo,
|
2022-11-17 11:01:27 +11:00
|
|
|
store,
|
|
|
|
|
lightPush,
|
2023-03-31 03:17:41 +02:00
|
|
|
filter,
|
2023-08-16 20:18:13 +05:30
|
|
|
relay
|
2022-12-06 13:18:32 +11:00
|
|
|
) as FullNode;
|
2022-09-08 11:25:18 +10:00
|
|
|
}
|
|
|
|
|
|
2023-09-07 13:15:49 +05:30
|
|
|
export function defaultPeerDiscoveries(): ((
|
2023-08-16 20:18:13 +05:30
|
|
|
components: Libp2pComponents
|
2023-09-07 13:15:49 +05:30
|
|
|
) => PeerDiscovery)[] {
|
|
|
|
|
const discoveries = [
|
|
|
|
|
wakuDnsDiscovery([enrTree["PROD"]], DEFAULT_NODE_REQUIREMENTS),
|
|
|
|
|
wakuPeerExchangeDiscovery()
|
|
|
|
|
];
|
|
|
|
|
return discoveries;
|
2022-08-03 15:08:12 +10:00
|
|
|
}
|
|
|
|
|
|
2023-07-25 02:17:52 +02:00
|
|
|
type PubsubService = {
|
|
|
|
|
pubsub?: (components: Libp2pComponents) => GossipSub;
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-03 15:08:12 +10:00
|
|
|
export async function defaultLibp2p(
|
2023-07-25 02:17:52 +02:00
|
|
|
wakuGossipSub?: PubsubService["pubsub"],
|
2023-11-28 00:40:59 +01:00
|
|
|
options?: Partial<CreateLibp2pOptions>,
|
2023-08-16 20:18:13 +05:30
|
|
|
userAgent?: string
|
2022-08-03 15:08:12 +10:00
|
|
|
): Promise<Libp2p> {
|
2023-11-28 00:40:59 +01:00
|
|
|
if (!options?.hideWebSocketInfo) {
|
|
|
|
|
/* eslint-disable no-console */
|
|
|
|
|
console.info(
|
|
|
|
|
"%cIgnore WebSocket connection failures",
|
|
|
|
|
"background: gray; color: white; font-size: x-large"
|
|
|
|
|
);
|
|
|
|
|
console.info(
|
|
|
|
|
"%cWaku tries to discover peers and some of them are expected to fail",
|
|
|
|
|
"background: gray; color: white; font-size: x-large"
|
|
|
|
|
);
|
|
|
|
|
/* eslint-enable no-console */
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-25 02:17:52 +02:00
|
|
|
const pubsubService: PubsubService = wakuGossipSub
|
|
|
|
|
? { pubsub: wakuGossipSub }
|
|
|
|
|
: {};
|
|
|
|
|
|
|
|
|
|
return createLibp2p({
|
2023-07-26 12:20:51 +05:30
|
|
|
connectionManager: {
|
2023-08-16 20:18:13 +05:30
|
|
|
minConnections: 1
|
2023-07-26 12:20:51 +05:30
|
|
|
},
|
2023-07-25 02:17:52 +02:00
|
|
|
transports: [webSockets({ filter: filterAll })],
|
|
|
|
|
streamMuxers: [mplex()],
|
|
|
|
|
connectionEncryption: [noise()],
|
|
|
|
|
...options,
|
|
|
|
|
services: {
|
|
|
|
|
identify: identifyService({
|
2023-08-16 20:18:13 +05:30
|
|
|
agentVersion: userAgent ?? DefaultUserAgent
|
2023-07-25 02:17:52 +02:00
|
|
|
}),
|
|
|
|
|
ping: pingService(),
|
|
|
|
|
...pubsubService,
|
2023-08-16 20:18:13 +05:30
|
|
|
...options?.services
|
|
|
|
|
}
|
2023-07-25 02:17:52 +02:00
|
|
|
}) as any as Libp2p; // TODO: make libp2p include it;
|
2022-08-01 15:43:43 +10:00
|
|
|
}
|