UNPKG

@bsv/authsocket-client

Version:
105 lines 3.84 kB
import { io as realIo } from 'socket.io-client'; import { Peer, Utils } from '@bsv/sdk'; import { SocketClientTransport } from './SocketClientTransport.js'; /** * Internal class that wraps a Socket.IO client connection with BRC-103 mutual authentication, * enabling secure and identity-aware communication with a server. */ class AuthSocketClientImpl { ioSocket; peer; connected = false; id = ''; serverIdentityKey; eventCallbacks = new Map(); /** * Creates an instance of AuthSocketClient. * * @param ioSocket - The underlying Socket.IO client socket instance. * @param peer - The BRC-103 Peer instance responsible for managing authenticated * communication, including message signing and verification. */ constructor(ioSocket, peer) { this.ioSocket = ioSocket; this.peer = peer; // Listen for 'connect' and 'disconnect' from underlying Socket.IO this.ioSocket.on('connect', () => { this.connected = true; this.id = this.ioSocket.id || ''; // Re-dispatch to dev if they've called "socket.on('connect', ...)" this.fireEventCallbacks('connect'); }); this.ioSocket.on('disconnect', (reason) => { this.connected = false; // Re-dispatch this.fireEventCallbacks('disconnect', reason); }); // Also listen for BRC-103 "general" messages // We'll rely on peer.listenForGeneralMessages this.peer.listenForGeneralMessages((senderKey, payload) => { this.serverIdentityKey = senderKey; const { eventName, data } = this.decodeEventPayload(payload); this.fireEventCallbacks(eventName, data); }); } on(eventName, callback) { let arr = this.eventCallbacks.get(eventName); if (!arr) { arr = []; this.eventCallbacks.set(eventName, arr); } arr.push(callback); return this; } emit(eventName, data) { // We sign a BRC-103 "general" message and send to the server // via peer.toPeer const encoded = this.encodeEventPayload(eventName, data); this.peer.toPeer(encoded, this.serverIdentityKey).catch(err => { console.error(`BRC103IoClientSocket emit error for event "${eventName}":`, err); }); return this; } disconnect() { this.serverIdentityKey = undefined; this.ioSocket.disconnect(); } fireEventCallbacks(eventName, data) { const cbs = this.eventCallbacks.get(eventName); if (!cbs) return; for (const cb of cbs) { cb(data); } } encodeEventPayload(eventName, data) { const obj = { eventName, data }; return Utils.toArray(JSON.stringify(obj), 'utf8'); } decodeEventPayload(payload) { try { const str = Utils.toUTF8(payload); return JSON.parse(str); } catch { return { eventName: '_unknown', data: undefined }; } } } /** * Factory function for creating a new AuthSocketClientImpl instance. * * @param url - The server URL * @param opts - Contains wallet, requested certificates, and other optional settings */ export function AuthSocketClient(url, opts) { // 1) Create real socket.io-client connection const socket = realIo(url, opts.managerOptions); // 2) Create a BRC-103 transport for the new socket const transport = new SocketClientTransport(socket); // 3) Create a Peer const peer = new Peer(opts.wallet, transport, opts.requestedCertificates, opts.sessionManager); // 4) Return our new AuthSocketClientImpl return new AuthSocketClientImpl(socket, peer); } //# sourceMappingURL=AuthSocketClient.js.map