2022-02-04 14:12:00 +11:00
|
|
|
import { ChildProcess, spawn } from "child_process";
|
2021-03-10 17:39:53 +11:00
|
|
|
|
2022-06-20 16:48:30 +10:00
|
|
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
|
|
|
|
import { peerIdFromString } from "@libp2p/peer-id";
|
|
|
|
|
import { Multiaddr, multiaddr } from "@multiformats/multiaddr";
|
2022-11-03 21:48:04 +11:00
|
|
|
import { bytesToHex, hexToBytes } from "@waku/byte-utils";
|
2022-11-01 21:31:53 +11:00
|
|
|
import { DefaultPubSubTopic } from "@waku/core";
|
2022-02-04 14:12:00 +11:00
|
|
|
import appRoot from "app-root-path";
|
|
|
|
|
import debug from "debug";
|
|
|
|
|
import portfinder from "portfinder";
|
2021-03-10 17:39:53 +11:00
|
|
|
|
2022-12-02 15:43:46 +11:00
|
|
|
import { existsAsync, mkdirAsync, openAsync } from "./async_fs.js";
|
|
|
|
|
import { delay } from "./delay.js";
|
|
|
|
|
import waitForLine from "./log_file.js";
|
2021-03-10 17:39:53 +11:00
|
|
|
|
2022-09-05 21:30:29 +10:00
|
|
|
const log = debug("waku:nwaku");
|
2021-04-06 11:00:40 +10:00
|
|
|
|
2022-05-27 20:54:38 +10:00
|
|
|
const WAKU_SERVICE_NODE_DIR =
|
|
|
|
|
process.env.WAKU_SERVICE_NODE_DIR ?? appRoot + "/nwaku";
|
|
|
|
|
const WAKU_SERVICE_NODE_BIN =
|
|
|
|
|
process.env.WAKU_SERVICE_NODE_BIN ??
|
|
|
|
|
WAKU_SERVICE_NODE_DIR + "/build/wakunode2";
|
2022-08-24 07:43:04 +10:00
|
|
|
const WAKU_SERVICE_NODE_PARAMS =
|
|
|
|
|
process.env.WAKU_SERVICE_NODE_PARAMS ?? undefined;
|
2022-05-26 15:49:39 +10:00
|
|
|
const NODE_READY_LOG_LINE = "Node setup complete";
|
2021-03-10 17:39:53 +11:00
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
const LOG_DIR = "./log";
|
2021-03-15 13:38:36 +11:00
|
|
|
|
2022-09-11 00:57:10 +10:00
|
|
|
const OneMillion = BigInt(1_000_000);
|
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
BigInt.prototype.toJSON = function toJSON() {
|
|
|
|
|
return Number(this);
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-11 10:54:35 +11:00
|
|
|
export interface Args {
|
|
|
|
|
staticnode?: string;
|
2022-02-04 14:12:00 +11:00
|
|
|
nat?: "none";
|
2021-03-11 10:54:35 +11:00
|
|
|
listenAddress?: string;
|
|
|
|
|
relay?: boolean;
|
|
|
|
|
rpc?: boolean;
|
|
|
|
|
rpcAdmin?: boolean;
|
|
|
|
|
nodekey?: string;
|
2021-03-12 17:08:42 +11:00
|
|
|
portsShift?: number;
|
2021-04-09 11:23:00 +10:00
|
|
|
logLevel?: LogLevel;
|
2021-05-19 11:00:43 +10:00
|
|
|
lightpush?: boolean;
|
2022-05-04 20:07:21 +10:00
|
|
|
filter?: boolean;
|
|
|
|
|
store?: boolean;
|
2022-11-15 14:09:04 +11:00
|
|
|
storeMessageDbUrl?: string;
|
2021-06-09 12:25:56 +10:00
|
|
|
topics?: string;
|
2021-07-09 10:07:39 +10:00
|
|
|
rpcPrivate?: boolean;
|
2022-01-20 13:00:58 +11:00
|
|
|
websocketSupport?: boolean;
|
2022-02-01 12:54:54 +11:00
|
|
|
tcpPort?: number;
|
|
|
|
|
rpcPort?: number;
|
|
|
|
|
websocketPort?: number;
|
2021-04-09 11:23:00 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export enum LogLevel {
|
2022-08-20 12:34:36 +10:00
|
|
|
Error = "ERROR",
|
|
|
|
|
Info = "INFO",
|
|
|
|
|
Warn = "WARN",
|
|
|
|
|
Debug = "DEBUG",
|
|
|
|
|
Trace = "TRACE",
|
|
|
|
|
Notice = "NOTICE",
|
|
|
|
|
Fatal = "FATAL",
|
2021-03-11 10:54:35 +11:00
|
|
|
}
|
|
|
|
|
|
2021-07-09 10:07:39 +10:00
|
|
|
export interface KeyPair {
|
|
|
|
|
privateKey: string;
|
|
|
|
|
publicKey: string;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-11 00:57:10 +10:00
|
|
|
export interface MessageRpcQuery {
|
2022-03-09 12:59:47 +11:00
|
|
|
payload: string; // Hex encoded data string without `0x` prefix.
|
2021-07-09 10:07:39 +10:00
|
|
|
contentTopic?: string;
|
2022-09-11 00:57:10 +10:00
|
|
|
timestamp?: bigint; // Unix epoch time in nanoseconds as a 64-bits integer value.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MessageRpcResponse {
|
|
|
|
|
payload: number[];
|
|
|
|
|
contentTopic?: string;
|
|
|
|
|
version?: number;
|
|
|
|
|
timestamp?: bigint; // Unix epoch time in nanoseconds as a 64-bits integer value.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MessageRpcResponseHex {
|
|
|
|
|
payload: string;
|
|
|
|
|
contentTopic?: string;
|
|
|
|
|
version?: number;
|
|
|
|
|
timestamp?: bigint; // Unix epoch time in nanoseconds as a 64-bits integer value.
|
2021-07-09 10:07:39 +10:00
|
|
|
}
|
|
|
|
|
|
2022-04-01 12:19:51 +11:00
|
|
|
export class Nwaku {
|
2021-03-10 17:39:53 +11:00
|
|
|
private process?: ChildProcess;
|
2021-03-26 13:07:47 +11:00
|
|
|
private pid?: number;
|
2021-03-12 17:08:42 +11:00
|
|
|
private peerId?: PeerId;
|
2021-03-23 11:14:51 +11:00
|
|
|
private multiaddrWithId?: Multiaddr;
|
2022-02-01 12:54:54 +11:00
|
|
|
private readonly logPath: string;
|
|
|
|
|
private rpcPort?: number;
|
2021-03-10 17:39:53 +11:00
|
|
|
|
2022-03-09 12:59:47 +11:00
|
|
|
/**
|
|
|
|
|
* Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used
|
|
|
|
|
* by the nwaku JSON-RPC API.
|
|
|
|
|
*/
|
2022-09-11 00:57:10 +10:00
|
|
|
static toMessageRpcQuery(message: {
|
|
|
|
|
payload: Uint8Array;
|
|
|
|
|
contentTopic: string;
|
|
|
|
|
timestamp?: Date;
|
|
|
|
|
}): MessageRpcQuery {
|
2022-03-09 12:59:47 +11:00
|
|
|
if (!message.payload) {
|
|
|
|
|
throw "Attempting to convert empty message";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let timestamp;
|
2022-09-11 00:57:10 +10:00
|
|
|
if (message.timestamp) {
|
|
|
|
|
timestamp = BigInt(message.timestamp.valueOf()) * OneMillion;
|
2022-03-09 12:59:47 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
payload: bytesToHex(message.payload),
|
|
|
|
|
contentTopic: message.contentTopic,
|
|
|
|
|
timestamp,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-25 15:49:07 +11:00
|
|
|
constructor(logName: string) {
|
2022-04-01 12:19:51 +11:00
|
|
|
this.logPath = `${LOG_DIR}/nwaku_${logName}.log`;
|
2021-03-15 13:25:14 +11:00
|
|
|
}
|
2021-03-11 11:11:37 +11:00
|
|
|
|
2021-05-03 15:52:38 +10:00
|
|
|
async start(args?: Args): Promise<void> {
|
2021-03-15 13:38:36 +11:00
|
|
|
try {
|
|
|
|
|
await existsAsync(LOG_DIR);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
try {
|
|
|
|
|
await mkdirAsync(LOG_DIR);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
// Looks like 2 tests tried to create the director at the same time,
|
|
|
|
|
// it can be ignored
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
const logFile = await openAsync(this.logPath, "w");
|
2021-03-11 10:54:35 +11:00
|
|
|
|
2021-03-12 17:08:42 +11:00
|
|
|
const mergedArgs = defaultArgs();
|
|
|
|
|
|
2022-02-01 12:54:54 +11:00
|
|
|
const ports: number[] = await new Promise((resolve, reject) => {
|
|
|
|
|
portfinder.getPorts(3, {}, (err, ports) => {
|
|
|
|
|
if (err) reject(err);
|
|
|
|
|
resolve(ports);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.rpcPort = ports[0];
|
|
|
|
|
|
2021-03-12 17:08:42 +11:00
|
|
|
// Object.assign overrides the properties with the source (if there are conflicts)
|
2021-04-09 11:23:00 +10:00
|
|
|
Object.assign(
|
|
|
|
|
mergedArgs,
|
2022-02-01 12:54:54 +11:00
|
|
|
{
|
|
|
|
|
tcpPort: ports[1],
|
|
|
|
|
rpcPort: this.rpcPort,
|
|
|
|
|
websocketPort: ports[2],
|
|
|
|
|
},
|
2021-04-09 11:23:00 +10:00
|
|
|
args
|
|
|
|
|
);
|
2021-03-12 17:08:42 +11:00
|
|
|
|
2022-11-17 14:28:01 +11:00
|
|
|
process.env.WAKUNODE2_STORE_MESSAGE_DB_URL = "";
|
|
|
|
|
|
2021-03-12 17:08:42 +11:00
|
|
|
const argsArray = argsToArray(mergedArgs);
|
2022-08-24 07:43:04 +10:00
|
|
|
if (WAKU_SERVICE_NODE_PARAMS) {
|
|
|
|
|
argsArray.push(WAKU_SERVICE_NODE_PARAMS);
|
|
|
|
|
}
|
2022-09-05 21:30:29 +10:00
|
|
|
log(`nwaku args: ${argsArray.join(" ")}`);
|
2022-05-27 20:54:38 +10:00
|
|
|
this.process = spawn(WAKU_SERVICE_NODE_BIN, argsArray, {
|
|
|
|
|
cwd: WAKU_SERVICE_NODE_DIR,
|
2021-03-11 10:54:35 +11:00
|
|
|
stdio: [
|
2022-02-04 14:12:00 +11:00
|
|
|
"ignore", // stdin
|
2021-03-11 10:54:35 +11:00
|
|
|
logFile, // stdout
|
|
|
|
|
logFile, // stderr
|
2021-03-10 17:39:53 +11:00
|
|
|
],
|
2021-03-11 10:54:35 +11:00
|
|
|
});
|
2021-03-26 13:07:47 +11:00
|
|
|
this.pid = this.process.pid;
|
2022-09-05 21:30:29 +10:00
|
|
|
log(
|
2022-04-01 12:19:51 +11:00
|
|
|
`nwaku ${this.process.pid} started at ${new Date().toLocaleTimeString()}`
|
2021-03-26 13:07:47 +11:00
|
|
|
);
|
2021-03-10 17:39:53 +11:00
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
this.process.on("exit", (signal) => {
|
2022-09-05 21:30:29 +10:00
|
|
|
log(
|
2022-04-01 12:19:51 +11:00
|
|
|
`nwaku ${
|
2021-03-26 13:07:47 +11:00
|
|
|
this.process ? this.process.pid : this.pid
|
|
|
|
|
} process exited with ${signal} at ${new Date().toLocaleTimeString()}`
|
|
|
|
|
);
|
2021-03-25 16:29:35 +11:00
|
|
|
});
|
|
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
this.process.on("error", (err) => {
|
2022-09-05 21:30:29 +10:00
|
|
|
log(
|
2022-04-01 12:19:51 +11:00
|
|
|
`nwaku ${
|
2021-03-26 13:07:47 +11:00
|
|
|
this.process ? this.process.pid : this.pid
|
|
|
|
|
} process encountered an error: ${err} at ${new Date().toLocaleTimeString()}`
|
|
|
|
|
);
|
2021-03-25 16:29:35 +11:00
|
|
|
});
|
|
|
|
|
|
2022-09-05 21:30:29 +10:00
|
|
|
log(`Waiting to see '${NODE_READY_LOG_LINE}' in nwaku logs`);
|
2022-05-26 15:49:39 +10:00
|
|
|
await this.waitForLog(NODE_READY_LOG_LINE, 15000);
|
2022-08-25 14:40:25 +10:00
|
|
|
if (process.env.CI) await delay(100);
|
2022-09-05 21:30:29 +10:00
|
|
|
log("nwaku node has been started");
|
2021-03-15 13:25:14 +11:00
|
|
|
}
|
|
|
|
|
|
2021-05-03 15:52:38 +10:00
|
|
|
public stop(): void {
|
2022-01-31 15:30:49 +11:00
|
|
|
const pid = this.process ? this.process.pid : this.pid;
|
2022-09-05 21:30:29 +10:00
|
|
|
log(`nwaku ${pid} getting SIGINT at ${new Date().toLocaleTimeString()}`);
|
2022-04-01 12:19:51 +11:00
|
|
|
if (!this.process) throw "nwaku process not set";
|
2022-02-04 14:12:00 +11:00
|
|
|
const res = this.process.kill("SIGINT");
|
2022-09-05 21:30:29 +10:00
|
|
|
log(`nwaku ${pid} interrupted:`, res);
|
2022-01-31 15:30:49 +11:00
|
|
|
this.process = undefined;
|
2021-03-19 16:07:56 +11:00
|
|
|
}
|
|
|
|
|
|
2021-08-09 11:58:58 +10:00
|
|
|
async waitForLog(msg: string, timeout: number): Promise<void> {
|
|
|
|
|
return waitForLine(this.logPath, msg, timeout);
|
2021-03-10 17:39:53 +11:00
|
|
|
}
|
|
|
|
|
|
2022-04-01 12:19:51 +11:00
|
|
|
/** Calls nwaku JSON-RPC API `get_waku_v2_admin_v1_peers` to check
|
2021-03-10 17:39:53 +11:00
|
|
|
* for known peers
|
2022-04-01 12:19:51 +11:00
|
|
|
* @throws if nwaku isn't started.
|
2021-03-10 17:39:53 +11:00
|
|
|
*/
|
2021-05-03 15:52:38 +10:00
|
|
|
async peers(): Promise<string[]> {
|
2021-03-10 17:39:53 +11:00
|
|
|
this.checkProcess();
|
|
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
return this.rpcCall<string[]>("get_waku_v2_admin_v1_peers", []);
|
2021-03-10 17:39:53 +11:00
|
|
|
}
|
|
|
|
|
|
2021-03-12 17:08:42 +11:00
|
|
|
async info(): Promise<RpcInfoResponse> {
|
2021-03-10 17:39:53 +11:00
|
|
|
this.checkProcess();
|
|
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
return this.rpcCall<RpcInfoResponse>("get_waku_v2_debug_v1_info", []);
|
2021-03-10 17:39:53 +11:00
|
|
|
}
|
|
|
|
|
|
2021-06-09 12:25:56 +10:00
|
|
|
async sendMessage(
|
2022-09-11 00:57:10 +10:00
|
|
|
message: MessageRpcQuery,
|
2022-08-24 19:04:31 +10:00
|
|
|
pubSubTopic: string = DefaultPubSubTopic
|
2021-06-09 12:25:56 +10:00
|
|
|
): Promise<boolean> {
|
2021-03-12 10:35:50 +11:00
|
|
|
this.checkProcess();
|
|
|
|
|
|
2022-09-11 00:57:10 +10:00
|
|
|
if (typeof message.timestamp === "undefined") {
|
|
|
|
|
message.timestamp = BigInt(new Date().valueOf()) * OneMillion;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
return this.rpcCall<boolean>("post_waku_v2_relay_v1_message", [
|
2022-08-24 19:04:31 +10:00
|
|
|
pubSubTopic,
|
2022-03-09 12:59:47 +11:00
|
|
|
message,
|
2021-03-12 10:35:50 +11:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-15 11:12:06 +10:00
|
|
|
async messages(
|
|
|
|
|
pubsubTopic: string = DefaultPubSubTopic
|
2022-09-11 00:57:10 +10:00
|
|
|
): Promise<MessageRpcResponse[]> {
|
2021-03-12 10:35:50 +11:00
|
|
|
this.checkProcess();
|
|
|
|
|
|
2022-09-11 00:57:10 +10:00
|
|
|
const isDefined = (
|
|
|
|
|
msg: MessageRpcResponse | undefined
|
|
|
|
|
): msg is MessageRpcResponse => {
|
2021-07-07 11:23:56 +10:00
|
|
|
return !!msg;
|
|
|
|
|
};
|
|
|
|
|
|
2022-09-11 00:57:10 +10:00
|
|
|
const msgs = await this.rpcCall<MessageRpcResponse[]>(
|
2022-02-04 14:12:00 +11:00
|
|
|
"get_waku_v2_relay_v1_messages",
|
2022-06-15 11:12:06 +10:00
|
|
|
[pubsubTopic]
|
2021-07-07 11:23:56 +10:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return msgs.filter(isDefined);
|
2021-03-12 10:35:50 +11:00
|
|
|
}
|
|
|
|
|
|
2021-07-09 10:07:39 +10:00
|
|
|
async getAsymmetricKeyPair(): Promise<KeyPair> {
|
|
|
|
|
this.checkProcess();
|
|
|
|
|
|
2022-06-15 14:22:10 +10:00
|
|
|
const { privateKey, publicKey, seckey, pubkey } = await this.rpcCall<{
|
2021-07-09 10:07:39 +10:00
|
|
|
seckey: string;
|
|
|
|
|
pubkey: string;
|
2022-06-15 14:22:10 +10:00
|
|
|
privateKey: string;
|
|
|
|
|
publicKey: string;
|
2022-02-04 14:12:00 +11:00
|
|
|
}>("get_waku_v2_private_v1_asymmetric_keypair", []);
|
2021-07-09 10:07:39 +10:00
|
|
|
|
2022-06-15 14:22:10 +10:00
|
|
|
// To be removed once https://github.com/vacp2p/rfc/issues/507 is fixed
|
|
|
|
|
if (seckey) {
|
|
|
|
|
return { privateKey: seckey, publicKey: pubkey };
|
|
|
|
|
} else {
|
|
|
|
|
return { privateKey, publicKey };
|
|
|
|
|
}
|
2021-07-09 10:07:39 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async postAsymmetricMessage(
|
2022-09-11 00:57:10 +10:00
|
|
|
message: MessageRpcQuery,
|
2021-07-09 10:07:39 +10:00
|
|
|
publicKey: Uint8Array,
|
2021-08-20 10:12:19 +10:00
|
|
|
pubSubTopic?: string
|
2021-07-09 10:07:39 +10:00
|
|
|
): Promise<boolean> {
|
|
|
|
|
this.checkProcess();
|
|
|
|
|
|
|
|
|
|
if (!message.payload) {
|
2022-02-04 14:12:00 +11:00
|
|
|
throw "Attempting to send empty message";
|
2021-07-09 10:07:39 +10:00
|
|
|
}
|
|
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
return this.rpcCall<boolean>("post_waku_v2_private_v1_asymmetric_message", [
|
2021-08-20 10:12:19 +10:00
|
|
|
pubSubTopic ? pubSubTopic : DefaultPubSubTopic,
|
2021-07-09 10:07:39 +10:00
|
|
|
message,
|
2022-02-14 10:50:02 +11:00
|
|
|
"0x" + bytesToHex(publicKey),
|
2021-07-09 10:07:39 +10:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-09 10:37:29 +10:00
|
|
|
async getAsymmetricMessages(
|
|
|
|
|
privateKey: Uint8Array,
|
2021-08-20 10:12:19 +10:00
|
|
|
pubSubTopic?: string
|
2022-09-11 00:57:10 +10:00
|
|
|
): Promise<MessageRpcResponseHex[]> {
|
2021-07-09 10:37:29 +10:00
|
|
|
this.checkProcess();
|
|
|
|
|
|
2022-09-11 00:57:10 +10:00
|
|
|
return await this.rpcCall<MessageRpcResponseHex[]>(
|
2022-02-04 14:12:00 +11:00
|
|
|
"get_waku_v2_private_v1_asymmetric_messages",
|
2021-07-09 10:37:29 +10:00
|
|
|
[
|
2021-08-20 10:12:19 +10:00
|
|
|
pubSubTopic ? pubSubTopic : DefaultPubSubTopic,
|
2022-02-14 10:50:02 +11:00
|
|
|
"0x" + bytesToHex(privateKey),
|
2021-07-09 10:37:29 +10:00
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-14 10:50:02 +11:00
|
|
|
async getSymmetricKey(): Promise<Uint8Array> {
|
2021-07-15 12:12:43 +10:00
|
|
|
this.checkProcess();
|
|
|
|
|
|
|
|
|
|
return this.rpcCall<string>(
|
2022-02-04 14:12:00 +11:00
|
|
|
"get_waku_v2_private_v1_symmetric_key",
|
2021-07-15 12:12:43 +10:00
|
|
|
[]
|
2022-02-14 10:50:02 +11:00
|
|
|
).then(hexToBytes);
|
2021-07-15 12:12:43 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async postSymmetricMessage(
|
2022-09-11 00:57:10 +10:00
|
|
|
message: MessageRpcQuery,
|
2021-07-15 12:12:43 +10:00
|
|
|
symKey: Uint8Array,
|
2021-08-20 10:12:19 +10:00
|
|
|
pubSubTopic?: string
|
2021-07-15 12:12:43 +10:00
|
|
|
): Promise<boolean> {
|
|
|
|
|
this.checkProcess();
|
|
|
|
|
|
|
|
|
|
if (!message.payload) {
|
2022-02-04 14:12:00 +11:00
|
|
|
throw "Attempting to send empty message";
|
2021-07-15 12:12:43 +10:00
|
|
|
}
|
|
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
return this.rpcCall<boolean>("post_waku_v2_private_v1_symmetric_message", [
|
2021-08-20 10:12:19 +10:00
|
|
|
pubSubTopic ? pubSubTopic : DefaultPubSubTopic,
|
2021-07-15 12:12:43 +10:00
|
|
|
message,
|
2022-02-14 10:50:02 +11:00
|
|
|
"0x" + bytesToHex(symKey),
|
2021-07-15 12:12:43 +10:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getSymmetricMessages(
|
|
|
|
|
symKey: Uint8Array,
|
2021-08-20 10:12:19 +10:00
|
|
|
pubSubTopic?: string
|
2022-09-11 00:57:10 +10:00
|
|
|
): Promise<MessageRpcResponseHex[]> {
|
2021-07-15 12:12:43 +10:00
|
|
|
this.checkProcess();
|
|
|
|
|
|
2022-09-11 00:57:10 +10:00
|
|
|
return await this.rpcCall<MessageRpcResponseHex[]>(
|
2022-02-04 14:12:00 +11:00
|
|
|
"get_waku_v2_private_v1_symmetric_messages",
|
2022-02-14 10:50:02 +11:00
|
|
|
[
|
|
|
|
|
pubSubTopic ? pubSubTopic : DefaultPubSubTopic,
|
|
|
|
|
"0x" + bytesToHex(symKey),
|
|
|
|
|
]
|
2021-07-15 12:12:43 +10:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-12 17:08:42 +11:00
|
|
|
async getPeerId(): Promise<PeerId> {
|
2022-01-19 15:43:45 +11:00
|
|
|
return await this._getPeerId().then((res) => res.peerId);
|
2021-03-23 11:14:51 +11:00
|
|
|
}
|
2021-03-12 17:08:42 +11:00
|
|
|
|
2021-03-23 11:14:51 +11:00
|
|
|
async getMultiaddrWithId(): Promise<Multiaddr> {
|
2022-01-19 15:43:45 +11:00
|
|
|
return await this._getPeerId().then((res) => res.multiaddrWithId);
|
2021-03-23 11:14:51 +11:00
|
|
|
}
|
2021-03-12 17:08:42 +11:00
|
|
|
|
2022-01-19 15:43:45 +11:00
|
|
|
private async _getPeerId(): Promise<{
|
2021-03-23 11:14:51 +11:00
|
|
|
peerId: PeerId;
|
|
|
|
|
multiaddrWithId: Multiaddr;
|
|
|
|
|
}> {
|
|
|
|
|
if (this.peerId && this.multiaddrWithId) {
|
|
|
|
|
return { peerId: this.peerId, multiaddrWithId: this.multiaddrWithId };
|
|
|
|
|
}
|
|
|
|
|
const res = await this.info();
|
2022-01-20 13:00:58 +11:00
|
|
|
this.multiaddrWithId = res.listenAddresses
|
|
|
|
|
.map((ma) => multiaddr(ma))
|
2022-02-04 14:12:00 +11:00
|
|
|
.find((ma) => ma.protoNames().includes("ws"));
|
2022-04-01 12:19:51 +11:00
|
|
|
if (!this.multiaddrWithId) throw "Nwaku did not return a ws multiaddr";
|
2021-03-23 11:14:51 +11:00
|
|
|
const peerIdStr = this.multiaddrWithId.getPeerId();
|
2022-04-01 12:19:51 +11:00
|
|
|
if (!peerIdStr) throw "Nwaku multiaddr does not contain peerId";
|
2022-06-20 16:48:30 +10:00
|
|
|
this.peerId = peerIdFromString(peerIdStr);
|
2021-03-23 11:14:51 +11:00
|
|
|
return { peerId: this.peerId, multiaddrWithId: this.multiaddrWithId };
|
2021-03-10 17:39:53 +11:00
|
|
|
}
|
|
|
|
|
|
2021-03-12 17:08:42 +11:00
|
|
|
get rpcUrl(): string {
|
2022-02-01 12:54:54 +11:00
|
|
|
return `http://localhost:${this.rpcPort}/`;
|
2021-03-10 17:39:53 +11:00
|
|
|
}
|
|
|
|
|
|
2021-05-03 15:52:38 +10:00
|
|
|
private async rpcCall<T>(
|
2021-04-13 15:22:29 +10:00
|
|
|
method: string,
|
|
|
|
|
params: Array<string | number | unknown>
|
2021-05-03 15:54:40 +10:00
|
|
|
): Promise<T> {
|
2022-09-05 21:30:29 +10:00
|
|
|
log("RPC Query: ", method, params);
|
2022-02-14 09:26:22 +11:00
|
|
|
const res = await fetch(this.rpcUrl, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: JSON.stringify({
|
2022-02-04 14:12:00 +11:00
|
|
|
jsonrpc: "2.0",
|
2021-03-10 17:39:53 +11:00
|
|
|
id: 1,
|
|
|
|
|
method,
|
|
|
|
|
params,
|
2022-02-14 09:26:22 +11:00
|
|
|
}),
|
|
|
|
|
headers: new Headers({ "Content-Type": "application/json" }),
|
|
|
|
|
});
|
|
|
|
|
const json = await res.json();
|
2022-11-15 14:15:29 +11:00
|
|
|
log(`RPC Response: `, JSON.stringify(json));
|
2022-02-14 09:26:22 +11:00
|
|
|
return json.result;
|
2021-03-10 17:39:53 +11:00
|
|
|
}
|
|
|
|
|
|
2021-05-03 15:52:38 +10:00
|
|
|
private checkProcess(): void {
|
2021-03-10 17:39:53 +11:00
|
|
|
if (!this.process) {
|
2022-04-01 12:19:51 +11:00
|
|
|
throw "Nwaku hasn't started";
|
2021-03-10 17:39:53 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-11 10:54:35 +11:00
|
|
|
|
|
|
|
|
export function argsToArray(args: Args): Array<string> {
|
|
|
|
|
const array = [];
|
|
|
|
|
|
|
|
|
|
for (const [key, value] of Object.entries(args)) {
|
|
|
|
|
// Change the key from camelCase to kebab-case
|
2022-11-15 14:09:04 +11:00
|
|
|
const kebabKey = key.replace(/([A-Z])/g, (_, capital) => {
|
2022-02-04 14:12:00 +11:00
|
|
|
return "-" + capital.toLowerCase();
|
2021-03-11 10:54:35 +11:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const arg = `--${kebabKey}=${value}`;
|
|
|
|
|
array.push(arg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return array;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-12 17:08:42 +11:00
|
|
|
export function defaultArgs(): Args {
|
2021-03-11 10:54:35 +11:00
|
|
|
return {
|
2022-02-04 14:12:00 +11:00
|
|
|
listenAddress: "127.0.0.1",
|
2022-05-26 15:49:39 +10:00
|
|
|
nat: "none",
|
2021-03-11 10:54:35 +11:00
|
|
|
relay: true,
|
|
|
|
|
rpc: true,
|
|
|
|
|
rpcAdmin: true,
|
2022-01-20 13:00:58 +11:00
|
|
|
websocketSupport: true,
|
2022-11-17 11:02:04 +11:00
|
|
|
logLevel: LogLevel.Trace,
|
2021-03-11 10:54:35 +11:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-12 17:08:42 +11:00
|
|
|
interface RpcInfoResponse {
|
2022-01-19 15:43:45 +11:00
|
|
|
// multiaddrs including peer id.
|
|
|
|
|
listenAddresses: string[];
|
2022-05-04 20:07:21 +10:00
|
|
|
enrUri?: string;
|
2021-03-12 17:08:42 +11:00
|
|
|
}
|