65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
import type { Plugin, PluginAPI } from "@lumeweb/interface-relay";
|
|
import type { Peer } from "@lumeweb/peer-discovery";
|
|
import { IrcClient } from "@ctrl/irc";
|
|
import b4a from "b4a";
|
|
import jsonStringify from "json-stringify-deterministic";
|
|
import type { Message } from "@ctrl/irc/dist/src/parseMessage";
|
|
|
|
interface SignedPeerResponse extends Peer {
|
|
timestamp: number;
|
|
signature?: string;
|
|
}
|
|
|
|
interface Network {
|
|
host: string;
|
|
port: number;
|
|
ssl: boolean;
|
|
}
|
|
|
|
const plugin: Plugin = {
|
|
name: "discovery-irc",
|
|
async plugin(api: PluginAPI): Promise<void> {
|
|
for (const network of api.pluginConfig.array("networks", []) as Network[]) {
|
|
let client = new IrcClient(undefined, api.identity.fingerprintHex, {
|
|
host: network.host,
|
|
port: network.port,
|
|
secure: network.ssl,
|
|
channels: ["#lumeweb"],
|
|
});
|
|
client.addListener("message", function (from, to, message) {
|
|
const pubkey = b4a.from(message, "hex");
|
|
if (!b4a.equals(api.identity.publicKeyRaw, pubkey)) {
|
|
return;
|
|
}
|
|
|
|
const host = api.config.str("domain");
|
|
const port = api.config.uint("port");
|
|
const timestamp = Date.now();
|
|
|
|
let data = {
|
|
host,
|
|
port,
|
|
timestamp,
|
|
} as SignedPeerResponse;
|
|
|
|
data.signature = b4a
|
|
.from(api.identity.sign(b4a.from(jsonStringify(data))))
|
|
.toString("hex");
|
|
|
|
client.say(from, jsonStringify(data));
|
|
});
|
|
client.addListener("error", (message: Message) => {
|
|
api.logger.error(message);
|
|
});
|
|
|
|
client.connect();
|
|
|
|
process.on("SIGTERM", () => {
|
|
client.end();
|
|
});
|
|
}
|
|
},
|
|
};
|
|
|
|
export default plugin;
|