@mmflow/sdk 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  // src/socket.ts
4
- var DEFAULT_URL = "wss://mmflowai-production.up.railway.app/v1";
4
+ var DEFAULT_URL = "wss://ws.mmflow.ai/v1";
5
5
  var keyOf = (channel, symbol) => `${channel}:${symbol}`;
6
6
  var MmflowSocket = class {
7
7
  constructor(options = {}) {
@@ -147,7 +147,7 @@ var MmflowSocket = class {
147
147
 
148
148
  // src/feed.ts
149
149
  var DEFAULT_BASE = "https://mmflow.ai";
150
- var DEFAULT_WS = "wss://mmflowai-production.up.railway.app/v1";
150
+ var DEFAULT_WS = "wss://ws.mmflow.ai/v1";
151
151
  function createMmflowFeed(opts = {}) {
152
152
  const base = (opts.baseUrl ?? DEFAULT_BASE).replace(/\/$/, "");
153
153
  const transport = opts.transport ?? "sse";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/socket.ts","../src/feed.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// MmflowSocket — typed WebSocket client for the mmflow real-time data API.\n//\n// Protocol (JSON frames):\n// client → server : { op: \"auth\", apiKey }\n// { op: \"subscribe\", channel, symbol, id }\n// { op: \"unsubscribe\", channel, symbol, id }\n// server → client : { type: \"ack\", id, channel, symbol }\n// { type: \"data\", channel, symbol, seq, ts, payload }\n// { type: \"heartbeat\", ts }\n// { type: \"error\", code, message, id? }\n//\n// Resilience: exponential-backoff auto-reconnect, with re-auth + replay of all\n// active subscriptions on every (re)connection — the same discipline the app's\n// in-process HL client uses.\n\nimport type { Unsubscribe } from \"./types\";\n\nexport type MmflowChannel =\n | \"trades\"\n | \"orderbook\"\n | \"candles\"\n | \"liquidations\"\n | \"funding\"\n | \"openInterest\"\n | \"markPrice\"\n | \"footprint\";\n\nexport interface MmflowSocketOptions {\n /** Gateway URL. Default is the live Railway gateway. */\n url?: string;\n /** API key sent in the opening `auth` frame. */\n apiKey?: string;\n /** Reconnect automatically on drop. Default true. */\n autoReconnect?: boolean;\n /** Initial reconnect backoff (ms). Default 500. */\n reconnectInitialMs?: number;\n /** Max reconnect backoff (ms). Default 30000. */\n reconnectMaxMs?: number;\n /** Called on a server `error` frame. */\n onError?: (code: string, message: string) => void;\n}\n\nexport interface MmflowMessageMeta {\n channel: MmflowChannel;\n symbol: string;\n seq?: number;\n ts?: number;\n}\n\nexport type MmflowDataHandler = (\n payload: unknown,\n meta: MmflowMessageMeta,\n) => void;\n\ninterface IncomingMessage {\n type?: \"ack\" | \"data\" | \"heartbeat\" | \"pong\" | \"error\";\n op?: string;\n channel?: MmflowChannel;\n symbol?: string;\n seq?: number;\n ts?: number;\n payload?: unknown;\n code?: string;\n message?: string;\n}\n\ninterface Subscription {\n channel: MmflowChannel;\n symbol: string;\n handlers: Set<MmflowDataHandler>;\n}\n\nconst DEFAULT_URL = \"wss://mmflowai-production.up.railway.app/v1\";\nconst keyOf = (channel: string, symbol: string) => `${channel}:${symbol}`;\n\nexport class MmflowSocket {\n private readonly url: string;\n private readonly apiKey?: string;\n private readonly autoReconnect: boolean;\n private readonly reconnectInitialMs: number;\n private readonly reconnectMaxMs: number;\n private readonly onError?: (code: string, message: string) => void;\n\n private ws: WebSocket | null = null;\n private readonly subs = new Map<string, Subscription>();\n private backoff: number;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closedByUser = false;\n private authed = false;\n private nextId = 1;\n\n constructor(options: MmflowSocketOptions = {}) {\n this.url = options.url ?? DEFAULT_URL;\n this.apiKey = options.apiKey;\n this.autoReconnect = options.autoReconnect ?? true;\n this.reconnectInitialMs = options.reconnectInitialMs ?? 500;\n this.reconnectMaxMs = options.reconnectMaxMs ?? 30_000;\n this.onError = options.onError;\n this.backoff = this.reconnectInitialMs;\n }\n\n /** Open the socket. Idempotent; subscriptions made before connect() are\n * sent as soon as the connection is established. */\n connect(): void {\n this.closedByUser = false;\n this.open();\n }\n\n private open(): void {\n if (typeof WebSocket === \"undefined\") {\n throw new Error(\n \"MmflowSocket requires a global WebSocket (browser, or Node >= 21 / the `ws` package).\",\n );\n }\n if (\n this.ws &&\n (this.ws.readyState === WebSocket.OPEN ||\n this.ws.readyState === WebSocket.CONNECTING)\n ) {\n return;\n }\n\n const ws = new WebSocket(this.url);\n this.ws = ws;\n this.authed = false;\n\n ws.onopen = () => {\n this.backoff = this.reconnectInitialMs;\n if (this.apiKey) this.send({ op: \"auth\", apiKey: this.apiKey });\n else this.replaySubscriptions();\n };\n ws.onmessage = (ev: MessageEvent) => this.handleMessage(ev);\n ws.onclose = () => {\n this.ws = null;\n this.authed = false;\n if (!this.closedByUser && this.autoReconnect) this.scheduleReconnect();\n };\n ws.onerror = () => {\n // A close event follows; reconnection is handled there.\n };\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer != null) return;\n const delay = this.backoff;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.open();\n }, delay);\n this.backoff = Math.min(this.backoff * 2, this.reconnectMaxMs);\n }\n\n private handleMessage(ev: MessageEvent): void {\n if (typeof ev.data !== \"string\") return;\n let msg: IncomingMessage;\n try {\n msg = JSON.parse(ev.data) as IncomingMessage;\n } catch {\n return;\n }\n if (msg.type === \"ack\" && msg.op === \"auth\") {\n this.authed = true;\n this.replaySubscriptions();\n } else if (msg.type === \"data\" && msg.channel && msg.symbol) {\n const sub = this.subs.get(keyOf(msg.channel, msg.symbol));\n if (!sub) return;\n const meta: MmflowMessageMeta = {\n channel: msg.channel,\n symbol: msg.symbol,\n seq: msg.seq,\n ts: msg.ts,\n };\n sub.handlers.forEach((handler) => {\n try {\n handler(msg.payload, meta);\n } catch {\n // Isolate handler faults so one bad listener can't kill the socket.\n }\n });\n } else if (msg.type === \"error\") {\n this.onError?.(msg.code ?? \"error\", msg.message ?? \"\");\n }\n // \"ack\" / \"heartbeat\" / \"pong\" require no action.\n }\n\n private send(obj: unknown): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(obj));\n }\n }\n\n private sendSubscribe(sub: Subscription): void {\n if (this.apiKey && !this.authed) return;\n this.send({\n op: \"subscribe\",\n channel: sub.channel,\n symbol: sub.symbol,\n id: this.nextId++,\n });\n }\n\n private replaySubscriptions(): void {\n this.subs.forEach((sub) => this.sendSubscribe(sub));\n }\n\n /**\n * Subscribe to `channel` for `symbol`. Returns an unsubscribe function.\n * Safe to call before connect() — it is (re)sent on each connection.\n * Multiple handlers for the same (channel, symbol) share one subscription.\n */\n subscribe(\n channel: MmflowChannel,\n symbol: string,\n handler: MmflowDataHandler,\n ): Unsubscribe {\n const key = keyOf(channel, symbol);\n let sub = this.subs.get(key);\n if (!sub) {\n sub = { channel, symbol, handlers: new Set() };\n this.subs.set(key, sub);\n this.sendSubscribe(sub);\n }\n sub.handlers.add(handler);\n\n return () => {\n const existing = this.subs.get(key);\n if (!existing) return;\n existing.handlers.delete(handler);\n if (existing.handlers.size === 0) {\n this.subs.delete(key);\n this.send({ op: \"unsubscribe\", channel, symbol, id: this.nextId++ });\n }\n };\n }\n\n /** Close permanently (disables auto-reconnect) and drop all subscriptions. */\n close(): void {\n this.closedByUser = true;\n if (this.reconnectTimer != null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.subs.clear();\n this.authed = false;\n this.ws?.close();\n this.ws = null;\n }\n}\n","// createMmflowFeed — a ready-made DataFeed backed by mmflow's public API.\n// History comes from the REST candles endpoint. Live trades default to SSE\n// for backwards compatibility, or can use the keyed WebSocket gateway with\n// `transport: \"ws\"`.\n//\n// import { createChart } from \"@mmflow/charts\";\n// import { createMmflowFeed } from \"@mmflow/sdk\";\n// const chart = createChart({ container });\n// chart.addCandleSeries();\n// chart.setData(createMmflowFeed()); // symbol/resolution via the binding\n\nimport { MmflowSocket } from \"./socket\";\nimport type {\n Candle,\n DataFeed,\n FeedUpdate,\n FootprintBar,\n MarkerSpec,\n OrderBookSnapshot,\n Unsubscribe,\n VolumeProfileSnapshot,\n} from \"./types\";\n\nexport interface MmflowFeedOptions {\n /** API origin. Default \"https://mmflow.ai\". */\n baseUrl?: string;\n /** Live transport. Default \"sse\" for backwards compatibility. */\n transport?: \"sse\" | \"ws\";\n /** API key. Used in the WS auth frame, or as `api_key` for keyed SSE quotas. */\n apiKey?: string;\n /** WebSocket gateway URL. Default is the live Railway gateway. */\n wsUrl?: string;\n /** Default symbol, used when the chart doesn't supply one (e.g. a vanilla\n * createChart without setData symbol opts). */\n symbol?: string;\n /** Minimum trade notional (USD) to stream. Default 0 (all prints). */\n minUsd?: number;\n}\n\nconst DEFAULT_BASE = \"https://mmflow.ai\";\nconst DEFAULT_WS = \"wss://mmflowai-production.up.railway.app/v1\";\n\n// Hyperliquid candle row as returned by /api/hl/candles (OHLCV serialized as\n// strings). `t` is the bar open time in epoch ms.\ninterface HlCandleRow {\n t: number;\n o: string;\n h: string;\n l: string;\n c: string;\n v: string;\n}\n\n// Normalized trade tick emitted by /api/v1/streams/trades (event: \"trade\").\ninterface TradeTick {\n coin: string;\n side: \"buy\" | \"sell\";\n price: number;\n size: number;\n ts: number;\n}\n\nexport function createMmflowFeed(opts: MmflowFeedOptions = {}): DataFeed {\n const base = (opts.baseUrl ?? DEFAULT_BASE).replace(/\\/$/, \"\");\n const transport = opts.transport ?? \"sse\";\n let socket: MmflowSocket | null = null;\n let socketRefs = 0;\n\n const ensureSocket = (): MmflowSocket => {\n if (transport !== \"ws\") {\n throw new Error(\"createMmflowFeed: this method requires transport=\\\"ws\\\"\");\n }\n if (!opts.apiKey) {\n throw new Error(\"createMmflowFeed: transport=\\\"ws\\\" requires apiKey\");\n }\n if (!socket) {\n socket = new MmflowSocket({\n apiKey: opts.apiKey,\n url: opts.wsUrl ?? DEFAULT_WS,\n });\n socket.connect();\n }\n return socket;\n };\n\n const attachSocket = (\n channel: Parameters<MmflowSocket[\"subscribe\"]>[0],\n symbol: string,\n handler: Parameters<MmflowSocket[\"subscribe\"]>[2],\n ): Unsubscribe => {\n const sock = ensureSocket();\n socketRefs++;\n const unsub = sock.subscribe(channel, symbol, handler);\n return () => {\n unsub();\n socketRefs = Math.max(0, socketRefs - 1);\n if (socketRefs === 0) {\n socket?.close();\n socket = null;\n }\n };\n };\n\n const feed: DataFeed = {\n async fetchCandles({ symbol, resolution, from, to }) {\n const hours = Math.min(720, Math.max(1, Math.ceil((to - from) / 3_600_000)));\n const url = new URL(`${base}/api/hl/candles`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"interval\", resolution);\n url.searchParams.set(\"hours\", String(hours));\n\n const res = await fetch(url.toString());\n if (!res.ok) {\n throw new Error(`mmflow: candles request failed (${res.status})`);\n }\n const json = (await res.json()) as { candles?: HlCandleRow[] };\n const rows = json.candles ?? [];\n\n const out: Candle[] = [];\n for (const r of rows) {\n const time = Number(r.t);\n if (!Number.isFinite(time)) continue;\n out.push({\n time,\n open: Number(r.o),\n high: Number(r.h),\n low: Number(r.l),\n close: Number(r.c),\n volume: Number(r.v),\n });\n }\n return out;\n },\n\n subscribe(symbol, _resolution, onUpdate) {\n const feedSymbol = symbol || opts.symbol || \"\";\n if (transport === \"ws\") {\n return attachSocket(\"trades\", feedSymbol, (payload) => {\n const t = payload as Partial<TradeTick> & {\n ts?: number;\n time?: number;\n symbol?: string;\n };\n const price = Number(t.price);\n const size = Number(t.size);\n const time = Number(t.ts ?? t.time);\n if (!Number.isFinite(price) || !Number.isFinite(size) || !Number.isFinite(time)) {\n return;\n }\n onUpdate({\n symbol: t.coin ?? t.symbol ?? feedSymbol,\n price,\n size,\n time,\n side: t.side,\n } satisfies FeedUpdate);\n });\n }\n if (typeof EventSource === \"undefined\") {\n throw new Error(\n \"createMmflowFeed.subscribe needs a global EventSource (browser). \" +\n \"In Node, install an EventSource polyfill or use MmflowSocket instead.\",\n );\n }\n const url = new URL(`${base}/api/v1/streams/trades`);\n url.searchParams.set(\"coin\", feedSymbol);\n if (opts.minUsd != null) url.searchParams.set(\"minUsd\", String(opts.minUsd));\n if (opts.apiKey) url.searchParams.set(\"api_key\", opts.apiKey);\n\n const es = new EventSource(url.toString());\n const onTrade = (e: MessageEvent) => {\n try {\n const t = JSON.parse(e.data as string) as TradeTick;\n onUpdate({\n symbol: t.coin ?? symbol,\n price: t.price,\n size: t.size,\n time: t.ts,\n side: t.side,\n } satisfies FeedUpdate);\n } catch {\n // Ignore malformed frames; EventSource keeps the stream alive.\n }\n };\n es.addEventListener(\"trade\", onTrade as EventListener);\n return () => {\n es.removeEventListener(\"trade\", onTrade as EventListener);\n es.close();\n };\n },\n };\n\n feed.fetchFootprint = async (symbol, fpOpts): Promise<FootprintBar[]> => {\n const url = new URL(`${base}/api/v1/perps/footprint`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"kind\", \"time\");\n url.searchParams.set(\"interval\", String(fpOpts.intervalMs));\n url.searchParams.set(\"bars\", \"500\");\n const res = await fetch(url.toString());\n if (!res.ok) throw new Error(`mmflow: footprint request failed (${res.status})`);\n const json = (await res.json()) as { data?: Array<FootprintBar & { time?: number }> };\n return (json.data ?? []).map((bar) => ({\n t: Number((bar as { t?: number }).t ?? bar.time),\n open: Number(bar.open),\n high: Number(bar.high),\n low: Number(bar.low),\n close: Number(bar.close),\n levels: (bar.levels ?? []).map((level) => ({\n price: Number(level.price),\n buyVol: Number(level.buyVol),\n sellVol: Number(level.sellVol),\n })),\n }));\n };\n\n feed.fetchVolumeProfile = async (symbol): Promise<VolumeProfileSnapshot> => {\n const url = new URL(`${base}/api/hl/marketprofile`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"hours\", \"24\");\n url.searchParams.set(\"bins\", \"80\");\n const res = await fetch(url.toString());\n if (!res.ok) throw new Error(`mmflow: volume profile request failed (${res.status})`);\n const json = (await res.json()) as {\n bins?: Array<{ px: number; totalUsd: number }>;\n range?: { binWidth?: number };\n val?: number;\n vah?: number;\n };\n return {\n bins: (json.bins ?? []).map((bin) => ({\n px: Number(bin.px),\n totalUsd: Number(bin.totalUsd),\n })),\n binWidth: Number(json.range?.binWidth ?? 0),\n val: Number(json.val ?? 0),\n vah: Number(json.vah ?? 0),\n };\n };\n\n if (transport === \"ws\") {\n feed.subscribeOrderBook = (symbol, onBook) =>\n attachSocket(\"orderbook\", symbol || opts.symbol || \"\", (payload) => {\n const book = payload as {\n ts?: number;\n bids?: Array<{ price?: number; size?: number; px?: number; sz?: number }>;\n asks?: Array<{ price?: number; size?: number; px?: number; sz?: number }>;\n };\n const map = (rows: NonNullable<typeof book.bids>) =>\n rows.map((level) => ({\n px: Number(level.px ?? level.price),\n sz: Number(level.sz ?? level.size),\n }));\n onBook({\n time: Number(book.ts ?? Date.now()),\n bids: map(book.bids ?? []),\n asks: map(book.asks ?? []),\n } satisfies OrderBookSnapshot);\n });\n\n feed.subscribeMarkers = (symbol, onMarkers) =>\n attachSocket(\"liquidations\", symbol || opts.symbol || \"\", (payload) => {\n const e = payload as {\n ts?: number;\n price?: number;\n notionalUsd?: number;\n side?: string;\n };\n const marker: MarkerSpec = {\n t: Number(e.ts ?? Date.now()),\n price: Number(e.price),\n sizeUsd: Number(e.notionalUsd ?? 0),\n };\n if (!Number.isFinite(marker.price) || marker.sizeUsd <= 0) return;\n if (e.side === \"long\") onMarkers({ buys: [marker], sells: [] });\n else onMarkers({ buys: [], sells: [marker] });\n });\n }\n\n return feed;\n}\n"]}
1
+ {"version":3,"sources":["../src/socket.ts","../src/feed.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// MmflowSocket — typed WebSocket client for the mmflow real-time data API.\n//\n// Protocol (JSON frames):\n// client → server : { op: \"auth\", apiKey }\n// { op: \"subscribe\", channel, symbol, id }\n// { op: \"unsubscribe\", channel, symbol, id }\n// server → client : { type: \"ack\", id, channel, symbol }\n// { type: \"data\", channel, symbol, seq, ts, payload }\n// { type: \"heartbeat\", ts }\n// { type: \"error\", code, message, id? }\n//\n// Resilience: exponential-backoff auto-reconnect, with re-auth + replay of all\n// active subscriptions on every (re)connection — the same discipline the app's\n// in-process HL client uses.\n\nimport type { Unsubscribe } from \"./types\";\n\nexport type MmflowChannel =\n | \"trades\"\n | \"orderbook\"\n | \"candles\"\n | \"liquidations\"\n | \"funding\"\n | \"openInterest\"\n | \"markPrice\"\n | \"footprint\";\n\nexport interface MmflowSocketOptions {\n /** Gateway URL. Default is the branded production gateway. */\n url?: string;\n /** API key sent in the opening `auth` frame. */\n apiKey?: string;\n /** Reconnect automatically on drop. Default true. */\n autoReconnect?: boolean;\n /** Initial reconnect backoff (ms). Default 500. */\n reconnectInitialMs?: number;\n /** Max reconnect backoff (ms). Default 30000. */\n reconnectMaxMs?: number;\n /** Called on a server `error` frame. */\n onError?: (code: string, message: string) => void;\n}\n\nexport interface MmflowMessageMeta {\n channel: MmflowChannel;\n symbol: string;\n seq?: number;\n ts?: number;\n}\n\nexport type MmflowDataHandler = (\n payload: unknown,\n meta: MmflowMessageMeta,\n) => void;\n\ninterface IncomingMessage {\n type?: \"ack\" | \"data\" | \"heartbeat\" | \"pong\" | \"error\";\n op?: string;\n channel?: MmflowChannel;\n symbol?: string;\n seq?: number;\n ts?: number;\n payload?: unknown;\n code?: string;\n message?: string;\n}\n\ninterface Subscription {\n channel: MmflowChannel;\n symbol: string;\n handlers: Set<MmflowDataHandler>;\n}\n\nconst DEFAULT_URL = \"wss://ws.mmflow.ai/v1\";\nconst keyOf = (channel: string, symbol: string) => `${channel}:${symbol}`;\n\nexport class MmflowSocket {\n private readonly url: string;\n private readonly apiKey?: string;\n private readonly autoReconnect: boolean;\n private readonly reconnectInitialMs: number;\n private readonly reconnectMaxMs: number;\n private readonly onError?: (code: string, message: string) => void;\n\n private ws: WebSocket | null = null;\n private readonly subs = new Map<string, Subscription>();\n private backoff: number;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closedByUser = false;\n private authed = false;\n private nextId = 1;\n\n constructor(options: MmflowSocketOptions = {}) {\n this.url = options.url ?? DEFAULT_URL;\n this.apiKey = options.apiKey;\n this.autoReconnect = options.autoReconnect ?? true;\n this.reconnectInitialMs = options.reconnectInitialMs ?? 500;\n this.reconnectMaxMs = options.reconnectMaxMs ?? 30_000;\n this.onError = options.onError;\n this.backoff = this.reconnectInitialMs;\n }\n\n /** Open the socket. Idempotent; subscriptions made before connect() are\n * sent as soon as the connection is established. */\n connect(): void {\n this.closedByUser = false;\n this.open();\n }\n\n private open(): void {\n if (typeof WebSocket === \"undefined\") {\n throw new Error(\n \"MmflowSocket requires a global WebSocket (browser, or Node >= 21 / the `ws` package).\",\n );\n }\n if (\n this.ws &&\n (this.ws.readyState === WebSocket.OPEN ||\n this.ws.readyState === WebSocket.CONNECTING)\n ) {\n return;\n }\n\n const ws = new WebSocket(this.url);\n this.ws = ws;\n this.authed = false;\n\n ws.onopen = () => {\n this.backoff = this.reconnectInitialMs;\n if (this.apiKey) this.send({ op: \"auth\", apiKey: this.apiKey });\n else this.replaySubscriptions();\n };\n ws.onmessage = (ev: MessageEvent) => this.handleMessage(ev);\n ws.onclose = () => {\n this.ws = null;\n this.authed = false;\n if (!this.closedByUser && this.autoReconnect) this.scheduleReconnect();\n };\n ws.onerror = () => {\n // A close event follows; reconnection is handled there.\n };\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer != null) return;\n const delay = this.backoff;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.open();\n }, delay);\n this.backoff = Math.min(this.backoff * 2, this.reconnectMaxMs);\n }\n\n private handleMessage(ev: MessageEvent): void {\n if (typeof ev.data !== \"string\") return;\n let msg: IncomingMessage;\n try {\n msg = JSON.parse(ev.data) as IncomingMessage;\n } catch {\n return;\n }\n if (msg.type === \"ack\" && msg.op === \"auth\") {\n this.authed = true;\n this.replaySubscriptions();\n } else if (msg.type === \"data\" && msg.channel && msg.symbol) {\n const sub = this.subs.get(keyOf(msg.channel, msg.symbol));\n if (!sub) return;\n const meta: MmflowMessageMeta = {\n channel: msg.channel,\n symbol: msg.symbol,\n seq: msg.seq,\n ts: msg.ts,\n };\n sub.handlers.forEach((handler) => {\n try {\n handler(msg.payload, meta);\n } catch {\n // Isolate handler faults so one bad listener can't kill the socket.\n }\n });\n } else if (msg.type === \"error\") {\n this.onError?.(msg.code ?? \"error\", msg.message ?? \"\");\n }\n // \"ack\" / \"heartbeat\" / \"pong\" require no action.\n }\n\n private send(obj: unknown): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(obj));\n }\n }\n\n private sendSubscribe(sub: Subscription): void {\n if (this.apiKey && !this.authed) return;\n this.send({\n op: \"subscribe\",\n channel: sub.channel,\n symbol: sub.symbol,\n id: this.nextId++,\n });\n }\n\n private replaySubscriptions(): void {\n this.subs.forEach((sub) => this.sendSubscribe(sub));\n }\n\n /**\n * Subscribe to `channel` for `symbol`. Returns an unsubscribe function.\n * Safe to call before connect() — it is (re)sent on each connection.\n * Multiple handlers for the same (channel, symbol) share one subscription.\n */\n subscribe(\n channel: MmflowChannel,\n symbol: string,\n handler: MmflowDataHandler,\n ): Unsubscribe {\n const key = keyOf(channel, symbol);\n let sub = this.subs.get(key);\n if (!sub) {\n sub = { channel, symbol, handlers: new Set() };\n this.subs.set(key, sub);\n this.sendSubscribe(sub);\n }\n sub.handlers.add(handler);\n\n return () => {\n const existing = this.subs.get(key);\n if (!existing) return;\n existing.handlers.delete(handler);\n if (existing.handlers.size === 0) {\n this.subs.delete(key);\n this.send({ op: \"unsubscribe\", channel, symbol, id: this.nextId++ });\n }\n };\n }\n\n /** Close permanently (disables auto-reconnect) and drop all subscriptions. */\n close(): void {\n this.closedByUser = true;\n if (this.reconnectTimer != null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.subs.clear();\n this.authed = false;\n this.ws?.close();\n this.ws = null;\n }\n}\n","// createMmflowFeed — a ready-made DataFeed backed by mmflow's public API.\n// History comes from the REST candles endpoint. Live trades default to SSE\n// for backwards compatibility, or can use the keyed WebSocket gateway with\n// `transport: \"ws\"`.\n//\n// import { createChart } from \"@mmflow/charts\";\n// import { createMmflowFeed } from \"@mmflow/sdk\";\n// const chart = createChart({ container });\n// chart.addCandleSeries();\n// chart.setData(createMmflowFeed()); // symbol/resolution via the binding\n\nimport { MmflowSocket } from \"./socket\";\nimport type {\n Candle,\n DataFeed,\n FeedUpdate,\n FootprintBar,\n MarkerSpec,\n OrderBookSnapshot,\n Unsubscribe,\n VolumeProfileSnapshot,\n} from \"./types\";\n\nexport interface MmflowFeedOptions {\n /** API origin. Default \"https://mmflow.ai\". */\n baseUrl?: string;\n /** Live transport. Default \"sse\" for backwards compatibility. */\n transport?: \"sse\" | \"ws\";\n /** API key. Used in the WS auth frame, or as `api_key` for keyed SSE quotas. */\n apiKey?: string;\n /** WebSocket gateway URL. Default is the branded production gateway. */\n wsUrl?: string;\n /** Default symbol, used when the chart doesn't supply one (e.g. a vanilla\n * createChart without setData symbol opts). */\n symbol?: string;\n /** Minimum trade notional (USD) to stream. Default 0 (all prints). */\n minUsd?: number;\n}\n\nconst DEFAULT_BASE = \"https://mmflow.ai\";\nconst DEFAULT_WS = \"wss://ws.mmflow.ai/v1\";\n\n// Hyperliquid candle row as returned by /api/hl/candles (OHLCV serialized as\n// strings). `t` is the bar open time in epoch ms.\ninterface HlCandleRow {\n t: number;\n o: string;\n h: string;\n l: string;\n c: string;\n v: string;\n}\n\n// Normalized trade tick emitted by /api/v1/streams/trades (event: \"trade\").\ninterface TradeTick {\n coin: string;\n side: \"buy\" | \"sell\";\n price: number;\n size: number;\n ts: number;\n}\n\nexport function createMmflowFeed(opts: MmflowFeedOptions = {}): DataFeed {\n const base = (opts.baseUrl ?? DEFAULT_BASE).replace(/\\/$/, \"\");\n const transport = opts.transport ?? \"sse\";\n let socket: MmflowSocket | null = null;\n let socketRefs = 0;\n\n const ensureSocket = (): MmflowSocket => {\n if (transport !== \"ws\") {\n throw new Error(\"createMmflowFeed: this method requires transport=\\\"ws\\\"\");\n }\n if (!opts.apiKey) {\n throw new Error(\"createMmflowFeed: transport=\\\"ws\\\" requires apiKey\");\n }\n if (!socket) {\n socket = new MmflowSocket({\n apiKey: opts.apiKey,\n url: opts.wsUrl ?? DEFAULT_WS,\n });\n socket.connect();\n }\n return socket;\n };\n\n const attachSocket = (\n channel: Parameters<MmflowSocket[\"subscribe\"]>[0],\n symbol: string,\n handler: Parameters<MmflowSocket[\"subscribe\"]>[2],\n ): Unsubscribe => {\n const sock = ensureSocket();\n socketRefs++;\n const unsub = sock.subscribe(channel, symbol, handler);\n return () => {\n unsub();\n socketRefs = Math.max(0, socketRefs - 1);\n if (socketRefs === 0) {\n socket?.close();\n socket = null;\n }\n };\n };\n\n const feed: DataFeed = {\n async fetchCandles({ symbol, resolution, from, to }) {\n const hours = Math.min(720, Math.max(1, Math.ceil((to - from) / 3_600_000)));\n const url = new URL(`${base}/api/hl/candles`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"interval\", resolution);\n url.searchParams.set(\"hours\", String(hours));\n\n const res = await fetch(url.toString());\n if (!res.ok) {\n throw new Error(`mmflow: candles request failed (${res.status})`);\n }\n const json = (await res.json()) as { candles?: HlCandleRow[] };\n const rows = json.candles ?? [];\n\n const out: Candle[] = [];\n for (const r of rows) {\n const time = Number(r.t);\n if (!Number.isFinite(time)) continue;\n out.push({\n time,\n open: Number(r.o),\n high: Number(r.h),\n low: Number(r.l),\n close: Number(r.c),\n volume: Number(r.v),\n });\n }\n return out;\n },\n\n subscribe(symbol, _resolution, onUpdate) {\n const feedSymbol = symbol || opts.symbol || \"\";\n if (transport === \"ws\") {\n return attachSocket(\"trades\", feedSymbol, (payload) => {\n const t = payload as Partial<TradeTick> & {\n ts?: number;\n time?: number;\n symbol?: string;\n };\n const price = Number(t.price);\n const size = Number(t.size);\n const time = Number(t.ts ?? t.time);\n if (!Number.isFinite(price) || !Number.isFinite(size) || !Number.isFinite(time)) {\n return;\n }\n onUpdate({\n symbol: t.coin ?? t.symbol ?? feedSymbol,\n price,\n size,\n time,\n side: t.side,\n } satisfies FeedUpdate);\n });\n }\n if (typeof EventSource === \"undefined\") {\n throw new Error(\n \"createMmflowFeed.subscribe needs a global EventSource (browser). \" +\n \"In Node, install an EventSource polyfill or use MmflowSocket instead.\",\n );\n }\n const url = new URL(`${base}/api/v1/streams/trades`);\n url.searchParams.set(\"coin\", feedSymbol);\n if (opts.minUsd != null) url.searchParams.set(\"minUsd\", String(opts.minUsd));\n if (opts.apiKey) url.searchParams.set(\"api_key\", opts.apiKey);\n\n const es = new EventSource(url.toString());\n const onTrade = (e: MessageEvent) => {\n try {\n const t = JSON.parse(e.data as string) as TradeTick;\n onUpdate({\n symbol: t.coin ?? symbol,\n price: t.price,\n size: t.size,\n time: t.ts,\n side: t.side,\n } satisfies FeedUpdate);\n } catch {\n // Ignore malformed frames; EventSource keeps the stream alive.\n }\n };\n es.addEventListener(\"trade\", onTrade as EventListener);\n return () => {\n es.removeEventListener(\"trade\", onTrade as EventListener);\n es.close();\n };\n },\n };\n\n feed.fetchFootprint = async (symbol, fpOpts): Promise<FootprintBar[]> => {\n const url = new URL(`${base}/api/v1/perps/footprint`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"kind\", \"time\");\n url.searchParams.set(\"interval\", String(fpOpts.intervalMs));\n url.searchParams.set(\"bars\", \"500\");\n const res = await fetch(url.toString());\n if (!res.ok) throw new Error(`mmflow: footprint request failed (${res.status})`);\n const json = (await res.json()) as { data?: Array<FootprintBar & { time?: number }> };\n return (json.data ?? []).map((bar) => ({\n t: Number((bar as { t?: number }).t ?? bar.time),\n open: Number(bar.open),\n high: Number(bar.high),\n low: Number(bar.low),\n close: Number(bar.close),\n levels: (bar.levels ?? []).map((level) => ({\n price: Number(level.price),\n buyVol: Number(level.buyVol),\n sellVol: Number(level.sellVol),\n })),\n }));\n };\n\n feed.fetchVolumeProfile = async (symbol): Promise<VolumeProfileSnapshot> => {\n const url = new URL(`${base}/api/hl/marketprofile`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"hours\", \"24\");\n url.searchParams.set(\"bins\", \"80\");\n const res = await fetch(url.toString());\n if (!res.ok) throw new Error(`mmflow: volume profile request failed (${res.status})`);\n const json = (await res.json()) as {\n bins?: Array<{ px: number; totalUsd: number }>;\n range?: { binWidth?: number };\n val?: number;\n vah?: number;\n };\n return {\n bins: (json.bins ?? []).map((bin) => ({\n px: Number(bin.px),\n totalUsd: Number(bin.totalUsd),\n })),\n binWidth: Number(json.range?.binWidth ?? 0),\n val: Number(json.val ?? 0),\n vah: Number(json.vah ?? 0),\n };\n };\n\n if (transport === \"ws\") {\n feed.subscribeOrderBook = (symbol, onBook) =>\n attachSocket(\"orderbook\", symbol || opts.symbol || \"\", (payload) => {\n const book = payload as {\n ts?: number;\n bids?: Array<{ price?: number; size?: number; px?: number; sz?: number }>;\n asks?: Array<{ price?: number; size?: number; px?: number; sz?: number }>;\n };\n const map = (rows: NonNullable<typeof book.bids>) =>\n rows.map((level) => ({\n px: Number(level.px ?? level.price),\n sz: Number(level.sz ?? level.size),\n }));\n onBook({\n time: Number(book.ts ?? Date.now()),\n bids: map(book.bids ?? []),\n asks: map(book.asks ?? []),\n } satisfies OrderBookSnapshot);\n });\n\n feed.subscribeMarkers = (symbol, onMarkers) =>\n attachSocket(\"liquidations\", symbol || opts.symbol || \"\", (payload) => {\n const e = payload as {\n ts?: number;\n price?: number;\n notionalUsd?: number;\n side?: string;\n };\n const marker: MarkerSpec = {\n t: Number(e.ts ?? Date.now()),\n price: Number(e.price),\n sizeUsd: Number(e.notionalUsd ?? 0),\n };\n if (!Number.isFinite(marker.price) || marker.sizeUsd <= 0) return;\n if (e.side === \"long\") onMarkers({ buys: [marker], sells: [] });\n else onMarkers({ buys: [], sells: [marker] });\n });\n }\n\n return feed;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -95,7 +95,7 @@ interface MmflowFeedOptions {
95
95
  transport?: "sse" | "ws";
96
96
  /** API key. Used in the WS auth frame, or as `api_key` for keyed SSE quotas. */
97
97
  apiKey?: string;
98
- /** WebSocket gateway URL. Default is the live Railway gateway. */
98
+ /** WebSocket gateway URL. Default is the branded production gateway. */
99
99
  wsUrl?: string;
100
100
  /** Default symbol, used when the chart doesn't supply one (e.g. a vanilla
101
101
  * createChart without setData symbol opts). */
@@ -107,7 +107,7 @@ declare function createMmflowFeed(opts?: MmflowFeedOptions): DataFeed;
107
107
 
108
108
  type MmflowChannel = "trades" | "orderbook" | "candles" | "liquidations" | "funding" | "openInterest" | "markPrice" | "footprint";
109
109
  interface MmflowSocketOptions {
110
- /** Gateway URL. Default is the live Railway gateway. */
110
+ /** Gateway URL. Default is the branded production gateway. */
111
111
  url?: string;
112
112
  /** API key sent in the opening `auth` frame. */
113
113
  apiKey?: string;
package/dist/index.d.ts CHANGED
@@ -95,7 +95,7 @@ interface MmflowFeedOptions {
95
95
  transport?: "sse" | "ws";
96
96
  /** API key. Used in the WS auth frame, or as `api_key` for keyed SSE quotas. */
97
97
  apiKey?: string;
98
- /** WebSocket gateway URL. Default is the live Railway gateway. */
98
+ /** WebSocket gateway URL. Default is the branded production gateway. */
99
99
  wsUrl?: string;
100
100
  /** Default symbol, used when the chart doesn't supply one (e.g. a vanilla
101
101
  * createChart without setData symbol opts). */
@@ -107,7 +107,7 @@ declare function createMmflowFeed(opts?: MmflowFeedOptions): DataFeed;
107
107
 
108
108
  type MmflowChannel = "trades" | "orderbook" | "candles" | "liquidations" | "funding" | "openInterest" | "markPrice" | "footprint";
109
109
  interface MmflowSocketOptions {
110
- /** Gateway URL. Default is the live Railway gateway. */
110
+ /** Gateway URL. Default is the branded production gateway. */
111
111
  url?: string;
112
112
  /** API key sent in the opening `auth` frame. */
113
113
  apiKey?: string;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/socket.ts
2
- var DEFAULT_URL = "wss://mmflowai-production.up.railway.app/v1";
2
+ var DEFAULT_URL = "wss://ws.mmflow.ai/v1";
3
3
  var keyOf = (channel, symbol) => `${channel}:${symbol}`;
4
4
  var MmflowSocket = class {
5
5
  constructor(options = {}) {
@@ -145,7 +145,7 @@ var MmflowSocket = class {
145
145
 
146
146
  // src/feed.ts
147
147
  var DEFAULT_BASE = "https://mmflow.ai";
148
- var DEFAULT_WS = "wss://mmflowai-production.up.railway.app/v1";
148
+ var DEFAULT_WS = "wss://ws.mmflow.ai/v1";
149
149
  function createMmflowFeed(opts = {}) {
150
150
  const base = (opts.baseUrl ?? DEFAULT_BASE).replace(/\/$/, "");
151
151
  const transport = opts.transport ?? "sse";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/socket.ts","../src/feed.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// MmflowSocket — typed WebSocket client for the mmflow real-time data API.\n//\n// Protocol (JSON frames):\n// client → server : { op: \"auth\", apiKey }\n// { op: \"subscribe\", channel, symbol, id }\n// { op: \"unsubscribe\", channel, symbol, id }\n// server → client : { type: \"ack\", id, channel, symbol }\n// { type: \"data\", channel, symbol, seq, ts, payload }\n// { type: \"heartbeat\", ts }\n// { type: \"error\", code, message, id? }\n//\n// Resilience: exponential-backoff auto-reconnect, with re-auth + replay of all\n// active subscriptions on every (re)connection — the same discipline the app's\n// in-process HL client uses.\n\nimport type { Unsubscribe } from \"./types\";\n\nexport type MmflowChannel =\n | \"trades\"\n | \"orderbook\"\n | \"candles\"\n | \"liquidations\"\n | \"funding\"\n | \"openInterest\"\n | \"markPrice\"\n | \"footprint\";\n\nexport interface MmflowSocketOptions {\n /** Gateway URL. Default is the live Railway gateway. */\n url?: string;\n /** API key sent in the opening `auth` frame. */\n apiKey?: string;\n /** Reconnect automatically on drop. Default true. */\n autoReconnect?: boolean;\n /** Initial reconnect backoff (ms). Default 500. */\n reconnectInitialMs?: number;\n /** Max reconnect backoff (ms). Default 30000. */\n reconnectMaxMs?: number;\n /** Called on a server `error` frame. */\n onError?: (code: string, message: string) => void;\n}\n\nexport interface MmflowMessageMeta {\n channel: MmflowChannel;\n symbol: string;\n seq?: number;\n ts?: number;\n}\n\nexport type MmflowDataHandler = (\n payload: unknown,\n meta: MmflowMessageMeta,\n) => void;\n\ninterface IncomingMessage {\n type?: \"ack\" | \"data\" | \"heartbeat\" | \"pong\" | \"error\";\n op?: string;\n channel?: MmflowChannel;\n symbol?: string;\n seq?: number;\n ts?: number;\n payload?: unknown;\n code?: string;\n message?: string;\n}\n\ninterface Subscription {\n channel: MmflowChannel;\n symbol: string;\n handlers: Set<MmflowDataHandler>;\n}\n\nconst DEFAULT_URL = \"wss://mmflowai-production.up.railway.app/v1\";\nconst keyOf = (channel: string, symbol: string) => `${channel}:${symbol}`;\n\nexport class MmflowSocket {\n private readonly url: string;\n private readonly apiKey?: string;\n private readonly autoReconnect: boolean;\n private readonly reconnectInitialMs: number;\n private readonly reconnectMaxMs: number;\n private readonly onError?: (code: string, message: string) => void;\n\n private ws: WebSocket | null = null;\n private readonly subs = new Map<string, Subscription>();\n private backoff: number;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closedByUser = false;\n private authed = false;\n private nextId = 1;\n\n constructor(options: MmflowSocketOptions = {}) {\n this.url = options.url ?? DEFAULT_URL;\n this.apiKey = options.apiKey;\n this.autoReconnect = options.autoReconnect ?? true;\n this.reconnectInitialMs = options.reconnectInitialMs ?? 500;\n this.reconnectMaxMs = options.reconnectMaxMs ?? 30_000;\n this.onError = options.onError;\n this.backoff = this.reconnectInitialMs;\n }\n\n /** Open the socket. Idempotent; subscriptions made before connect() are\n * sent as soon as the connection is established. */\n connect(): void {\n this.closedByUser = false;\n this.open();\n }\n\n private open(): void {\n if (typeof WebSocket === \"undefined\") {\n throw new Error(\n \"MmflowSocket requires a global WebSocket (browser, or Node >= 21 / the `ws` package).\",\n );\n }\n if (\n this.ws &&\n (this.ws.readyState === WebSocket.OPEN ||\n this.ws.readyState === WebSocket.CONNECTING)\n ) {\n return;\n }\n\n const ws = new WebSocket(this.url);\n this.ws = ws;\n this.authed = false;\n\n ws.onopen = () => {\n this.backoff = this.reconnectInitialMs;\n if (this.apiKey) this.send({ op: \"auth\", apiKey: this.apiKey });\n else this.replaySubscriptions();\n };\n ws.onmessage = (ev: MessageEvent) => this.handleMessage(ev);\n ws.onclose = () => {\n this.ws = null;\n this.authed = false;\n if (!this.closedByUser && this.autoReconnect) this.scheduleReconnect();\n };\n ws.onerror = () => {\n // A close event follows; reconnection is handled there.\n };\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer != null) return;\n const delay = this.backoff;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.open();\n }, delay);\n this.backoff = Math.min(this.backoff * 2, this.reconnectMaxMs);\n }\n\n private handleMessage(ev: MessageEvent): void {\n if (typeof ev.data !== \"string\") return;\n let msg: IncomingMessage;\n try {\n msg = JSON.parse(ev.data) as IncomingMessage;\n } catch {\n return;\n }\n if (msg.type === \"ack\" && msg.op === \"auth\") {\n this.authed = true;\n this.replaySubscriptions();\n } else if (msg.type === \"data\" && msg.channel && msg.symbol) {\n const sub = this.subs.get(keyOf(msg.channel, msg.symbol));\n if (!sub) return;\n const meta: MmflowMessageMeta = {\n channel: msg.channel,\n symbol: msg.symbol,\n seq: msg.seq,\n ts: msg.ts,\n };\n sub.handlers.forEach((handler) => {\n try {\n handler(msg.payload, meta);\n } catch {\n // Isolate handler faults so one bad listener can't kill the socket.\n }\n });\n } else if (msg.type === \"error\") {\n this.onError?.(msg.code ?? \"error\", msg.message ?? \"\");\n }\n // \"ack\" / \"heartbeat\" / \"pong\" require no action.\n }\n\n private send(obj: unknown): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(obj));\n }\n }\n\n private sendSubscribe(sub: Subscription): void {\n if (this.apiKey && !this.authed) return;\n this.send({\n op: \"subscribe\",\n channel: sub.channel,\n symbol: sub.symbol,\n id: this.nextId++,\n });\n }\n\n private replaySubscriptions(): void {\n this.subs.forEach((sub) => this.sendSubscribe(sub));\n }\n\n /**\n * Subscribe to `channel` for `symbol`. Returns an unsubscribe function.\n * Safe to call before connect() — it is (re)sent on each connection.\n * Multiple handlers for the same (channel, symbol) share one subscription.\n */\n subscribe(\n channel: MmflowChannel,\n symbol: string,\n handler: MmflowDataHandler,\n ): Unsubscribe {\n const key = keyOf(channel, symbol);\n let sub = this.subs.get(key);\n if (!sub) {\n sub = { channel, symbol, handlers: new Set() };\n this.subs.set(key, sub);\n this.sendSubscribe(sub);\n }\n sub.handlers.add(handler);\n\n return () => {\n const existing = this.subs.get(key);\n if (!existing) return;\n existing.handlers.delete(handler);\n if (existing.handlers.size === 0) {\n this.subs.delete(key);\n this.send({ op: \"unsubscribe\", channel, symbol, id: this.nextId++ });\n }\n };\n }\n\n /** Close permanently (disables auto-reconnect) and drop all subscriptions. */\n close(): void {\n this.closedByUser = true;\n if (this.reconnectTimer != null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.subs.clear();\n this.authed = false;\n this.ws?.close();\n this.ws = null;\n }\n}\n","// createMmflowFeed — a ready-made DataFeed backed by mmflow's public API.\n// History comes from the REST candles endpoint. Live trades default to SSE\n// for backwards compatibility, or can use the keyed WebSocket gateway with\n// `transport: \"ws\"`.\n//\n// import { createChart } from \"@mmflow/charts\";\n// import { createMmflowFeed } from \"@mmflow/sdk\";\n// const chart = createChart({ container });\n// chart.addCandleSeries();\n// chart.setData(createMmflowFeed()); // symbol/resolution via the binding\n\nimport { MmflowSocket } from \"./socket\";\nimport type {\n Candle,\n DataFeed,\n FeedUpdate,\n FootprintBar,\n MarkerSpec,\n OrderBookSnapshot,\n Unsubscribe,\n VolumeProfileSnapshot,\n} from \"./types\";\n\nexport interface MmflowFeedOptions {\n /** API origin. Default \"https://mmflow.ai\". */\n baseUrl?: string;\n /** Live transport. Default \"sse\" for backwards compatibility. */\n transport?: \"sse\" | \"ws\";\n /** API key. Used in the WS auth frame, or as `api_key` for keyed SSE quotas. */\n apiKey?: string;\n /** WebSocket gateway URL. Default is the live Railway gateway. */\n wsUrl?: string;\n /** Default symbol, used when the chart doesn't supply one (e.g. a vanilla\n * createChart without setData symbol opts). */\n symbol?: string;\n /** Minimum trade notional (USD) to stream. Default 0 (all prints). */\n minUsd?: number;\n}\n\nconst DEFAULT_BASE = \"https://mmflow.ai\";\nconst DEFAULT_WS = \"wss://mmflowai-production.up.railway.app/v1\";\n\n// Hyperliquid candle row as returned by /api/hl/candles (OHLCV serialized as\n// strings). `t` is the bar open time in epoch ms.\ninterface HlCandleRow {\n t: number;\n o: string;\n h: string;\n l: string;\n c: string;\n v: string;\n}\n\n// Normalized trade tick emitted by /api/v1/streams/trades (event: \"trade\").\ninterface TradeTick {\n coin: string;\n side: \"buy\" | \"sell\";\n price: number;\n size: number;\n ts: number;\n}\n\nexport function createMmflowFeed(opts: MmflowFeedOptions = {}): DataFeed {\n const base = (opts.baseUrl ?? DEFAULT_BASE).replace(/\\/$/, \"\");\n const transport = opts.transport ?? \"sse\";\n let socket: MmflowSocket | null = null;\n let socketRefs = 0;\n\n const ensureSocket = (): MmflowSocket => {\n if (transport !== \"ws\") {\n throw new Error(\"createMmflowFeed: this method requires transport=\\\"ws\\\"\");\n }\n if (!opts.apiKey) {\n throw new Error(\"createMmflowFeed: transport=\\\"ws\\\" requires apiKey\");\n }\n if (!socket) {\n socket = new MmflowSocket({\n apiKey: opts.apiKey,\n url: opts.wsUrl ?? DEFAULT_WS,\n });\n socket.connect();\n }\n return socket;\n };\n\n const attachSocket = (\n channel: Parameters<MmflowSocket[\"subscribe\"]>[0],\n symbol: string,\n handler: Parameters<MmflowSocket[\"subscribe\"]>[2],\n ): Unsubscribe => {\n const sock = ensureSocket();\n socketRefs++;\n const unsub = sock.subscribe(channel, symbol, handler);\n return () => {\n unsub();\n socketRefs = Math.max(0, socketRefs - 1);\n if (socketRefs === 0) {\n socket?.close();\n socket = null;\n }\n };\n };\n\n const feed: DataFeed = {\n async fetchCandles({ symbol, resolution, from, to }) {\n const hours = Math.min(720, Math.max(1, Math.ceil((to - from) / 3_600_000)));\n const url = new URL(`${base}/api/hl/candles`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"interval\", resolution);\n url.searchParams.set(\"hours\", String(hours));\n\n const res = await fetch(url.toString());\n if (!res.ok) {\n throw new Error(`mmflow: candles request failed (${res.status})`);\n }\n const json = (await res.json()) as { candles?: HlCandleRow[] };\n const rows = json.candles ?? [];\n\n const out: Candle[] = [];\n for (const r of rows) {\n const time = Number(r.t);\n if (!Number.isFinite(time)) continue;\n out.push({\n time,\n open: Number(r.o),\n high: Number(r.h),\n low: Number(r.l),\n close: Number(r.c),\n volume: Number(r.v),\n });\n }\n return out;\n },\n\n subscribe(symbol, _resolution, onUpdate) {\n const feedSymbol = symbol || opts.symbol || \"\";\n if (transport === \"ws\") {\n return attachSocket(\"trades\", feedSymbol, (payload) => {\n const t = payload as Partial<TradeTick> & {\n ts?: number;\n time?: number;\n symbol?: string;\n };\n const price = Number(t.price);\n const size = Number(t.size);\n const time = Number(t.ts ?? t.time);\n if (!Number.isFinite(price) || !Number.isFinite(size) || !Number.isFinite(time)) {\n return;\n }\n onUpdate({\n symbol: t.coin ?? t.symbol ?? feedSymbol,\n price,\n size,\n time,\n side: t.side,\n } satisfies FeedUpdate);\n });\n }\n if (typeof EventSource === \"undefined\") {\n throw new Error(\n \"createMmflowFeed.subscribe needs a global EventSource (browser). \" +\n \"In Node, install an EventSource polyfill or use MmflowSocket instead.\",\n );\n }\n const url = new URL(`${base}/api/v1/streams/trades`);\n url.searchParams.set(\"coin\", feedSymbol);\n if (opts.minUsd != null) url.searchParams.set(\"minUsd\", String(opts.minUsd));\n if (opts.apiKey) url.searchParams.set(\"api_key\", opts.apiKey);\n\n const es = new EventSource(url.toString());\n const onTrade = (e: MessageEvent) => {\n try {\n const t = JSON.parse(e.data as string) as TradeTick;\n onUpdate({\n symbol: t.coin ?? symbol,\n price: t.price,\n size: t.size,\n time: t.ts,\n side: t.side,\n } satisfies FeedUpdate);\n } catch {\n // Ignore malformed frames; EventSource keeps the stream alive.\n }\n };\n es.addEventListener(\"trade\", onTrade as EventListener);\n return () => {\n es.removeEventListener(\"trade\", onTrade as EventListener);\n es.close();\n };\n },\n };\n\n feed.fetchFootprint = async (symbol, fpOpts): Promise<FootprintBar[]> => {\n const url = new URL(`${base}/api/v1/perps/footprint`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"kind\", \"time\");\n url.searchParams.set(\"interval\", String(fpOpts.intervalMs));\n url.searchParams.set(\"bars\", \"500\");\n const res = await fetch(url.toString());\n if (!res.ok) throw new Error(`mmflow: footprint request failed (${res.status})`);\n const json = (await res.json()) as { data?: Array<FootprintBar & { time?: number }> };\n return (json.data ?? []).map((bar) => ({\n t: Number((bar as { t?: number }).t ?? bar.time),\n open: Number(bar.open),\n high: Number(bar.high),\n low: Number(bar.low),\n close: Number(bar.close),\n levels: (bar.levels ?? []).map((level) => ({\n price: Number(level.price),\n buyVol: Number(level.buyVol),\n sellVol: Number(level.sellVol),\n })),\n }));\n };\n\n feed.fetchVolumeProfile = async (symbol): Promise<VolumeProfileSnapshot> => {\n const url = new URL(`${base}/api/hl/marketprofile`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"hours\", \"24\");\n url.searchParams.set(\"bins\", \"80\");\n const res = await fetch(url.toString());\n if (!res.ok) throw new Error(`mmflow: volume profile request failed (${res.status})`);\n const json = (await res.json()) as {\n bins?: Array<{ px: number; totalUsd: number }>;\n range?: { binWidth?: number };\n val?: number;\n vah?: number;\n };\n return {\n bins: (json.bins ?? []).map((bin) => ({\n px: Number(bin.px),\n totalUsd: Number(bin.totalUsd),\n })),\n binWidth: Number(json.range?.binWidth ?? 0),\n val: Number(json.val ?? 0),\n vah: Number(json.vah ?? 0),\n };\n };\n\n if (transport === \"ws\") {\n feed.subscribeOrderBook = (symbol, onBook) =>\n attachSocket(\"orderbook\", symbol || opts.symbol || \"\", (payload) => {\n const book = payload as {\n ts?: number;\n bids?: Array<{ price?: number; size?: number; px?: number; sz?: number }>;\n asks?: Array<{ price?: number; size?: number; px?: number; sz?: number }>;\n };\n const map = (rows: NonNullable<typeof book.bids>) =>\n rows.map((level) => ({\n px: Number(level.px ?? level.price),\n sz: Number(level.sz ?? level.size),\n }));\n onBook({\n time: Number(book.ts ?? Date.now()),\n bids: map(book.bids ?? []),\n asks: map(book.asks ?? []),\n } satisfies OrderBookSnapshot);\n });\n\n feed.subscribeMarkers = (symbol, onMarkers) =>\n attachSocket(\"liquidations\", symbol || opts.symbol || \"\", (payload) => {\n const e = payload as {\n ts?: number;\n price?: number;\n notionalUsd?: number;\n side?: string;\n };\n const marker: MarkerSpec = {\n t: Number(e.ts ?? Date.now()),\n price: Number(e.price),\n sizeUsd: Number(e.notionalUsd ?? 0),\n };\n if (!Number.isFinite(marker.price) || marker.sizeUsd <= 0) return;\n if (e.side === \"long\") onMarkers({ buys: [marker], sells: [] });\n else onMarkers({ buys: [], sells: [marker] });\n });\n }\n\n return feed;\n}\n"]}
1
+ {"version":3,"sources":["../src/socket.ts","../src/feed.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// MmflowSocket — typed WebSocket client for the mmflow real-time data API.\n//\n// Protocol (JSON frames):\n// client → server : { op: \"auth\", apiKey }\n// { op: \"subscribe\", channel, symbol, id }\n// { op: \"unsubscribe\", channel, symbol, id }\n// server → client : { type: \"ack\", id, channel, symbol }\n// { type: \"data\", channel, symbol, seq, ts, payload }\n// { type: \"heartbeat\", ts }\n// { type: \"error\", code, message, id? }\n//\n// Resilience: exponential-backoff auto-reconnect, with re-auth + replay of all\n// active subscriptions on every (re)connection — the same discipline the app's\n// in-process HL client uses.\n\nimport type { Unsubscribe } from \"./types\";\n\nexport type MmflowChannel =\n | \"trades\"\n | \"orderbook\"\n | \"candles\"\n | \"liquidations\"\n | \"funding\"\n | \"openInterest\"\n | \"markPrice\"\n | \"footprint\";\n\nexport interface MmflowSocketOptions {\n /** Gateway URL. Default is the branded production gateway. */\n url?: string;\n /** API key sent in the opening `auth` frame. */\n apiKey?: string;\n /** Reconnect automatically on drop. Default true. */\n autoReconnect?: boolean;\n /** Initial reconnect backoff (ms). Default 500. */\n reconnectInitialMs?: number;\n /** Max reconnect backoff (ms). Default 30000. */\n reconnectMaxMs?: number;\n /** Called on a server `error` frame. */\n onError?: (code: string, message: string) => void;\n}\n\nexport interface MmflowMessageMeta {\n channel: MmflowChannel;\n symbol: string;\n seq?: number;\n ts?: number;\n}\n\nexport type MmflowDataHandler = (\n payload: unknown,\n meta: MmflowMessageMeta,\n) => void;\n\ninterface IncomingMessage {\n type?: \"ack\" | \"data\" | \"heartbeat\" | \"pong\" | \"error\";\n op?: string;\n channel?: MmflowChannel;\n symbol?: string;\n seq?: number;\n ts?: number;\n payload?: unknown;\n code?: string;\n message?: string;\n}\n\ninterface Subscription {\n channel: MmflowChannel;\n symbol: string;\n handlers: Set<MmflowDataHandler>;\n}\n\nconst DEFAULT_URL = \"wss://ws.mmflow.ai/v1\";\nconst keyOf = (channel: string, symbol: string) => `${channel}:${symbol}`;\n\nexport class MmflowSocket {\n private readonly url: string;\n private readonly apiKey?: string;\n private readonly autoReconnect: boolean;\n private readonly reconnectInitialMs: number;\n private readonly reconnectMaxMs: number;\n private readonly onError?: (code: string, message: string) => void;\n\n private ws: WebSocket | null = null;\n private readonly subs = new Map<string, Subscription>();\n private backoff: number;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closedByUser = false;\n private authed = false;\n private nextId = 1;\n\n constructor(options: MmflowSocketOptions = {}) {\n this.url = options.url ?? DEFAULT_URL;\n this.apiKey = options.apiKey;\n this.autoReconnect = options.autoReconnect ?? true;\n this.reconnectInitialMs = options.reconnectInitialMs ?? 500;\n this.reconnectMaxMs = options.reconnectMaxMs ?? 30_000;\n this.onError = options.onError;\n this.backoff = this.reconnectInitialMs;\n }\n\n /** Open the socket. Idempotent; subscriptions made before connect() are\n * sent as soon as the connection is established. */\n connect(): void {\n this.closedByUser = false;\n this.open();\n }\n\n private open(): void {\n if (typeof WebSocket === \"undefined\") {\n throw new Error(\n \"MmflowSocket requires a global WebSocket (browser, or Node >= 21 / the `ws` package).\",\n );\n }\n if (\n this.ws &&\n (this.ws.readyState === WebSocket.OPEN ||\n this.ws.readyState === WebSocket.CONNECTING)\n ) {\n return;\n }\n\n const ws = new WebSocket(this.url);\n this.ws = ws;\n this.authed = false;\n\n ws.onopen = () => {\n this.backoff = this.reconnectInitialMs;\n if (this.apiKey) this.send({ op: \"auth\", apiKey: this.apiKey });\n else this.replaySubscriptions();\n };\n ws.onmessage = (ev: MessageEvent) => this.handleMessage(ev);\n ws.onclose = () => {\n this.ws = null;\n this.authed = false;\n if (!this.closedByUser && this.autoReconnect) this.scheduleReconnect();\n };\n ws.onerror = () => {\n // A close event follows; reconnection is handled there.\n };\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer != null) return;\n const delay = this.backoff;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.open();\n }, delay);\n this.backoff = Math.min(this.backoff * 2, this.reconnectMaxMs);\n }\n\n private handleMessage(ev: MessageEvent): void {\n if (typeof ev.data !== \"string\") return;\n let msg: IncomingMessage;\n try {\n msg = JSON.parse(ev.data) as IncomingMessage;\n } catch {\n return;\n }\n if (msg.type === \"ack\" && msg.op === \"auth\") {\n this.authed = true;\n this.replaySubscriptions();\n } else if (msg.type === \"data\" && msg.channel && msg.symbol) {\n const sub = this.subs.get(keyOf(msg.channel, msg.symbol));\n if (!sub) return;\n const meta: MmflowMessageMeta = {\n channel: msg.channel,\n symbol: msg.symbol,\n seq: msg.seq,\n ts: msg.ts,\n };\n sub.handlers.forEach((handler) => {\n try {\n handler(msg.payload, meta);\n } catch {\n // Isolate handler faults so one bad listener can't kill the socket.\n }\n });\n } else if (msg.type === \"error\") {\n this.onError?.(msg.code ?? \"error\", msg.message ?? \"\");\n }\n // \"ack\" / \"heartbeat\" / \"pong\" require no action.\n }\n\n private send(obj: unknown): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(obj));\n }\n }\n\n private sendSubscribe(sub: Subscription): void {\n if (this.apiKey && !this.authed) return;\n this.send({\n op: \"subscribe\",\n channel: sub.channel,\n symbol: sub.symbol,\n id: this.nextId++,\n });\n }\n\n private replaySubscriptions(): void {\n this.subs.forEach((sub) => this.sendSubscribe(sub));\n }\n\n /**\n * Subscribe to `channel` for `symbol`. Returns an unsubscribe function.\n * Safe to call before connect() — it is (re)sent on each connection.\n * Multiple handlers for the same (channel, symbol) share one subscription.\n */\n subscribe(\n channel: MmflowChannel,\n symbol: string,\n handler: MmflowDataHandler,\n ): Unsubscribe {\n const key = keyOf(channel, symbol);\n let sub = this.subs.get(key);\n if (!sub) {\n sub = { channel, symbol, handlers: new Set() };\n this.subs.set(key, sub);\n this.sendSubscribe(sub);\n }\n sub.handlers.add(handler);\n\n return () => {\n const existing = this.subs.get(key);\n if (!existing) return;\n existing.handlers.delete(handler);\n if (existing.handlers.size === 0) {\n this.subs.delete(key);\n this.send({ op: \"unsubscribe\", channel, symbol, id: this.nextId++ });\n }\n };\n }\n\n /** Close permanently (disables auto-reconnect) and drop all subscriptions. */\n close(): void {\n this.closedByUser = true;\n if (this.reconnectTimer != null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.subs.clear();\n this.authed = false;\n this.ws?.close();\n this.ws = null;\n }\n}\n","// createMmflowFeed — a ready-made DataFeed backed by mmflow's public API.\n// History comes from the REST candles endpoint. Live trades default to SSE\n// for backwards compatibility, or can use the keyed WebSocket gateway with\n// `transport: \"ws\"`.\n//\n// import { createChart } from \"@mmflow/charts\";\n// import { createMmflowFeed } from \"@mmflow/sdk\";\n// const chart = createChart({ container });\n// chart.addCandleSeries();\n// chart.setData(createMmflowFeed()); // symbol/resolution via the binding\n\nimport { MmflowSocket } from \"./socket\";\nimport type {\n Candle,\n DataFeed,\n FeedUpdate,\n FootprintBar,\n MarkerSpec,\n OrderBookSnapshot,\n Unsubscribe,\n VolumeProfileSnapshot,\n} from \"./types\";\n\nexport interface MmflowFeedOptions {\n /** API origin. Default \"https://mmflow.ai\". */\n baseUrl?: string;\n /** Live transport. Default \"sse\" for backwards compatibility. */\n transport?: \"sse\" | \"ws\";\n /** API key. Used in the WS auth frame, or as `api_key` for keyed SSE quotas. */\n apiKey?: string;\n /** WebSocket gateway URL. Default is the branded production gateway. */\n wsUrl?: string;\n /** Default symbol, used when the chart doesn't supply one (e.g. a vanilla\n * createChart without setData symbol opts). */\n symbol?: string;\n /** Minimum trade notional (USD) to stream. Default 0 (all prints). */\n minUsd?: number;\n}\n\nconst DEFAULT_BASE = \"https://mmflow.ai\";\nconst DEFAULT_WS = \"wss://ws.mmflow.ai/v1\";\n\n// Hyperliquid candle row as returned by /api/hl/candles (OHLCV serialized as\n// strings). `t` is the bar open time in epoch ms.\ninterface HlCandleRow {\n t: number;\n o: string;\n h: string;\n l: string;\n c: string;\n v: string;\n}\n\n// Normalized trade tick emitted by /api/v1/streams/trades (event: \"trade\").\ninterface TradeTick {\n coin: string;\n side: \"buy\" | \"sell\";\n price: number;\n size: number;\n ts: number;\n}\n\nexport function createMmflowFeed(opts: MmflowFeedOptions = {}): DataFeed {\n const base = (opts.baseUrl ?? DEFAULT_BASE).replace(/\\/$/, \"\");\n const transport = opts.transport ?? \"sse\";\n let socket: MmflowSocket | null = null;\n let socketRefs = 0;\n\n const ensureSocket = (): MmflowSocket => {\n if (transport !== \"ws\") {\n throw new Error(\"createMmflowFeed: this method requires transport=\\\"ws\\\"\");\n }\n if (!opts.apiKey) {\n throw new Error(\"createMmflowFeed: transport=\\\"ws\\\" requires apiKey\");\n }\n if (!socket) {\n socket = new MmflowSocket({\n apiKey: opts.apiKey,\n url: opts.wsUrl ?? DEFAULT_WS,\n });\n socket.connect();\n }\n return socket;\n };\n\n const attachSocket = (\n channel: Parameters<MmflowSocket[\"subscribe\"]>[0],\n symbol: string,\n handler: Parameters<MmflowSocket[\"subscribe\"]>[2],\n ): Unsubscribe => {\n const sock = ensureSocket();\n socketRefs++;\n const unsub = sock.subscribe(channel, symbol, handler);\n return () => {\n unsub();\n socketRefs = Math.max(0, socketRefs - 1);\n if (socketRefs === 0) {\n socket?.close();\n socket = null;\n }\n };\n };\n\n const feed: DataFeed = {\n async fetchCandles({ symbol, resolution, from, to }) {\n const hours = Math.min(720, Math.max(1, Math.ceil((to - from) / 3_600_000)));\n const url = new URL(`${base}/api/hl/candles`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"interval\", resolution);\n url.searchParams.set(\"hours\", String(hours));\n\n const res = await fetch(url.toString());\n if (!res.ok) {\n throw new Error(`mmflow: candles request failed (${res.status})`);\n }\n const json = (await res.json()) as { candles?: HlCandleRow[] };\n const rows = json.candles ?? [];\n\n const out: Candle[] = [];\n for (const r of rows) {\n const time = Number(r.t);\n if (!Number.isFinite(time)) continue;\n out.push({\n time,\n open: Number(r.o),\n high: Number(r.h),\n low: Number(r.l),\n close: Number(r.c),\n volume: Number(r.v),\n });\n }\n return out;\n },\n\n subscribe(symbol, _resolution, onUpdate) {\n const feedSymbol = symbol || opts.symbol || \"\";\n if (transport === \"ws\") {\n return attachSocket(\"trades\", feedSymbol, (payload) => {\n const t = payload as Partial<TradeTick> & {\n ts?: number;\n time?: number;\n symbol?: string;\n };\n const price = Number(t.price);\n const size = Number(t.size);\n const time = Number(t.ts ?? t.time);\n if (!Number.isFinite(price) || !Number.isFinite(size) || !Number.isFinite(time)) {\n return;\n }\n onUpdate({\n symbol: t.coin ?? t.symbol ?? feedSymbol,\n price,\n size,\n time,\n side: t.side,\n } satisfies FeedUpdate);\n });\n }\n if (typeof EventSource === \"undefined\") {\n throw new Error(\n \"createMmflowFeed.subscribe needs a global EventSource (browser). \" +\n \"In Node, install an EventSource polyfill or use MmflowSocket instead.\",\n );\n }\n const url = new URL(`${base}/api/v1/streams/trades`);\n url.searchParams.set(\"coin\", feedSymbol);\n if (opts.minUsd != null) url.searchParams.set(\"minUsd\", String(opts.minUsd));\n if (opts.apiKey) url.searchParams.set(\"api_key\", opts.apiKey);\n\n const es = new EventSource(url.toString());\n const onTrade = (e: MessageEvent) => {\n try {\n const t = JSON.parse(e.data as string) as TradeTick;\n onUpdate({\n symbol: t.coin ?? symbol,\n price: t.price,\n size: t.size,\n time: t.ts,\n side: t.side,\n } satisfies FeedUpdate);\n } catch {\n // Ignore malformed frames; EventSource keeps the stream alive.\n }\n };\n es.addEventListener(\"trade\", onTrade as EventListener);\n return () => {\n es.removeEventListener(\"trade\", onTrade as EventListener);\n es.close();\n };\n },\n };\n\n feed.fetchFootprint = async (symbol, fpOpts): Promise<FootprintBar[]> => {\n const url = new URL(`${base}/api/v1/perps/footprint`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"kind\", \"time\");\n url.searchParams.set(\"interval\", String(fpOpts.intervalMs));\n url.searchParams.set(\"bars\", \"500\");\n const res = await fetch(url.toString());\n if (!res.ok) throw new Error(`mmflow: footprint request failed (${res.status})`);\n const json = (await res.json()) as { data?: Array<FootprintBar & { time?: number }> };\n return (json.data ?? []).map((bar) => ({\n t: Number((bar as { t?: number }).t ?? bar.time),\n open: Number(bar.open),\n high: Number(bar.high),\n low: Number(bar.low),\n close: Number(bar.close),\n levels: (bar.levels ?? []).map((level) => ({\n price: Number(level.price),\n buyVol: Number(level.buyVol),\n sellVol: Number(level.sellVol),\n })),\n }));\n };\n\n feed.fetchVolumeProfile = async (symbol): Promise<VolumeProfileSnapshot> => {\n const url = new URL(`${base}/api/hl/marketprofile`);\n url.searchParams.set(\"coin\", symbol || opts.symbol || \"\");\n url.searchParams.set(\"hours\", \"24\");\n url.searchParams.set(\"bins\", \"80\");\n const res = await fetch(url.toString());\n if (!res.ok) throw new Error(`mmflow: volume profile request failed (${res.status})`);\n const json = (await res.json()) as {\n bins?: Array<{ px: number; totalUsd: number }>;\n range?: { binWidth?: number };\n val?: number;\n vah?: number;\n };\n return {\n bins: (json.bins ?? []).map((bin) => ({\n px: Number(bin.px),\n totalUsd: Number(bin.totalUsd),\n })),\n binWidth: Number(json.range?.binWidth ?? 0),\n val: Number(json.val ?? 0),\n vah: Number(json.vah ?? 0),\n };\n };\n\n if (transport === \"ws\") {\n feed.subscribeOrderBook = (symbol, onBook) =>\n attachSocket(\"orderbook\", symbol || opts.symbol || \"\", (payload) => {\n const book = payload as {\n ts?: number;\n bids?: Array<{ price?: number; size?: number; px?: number; sz?: number }>;\n asks?: Array<{ price?: number; size?: number; px?: number; sz?: number }>;\n };\n const map = (rows: NonNullable<typeof book.bids>) =>\n rows.map((level) => ({\n px: Number(level.px ?? level.price),\n sz: Number(level.sz ?? level.size),\n }));\n onBook({\n time: Number(book.ts ?? Date.now()),\n bids: map(book.bids ?? []),\n asks: map(book.asks ?? []),\n } satisfies OrderBookSnapshot);\n });\n\n feed.subscribeMarkers = (symbol, onMarkers) =>\n attachSocket(\"liquidations\", symbol || opts.symbol || \"\", (payload) => {\n const e = payload as {\n ts?: number;\n price?: number;\n notionalUsd?: number;\n side?: string;\n };\n const marker: MarkerSpec = {\n t: Number(e.ts ?? Date.now()),\n price: Number(e.price),\n sizeUsd: Number(e.notionalUsd ?? 0),\n };\n if (!Number.isFinite(marker.price) || marker.sizeUsd <= 0) return;\n if (e.side === \"long\") onMarkers({ buys: [marker], sells: [] });\n else onMarkers({ buys: [], sells: [marker] });\n });\n }\n\n return feed;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmflow/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "mmflow data SDK — a typed WebSocket client and a ready-made createMmflowFeed() that plugs live mmflow market data straight into @mmflow/charts.",
5
5
  "license": "MIT",
6
6
  "type": "module",