@waku/sdk
Version:
A unified SDK for easy creation and management of js-waku nodes.
185 lines • 6.63 kB
JavaScript
import { TypedEventEmitter } from "@libp2p/interface";
import { ConnectionManager, createDecoder, createEncoder } from "@waku/core";
import { DefaultNetworkConfig, Protocols } from "@waku/interfaces";
import { createRoutingInfo, Logger } from "@waku/utils";
import { Filter } from "../filter/index.js";
import { HealthIndicator } from "../health_indicator/index.js";
import { LightPush } from "../light_push/index.js";
import { PeerManager } from "../peer_manager/index.js";
import { Store } from "../store/index.js";
import { waitForRemotePeer } from "./wait_for_remote_peer.js";
const log = new Logger("waku");
export class WakuNode {
libp2p;
relay;
store;
filter;
lightPush;
events = new TypedEventEmitter();
networkConfig;
// needed to create a lock for async operations
_nodeStateLock = false;
_nodeStarted = false;
connectionManager;
peerManager;
healthIndicator;
constructor(options, libp2p, protocolsEnabled, relay) {
this.relay = relay;
this.libp2p = libp2p;
this.networkConfig = options.networkConfig || DefaultNetworkConfig;
protocolsEnabled = {
filter: false,
lightpush: false,
store: false,
...protocolsEnabled
};
const peerId = this.libp2p.peerId.toString();
this.connectionManager = new ConnectionManager({
libp2p,
relay: this.relay,
events: this.events,
networkConfig: this.networkConfig,
config: options?.connectionManager
});
this.peerManager = new PeerManager({
libp2p,
config: {
numPeersToUse: options.numPeersToUse
},
connectionManager: this.connectionManager
});
this.healthIndicator = new HealthIndicator({ libp2p, events: this.events });
if (protocolsEnabled.store) {
this.store = new Store({
libp2p,
peerManager: this.peerManager,
options: options?.store
});
}
if (protocolsEnabled.lightpush) {
this.lightPush = new LightPush({
libp2p,
peerManager: this.peerManager,
options: options?.lightPush
});
}
if (protocolsEnabled.filter) {
this.filter = new Filter({
libp2p,
peerManager: this.peerManager,
options: options.filter
});
}
log.info("Waku node created", peerId, `relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
.lightPush}, filter: ${!!this.filter}`);
}
get peerId() {
return this.libp2p.peerId;
}
get protocols() {
return this.libp2p.getProtocols();
}
get health() {
return this.healthIndicator.toValue();
}
async dial(peer, protocols) {
const _protocols = protocols ?? [];
if (typeof protocols === "undefined") {
this.relay && _protocols.push(Protocols.Relay);
this.store && _protocols.push(Protocols.Store);
this.filter && _protocols.push(Protocols.Filter);
this.lightPush && _protocols.push(Protocols.LightPush);
}
const codecs = [];
if (_protocols.includes(Protocols.Relay)) {
if (this.relay) {
this.relay.gossipSub.multicodecs.forEach((codec) => codecs.push(codec));
}
else {
log.error("Relay codec not included in dial codec: protocol not mounted locally");
}
}
if (_protocols.includes(Protocols.Store)) {
if (this.store) {
codecs.push(this.store.multicodec);
}
else {
log.error("Store codec not included in dial codec: protocol not mounted locally");
}
}
if (_protocols.includes(Protocols.LightPush)) {
if (this.lightPush) {
codecs.push(this.lightPush.multicodec);
}
else {
log.error("Light Push codec not included in dial codec: protocol not mounted locally");
}
}
if (_protocols.includes(Protocols.Filter)) {
if (this.filter) {
codecs.push(this.filter.multicodec);
}
else {
log.error("Filter codec not included in dial codec: protocol not mounted locally");
}
}
log.info(`Dialing to ${peer?.toString()} with protocols ${_protocols}`);
return await this.connectionManager.dial(peer, codecs);
}
async hangUp(peer) {
log.info(`Hanging up peer:${peer?.toString()}.`);
return this.connectionManager.hangUp(peer);
}
async start() {
if (this._nodeStateLock || this.isStarted())
return;
this._nodeStateLock = true;
await this.libp2p.start();
this.connectionManager.start();
this.peerManager.start();
this.healthIndicator.start();
this.lightPush?.start();
this._nodeStateLock = false;
this._nodeStarted = true;
}
async stop() {
if (this._nodeStateLock || !this.isStarted())
return;
this._nodeStateLock = true;
this.lightPush?.stop();
this.healthIndicator.stop();
this.peerManager.stop();
this.connectionManager.stop();
await this.libp2p.stop();
this._nodeStateLock = false;
this._nodeStarted = false;
}
async getConnectedPeers() {
return this.connectionManager.getConnectedPeers();
}
async waitForPeers(protocols, timeoutMs) {
return waitForRemotePeer(this, protocols, timeoutMs);
}
isStarted() {
return this._nodeStarted && this.libp2p.status === "started";
}
isConnected() {
return this.connectionManager.isConnected();
}
createDecoder(params) {
const routingInfo = this.createRoutingInfo(params.contentTopic, params.shardId);
return createDecoder(params.contentTopic, routingInfo);
}
createEncoder(params) {
const routingInfo = this.createRoutingInfo(params.contentTopic, params.shardId);
return createEncoder({
contentTopic: params.contentTopic,
ephemeral: params.ephemeral,
routingInfo: routingInfo
});
}
createRoutingInfo(contentTopic, shardId) {
return createRoutingInfo(this.networkConfig, { contentTopic, shardId });
}
}
//# sourceMappingURL=waku.js.map