UNPKG

@nktkas/hyperliquid

Version:

Hyperliquid API SDK for all major JS runtimes, written in TypeScript.

47 lines (46 loc) 1.9 kB
/** * Typed event target for Hyperliquid WebSocket messages. * * The frame types below are a trusted contract with the server: handlers * consume them without re-validating the shape. * * @module */ import { CustomEvent_ } from "../_polyfills.js"; /** Matches the `{ channel, data? }` envelope; `pong` is the only frame without `data`. */ function isHyperliquidEvent(msg) { return typeof msg === "object" && msg !== null && "channel" in msg && typeof msg.channel === "string"; } // The explorer RPC pushes raw arrays without a { channel, data } envelope: // detect them by shape and route them to synthetic "_"-suffixed channels. function isExplorerBlockEvent(msg) { return Array.isArray(msg) && msg.length > 0 && typeof msg[0] === "object" && msg[0] !== null && "blockTime" in msg[0] && "hash" in msg[0] && "height" in msg[0] && "numTxs" in msg[0] && "proposer" in msg[0]; } function isExplorerTxsEvent(msg) { return Array.isArray(msg) && msg.length > 0 && typeof msg[0] === "object" && msg[0] !== null && "action" in msg[0] && "block" in msg[0] && "error" in msg[0] && "hash" in msg[0] && "time" in msg[0] && "user" in msg[0]; } export class HyperliquidEventTarget extends EventTarget { constructor(socket){ super(); socket.addEventListener("message", (event)=>{ let msg; try { msg = JSON.parse(event.data); } catch { return; // Ignore non-JSON frames } if (isHyperliquidEvent(msg)) { this.dispatchEvent(new CustomEvent_(msg.channel, { detail: msg.data })); } else if (isExplorerBlockEvent(msg)) { this.dispatchEvent(new CustomEvent_("explorerBlock_", { detail: msg })); } else if (isExplorerTxsEvent(msg)) { this.dispatchEvent(new CustomEvent_("explorerTxs_", { detail: msg })); } }); } } //# sourceMappingURL=_events.js.map