UNPKG

@nktkas/hyperliquid

Version:

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

76 lines (75 loc) 3.12 kB
import * as v from "valibot"; // ============================================================ // API Schemas // ============================================================ /** * Subscription to mark and mid price events for all assets. * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions */ export const FastAssetCtxsRequest = /* @__PURE__ */ (()=>{ return v.object({ /** Type of subscription. */ type: v.literal("fastAssetCtxs") }); })(); // ============================================================ // Execution Logic // ============================================================ import { parse } from "../../../_base.js"; /** * Subscribe to mark and mid prices for all assets. * * @param config General configuration for Subscription API subscriptions. * @param listener A callback function to be called when the event is received. * @param options Options to control the subscription lifecycle. * @return A request-promise that resolves with a {@link ISubscription} object to manage the subscription lifecycle. * * @throws {ValidationError} When the request parameters fail validation (before sending). * @throws {TransportError} When the transport layer throws an error. * * @example * ```ts * import { WebSocketTransport } from "@nktkas/hyperliquid"; * import { fastAssetCtxs } from "@nktkas/hyperliquid/api/subscription"; * * const transport = new WebSocketTransport(); * * const sub = await fastAssetCtxs( * { transport }, * (data) => console.log(data), * ); * ``` * * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions */ export function fastAssetCtxs(config, listener, options) { const payload = parse(FastAssetCtxsRequest, { type: "fastAssetCtxs" }); // The server pushes each update as a base64 + raw DEFLATE (RFC 1951) compressed JSON string (assumed to be valid). // Decompress sequentially so events reach the listener in arrival order. let queue = Promise.resolve(); return config.transport.subscribe(payload.type, payload, (e)=>{ queue = queue.then(async ()=>listener(await decompress(e.detail))); }, options); } /** Decode a base64 + raw DEFLATE (RFC 1951) payload into a {@linkcode FastAssetCtxsEvent}. */ async function decompress(data) { const bytes = Uint8Array.from(atob(data), (c)=>c.charCodeAt(0)); const stream = new DecompressionStream("deflate-raw"); const writer = stream.writable.getWriter(); // Do not await write/close before draining: backpressure on multi-chunk output would deadlock. writer.write(bytes); writer.close(); const reader = stream.readable.getReader(); const chunks = []; let result = await reader.read(); while(!result.done){ chunks.push(result.value); result = await reader.read(); } const merged = new Uint8Array(chunks.reduce((total, chunk)=>total + chunk.length, 0)); let offset = 0; for (const chunk of chunks){ merged.set(chunk, offset); offset += chunk.length; } return JSON.parse(new TextDecoder().decode(merged)); } //# sourceMappingURL=fastAssetCtxs.js.map