@nktkas/hyperliquid
Version:
Hyperliquid API SDK for all major JS runtimes, written in TypeScript.
47 lines (46 loc) • 1.9 kB
JavaScript
/**
* 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