js-waku/src/lib/waku.ts

156 lines
4.2 KiB
TypeScript
Raw Normal View History

2021-04-22 04:47:43 +00:00
import Libp2p, { Libp2pConfig, Libp2pModules, Libp2pOptions } from 'libp2p';
2021-03-19 03:40:16 +00:00
import Mplex from 'libp2p-mplex';
import { bytes } from 'libp2p-noise/dist/src/@types/basic';
import { Noise } from 'libp2p-noise/dist/src/noise';
import Websockets from 'libp2p-websockets';
import filters from 'libp2p-websockets/src/filters';
import { Multiaddr, multiaddr } from 'multiaddr';
import PeerId from 'peer-id';
2021-03-19 03:40:16 +00:00
2021-05-19 01:00:43 +00:00
import { WakuLightPush } from './waku_light_push';
import { RelayCodec, WakuRelay } from './waku_relay';
2021-04-07 01:04:30 +00:00
import { StoreCodec, WakuStore } from './waku_store';
2021-03-19 03:40:16 +00:00
const transportKey = Websockets.prototype[Symbol.toStringTag];
2021-04-22 04:47:43 +00:00
export type CreateOptions =
| {
listenAddresses: string[] | undefined;
staticNoiseKey: bytes | undefined;
modules: Partial<Libp2pModules>;
config: Partial<Libp2pConfig>;
}
| (Libp2pOptions & import('libp2p').CreateOptions);
2021-03-29 02:56:17 +00:00
export class Waku {
public libp2p: Libp2p;
public relay: WakuRelay;
public store: WakuStore;
2021-05-19 01:00:43 +00:00
public lightPush: WakuLightPush;
2021-05-19 01:00:43 +00:00
private constructor(
libp2p: Libp2p,
store: WakuStore,
lightPush: WakuLightPush
) {
this.libp2p = libp2p;
this.relay = (libp2p.pubsub as unknown) as WakuRelay;
this.store = store;
2021-05-19 01:00:43 +00:00
this.lightPush = lightPush;
}
2021-03-19 03:40:16 +00:00
/**
* Create new waku node
2021-05-13 01:49:20 +00:00
*
* @param options Takes the same options than `Libp2p`.
*/
2021-03-29 02:56:17 +00:00
static async create(options: Partial<CreateOptions>): Promise<Waku> {
const opts = Object.assign(
{
listenAddresses: [],
2021-03-29 02:56:17 +00:00
staticNoiseKey: undefined,
},
options
);
2021-04-22 04:47:43 +00:00
opts.config = Object.assign(
{
transport: {
[transportKey]: {
filter: filters.all,
},
},
},
options.config
);
opts.modules = Object.assign({}, options.modules);
let transport = [Websockets];
if (opts.modules?.transport) {
transport = transport.concat(opts.modules?.transport);
}
// FIXME: By controlling the creation of libp2p we have to think about what
// needs to be exposed and what does not. Ideally, we should be able to let
// the user create the WakuStore, WakuRelay instances and pass them when
// creating the libp2p instance.
2021-03-19 03:40:16 +00:00
const libp2p = await Libp2p.create({
addresses: {
2021-03-29 02:56:17 +00:00
listen: opts.listenAddresses,
2021-03-19 03:40:16 +00:00
},
modules: {
transport,
2021-03-19 03:40:16 +00:00
streamMuxer: [Mplex],
2021-03-29 02:56:17 +00:00
connEncryption: [new Noise(opts.staticNoiseKey)],
2021-03-19 03:40:16 +00:00
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Type needs update
pubsub: WakuRelay,
2021-03-19 03:40:16 +00:00
},
2021-04-22 04:47:43 +00:00
config: opts.config,
2021-03-19 03:40:16 +00:00
});
2021-04-07 01:04:30 +00:00
const wakuStore = new WakuStore(libp2p);
2021-05-19 01:00:43 +00:00
const wakuLightPush = new WakuLightPush(libp2p);
2021-04-07 01:04:30 +00:00
2021-03-19 03:40:16 +00:00
await libp2p.start();
2021-05-19 01:00:43 +00:00
return new Waku(libp2p, wakuStore, wakuLightPush);
2021-03-19 03:40:16 +00:00
}
/**
2021-04-07 01:04:30 +00:00
* Dials to the provided peer.
*
* @param peer The peer to dial
*/
async dial(
peer: PeerId | Multiaddr | string
): Promise<{
stream: import('libp2p-interfaces/src/stream-muxer/types').MuxedStream;
protocol: string;
}> {
return this.libp2p.dialProtocol(peer, [RelayCodec, StoreCodec]);
}
/**
* Add peer to address book, it will be auto-dialed in the background.
*/
addPeerToAddressBook(
peerId: PeerId | string,
multiaddrs: Multiaddr[] | string[]
): void {
let peer;
if (typeof peerId === 'string') {
peer = PeerId.createFromB58String(peerId);
} else {
peer = peerId;
}
const addresses = multiaddrs.map((addr: Multiaddr | string) => {
if (typeof addr === 'string') {
return multiaddr(addr);
} else {
return addr;
}
});
this.libp2p.peerStore.addressBook.set(peer, addresses);
}
async stop(): Promise<void> {
return this.libp2p.stop();
}
2021-04-06 01:06:10 +00:00
/**
* Return the local multiaddr with peer id on which libp2p is listening.
* @throws if libp2p is not listening on localhost
*/
getLocalMultiaddrWithID(): string {
const localMultiaddr = this.libp2p.multiaddrs.find((addr) =>
addr.toString().match(/127\.0\.0\.1/)
);
if (!localMultiaddr || localMultiaddr.toString() === '') {
throw 'Not listening on localhost';
}
2021-05-13 01:49:36 +00:00
return localMultiaddr + '/p2p/' + this.libp2p.peerId.toB58String();
2021-04-06 01:06:10 +00:00
}
2021-03-19 03:40:16 +00:00
}