From 1b78d0e696f57520fb717d839c648e400d7bbe83 Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Fri, 30 Dec 2022 01:00:45 -0500 Subject: [PATCH] *Implement a protocol manager to register protomux based protocols and add it to the plugin api --- src/modules/plugin.ts | 10 +++++++++- src/modules/swarm.ts | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/modules/plugin.ts b/src/modules/plugin.ts index 7afb069..ac45d55 100644 --- a/src/modules/plugin.ts +++ b/src/modules/plugin.ts @@ -13,7 +13,11 @@ import pluginCore from "./plugins/core"; import type Config from "@lumeweb/cfg"; import EventEmitter2 from "eventemitter2"; import log from "../log.js"; -import { get as getSwarm } from "./swarm.js"; +import { + get as getSwarm, + getProtocolManager, + ProtocolManager, +} from "./swarm.js"; import { get as getSSl, SSLManager } from "./ssl.js"; import type { HDKey } from "micro-ed25519-hdkey"; @@ -86,6 +90,10 @@ class PluginAPI extends EventEmitter2 { return getSSl(); } + get protocols(): ProtocolManager { + return getProtocolManager(); + } + public loadPlugin( moduleName: string ): (moduleName: string) => Promise { diff --git a/src/modules/swarm.ts b/src/modules/swarm.ts index f6a6a09..efd88dd 100644 --- a/src/modules/swarm.ts +++ b/src/modules/swarm.ts @@ -5,6 +5,8 @@ import Hyperswarm from "hyperswarm"; // @ts-ignore import DHT from "@hyperswarm/dht"; +// @ts-ignore +import Protomux from "protomux"; // @ts-ignore import sodium from "sodium-universal"; @@ -20,6 +22,7 @@ sodium.crypto_generichash(LUMEWEB_TOPIC_HASH, LUMEWEB); export type SecretStream = any; let node: Hyperswarm; +let protocolManager: ProtocolManager; export async function start() { const keyPair = getKeyPair(); @@ -51,3 +54,44 @@ export async function start() { export function get(): Hyperswarm { return node; } + +export class ProtocolManager { + private _protocols: Map = new Map(); + private _swarm; + + constructor(swarm: any) { + this._swarm = swarm; + + this._swarm.on("connection", (peer: any) => { + for (const protocol of this._protocols) { + Protomux.from(peer).pair( + protocol[0], + this.handler.bind(this, protocol[0], peer) + ); + } + }); + } + + private handler(protocol: string, peer: any) { + if (this._protocols.has(protocol)) { + this._protocols.get(protocol)?.(peer, Protomux.from(peer)); + } + } + + public register(name: string, handler: Function): boolean { + if (this._protocols.has(name)) { + return false; + } + + this._protocols.set(name, handler); + return true; + } +} + +export function getProtocolManager(): ProtocolManager { + if (!protocolManager) { + protocolManager = new ProtocolManager(get()); + } + + return protocolManager; +}