// @ts-ignore import Protomux from "protomux"; // @ts-ignore import { SPVNode } from "hsd/lib/node"; // @ts-ignore import { Peer as HNSPeer } from "hsd/lib/net"; // @ts-ignore import sodium from "sodium-universal"; import b4a from "b4a"; // @ts-ignore import c from "compact-encoding"; const PROTOCOL = "lumeweb.proxy.handshake"; import { Proxy, createSocket, createServer, Socket, } from "@lumeweb/libhyperproxy"; export default class HandshakeProxy extends Proxy { constructor({ swarm, listen = false }: { swarm: any; listen?: boolean }) { super({ swarm, listen, autostart: true, protocol: PROTOCOL, async onopen(socket: Socket) { const peer = HNSPeer.fromInbound(self._node.pool.options, socket); peer.connected = false; peer.outbound = true; if ( self._node.pool.peers.map.has(peer.hostname()) || self._node.pool.peers.ids.has(peer.id) ) { return { connect: false }; } self._node.pool.bindPeer(peer); const open = peer.tryOpen(); // @ts-ignore socket.emit("connect"); await open; self._node.pool.peers.add(peer); self._node.pool.connectedGroups.add(peer.address.getGroup()); self._node.pool.emit("peer", peer); return { connect: false }; }, }); const self = this; } private _node?: any; get node(): any { return this._node; } protected async _init() { this._node = new SPVNode({ config: false, argv: false, env: false, noDns: true, memory: false, logFile: false, logConsole: true, logLevel: "info", workers: true, network: "main", createServer, createSocket, }); if(this?._node?.http?.http?.listen){ this._node.http.http.listen = (port: number, host: string, cb: Function) => cb(); } await this._node.open(); this._node.pool.connected = true; this._node.startSync(); const topic = b4a.from(PROTOCOL); const topicHash = b4a.allocUnsafe(32); sodium.crypto_generichash(topicHash, topic); this.swarm.join(topicHash); } }