// @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 { private _join: boolean; constructor({ swarm, listen = false, join = false, }: { swarm: any; listen?: boolean; join?: boolean; }) { super({ swarm, listen, autostart: true, protocol: PROTOCOL, async onopen(inboundPeer, 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); peer.tryOpen(); // @ts-ignore socket.emit("connect"); 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; this._join = join; } 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(); if (this._join) { const topic = b4a.from(PROTOCOL); const topicHash = b4a.allocUnsafe(32); sodium.crypto_generichash(topicHash, topic); this.swarm.join(topicHash); } } }