JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 32
  • Score
    100M100P100Q79083F
  • License MIT

TypeScript SDK for Hyperliquid market data — fills, trades, liquidations, order books, HIP-3 + HIP-4 — REST + WebSocket

Package Exports

  • @ironflowsh/sdk

Readme

@ironflowsh/sdk

REST + WebSocket SDK for Ironflow — every Hyperliquid trade, fill, order, liquidation, and book update, plus HIP-3 builder markets, HIP-4 prediction outcomes, and full wallet analytics (open positions, funding payments, maker/taker split, full ledger). Historical fills back to 2025-07-27, sub-second streaming from venue.

Get a free API key in 30 seconds — email-only, no credit card. Free tier: 24h history, 10 req/min, 1 WebSocket connection, 10 tracked addresses. Paid tiers add more WS connections, 90-day to unlimited history, and webhook triggers.

Install

npm install @ironflowsh/sdk

Node.js 18+ (uses native fetch and WebSocket). Zero runtime dependencies, full TypeScript types.

Quick Start

import { Ironflow } from "@ironflowsh/sdk";

const client = new Ironflow("if_your_api_key");

// Stream live trades (paid tiers)
for await (const trade of client.stream.trades("BTC-PERP")) {
  console.log(trade.price, trade.size, trade.side);
}

// Or fetch history with auto-pagination
const page = await client.trades("BTC-PERP", { limit: 100 });
for (const trade of page.data) console.log(trade);

Recipes

Copy-trade a wallet

Mirror every fill from a leader address as it lands.

for await (const fill of client.stream.fills("0xleader_address")) {
  console.log(`${fill.side} ${fill.size} ${fill.market} @ ${fill.price}`);
  // submit identical order to your venue
}

Alert on Hyperliquid liquidations

Pipe every liquidation above a size threshold to Slack.

for await (const liq of client.stream.liquidations("BTC-PERP")) {
  if (Number(liq.size) >= 10) {
    await fetch(SLACK_WEBHOOK, {
      method: "POST",
      body: JSON.stringify({ text: `${liq.size} BTC liq @ ${liq.price}` }),
    });
  }
}

Scan funding rates across every perp market

Find rate divergences across native and HIP-3 builder markets in one pass.

const markets = await client.markets({ market_class: "perp" });
for (const m of markets) {
  const page = await client.funding(m.display_symbol, { limit: 1 });
  const [latest] = page.data;
  if (latest && Math.abs(Number(latest.rate)) > 0.0005) {
    console.log(`${m.display_symbol}: ${latest.rate}`);
  }
}

Reconstruct any HL wallet

Four endpoints over the same 365-day history reverse-engineer a wallet end-to-end — open positions and margin, funding payments, maker/taker split, and a unified ledger across deposits/withdrawals/funding/transfers. Backed by a bloom-filter index on fills.address — wallet-scope queries return in milliseconds.

const addr = "0xabc...";

// Live snapshot (HL clearinghouseState shape)
const state = await client.userState(addr);
console.log(state.margin_summary.account_value, state.positions.length);

// Funding payments — UI-aligned (positive = paid, negative = received)
const funding = await client.userFunding(addr, { from: Date.now() - 14 * 86400_000 });
const total = funding.reduce((s, p) => s + Number(p.usdc), 0);

// Maker/taker split, per market + a TOTAL row
const mt = await client.userMakerTaker(addr, { from: Date.now() - 14 * 86400_000 });
const total_row = mt.breakdown.find((r) => r.market === "TOTAL");
console.log(total_row?.maker_pct, total_row?.taker_pct);

// Unified ledger: deposits, withdrawals, funding payments, transfers
const ledger = await client.userLedger(addr, { limit: 200 });

Discover HIP-4 prediction markets

HIP-4 binary outcome contracts went live on Hyperliquid mainnet on 2026-05-02. Complementary outcomes have prices summing to 1.0.

const predictions = await client.markets({ market_class: "prediction" });
// predictions[0].display_symbol -> e.g. "BTC-78213-20260503-Yes"
for (const m of predictions) {
  const page = await client.trades(m.display_symbol, { limit: 1 });
  console.log(m.display_symbol, page.data[0]?.price);
}

Configuration

const client = new Ironflow("if_your_api_key", {
  baseUrl: "https://api.ironflow.sh",  // default
  source: "hyperliquid",               // default
  timeout: 30_000,                     // request timeout in ms (default: 30s)
});

REST Endpoints

Market Data

// Trades
const trades = await client.trades("BTC-PERP", { limit: 100 });

// Fills (requires address)
const fills = await client.fills({ address: "0xabc...", market: "ETH-PERP" });

// Order book snapshot
const book = await client.book("BTC-PERP");
// book.bids[0].price, book.bids[0].size

// OHLCV candles
const candles = await client.candles("BTC-PERP", "1h", { limit: 24 });

// Liquidations
const liqs = await client.liquidations("BTC-PERP");

// Funding rates
const rates = await client.funding("BTC-PERP");

// Open interest
const oi = await client.openInterest("BTC-PERP");

// Mark prices
const prices = await client.markPrices("BTC-PERP");

// Deposits & withdrawals
const deps = await client.deposits({ address: "0xabc..." });
const wds = await client.withdrawals({ address: "0xabc..." });

// Order statuses
const orders = await client.orderStatuses({ address: "0xabc..." });

// Vault operations
const vaults = await client.vaultOperations({ vault: "HLP" });

Wallet Analytics

Reverse-engineer any Hyperliquid wallet end-to-end. Available on every paid tier; respects per-tier history windows.

const addr = "0xabc...";

// Open positions + margin summary (HL clearinghouseState shape)
const state = await client.userState(addr);

// Funding payments — paid (positive) and received (negative)
const funding = await client.userFunding(addr, { from, to });

// Maker vs taker breakdown per market + a synthetic TOTAL row
const mt = await client.userMakerTaker(addr, { from, to });
// mt.breakdown[i].market, .maker_volume, .taker_volume, .maker_pct, .taker_pct

// Unified ledger: deposits / withdrawals / funding / transfers
const ledger = await client.userLedger(addr, { limit: 200, cursor });

Analytics (Builder+)

const flows = await client.netFlows({ interval: "1d", limit: 7 });
// flows[0].deposits, flows[0].withdrawals, flows[0].net_flow

const levels = await client.liquidationLevels("BTC-PERP", { bucket_size: 100 });
// levels[0].price_bucket, levels[0].count, levels[0].total_size

const orderFlow = await client.orderFlow();
// orderFlow[0].total_orders, orderFlow[0].filled_orders, orderFlow[0].fill_rate

const leaderboard = await client.vaultLeaderboard();
// leaderboard[0].vault, leaderboard[0].total_deposits, leaderboard[0].net_flow

const funding = await client.fundingStats("BTC-PERP", { interval: "8h" });
// funding[0].avg_rate, funding[0].min_rate, funding[0].max_rate

Triggers

// Create a webhook trigger
const trigger = await client.createTrigger({
  name: "whale-alert",
  channel: "trades",
  webhook_url: "https://your-server.com/hook",
  rule: {
    condition: { field: "data.size", op: "gt", value: "100" },
  },
});

// List, toggle, delete
const triggers = await client.listTriggers();
await client.toggleTrigger(trigger.id, false);
await client.deleteTrigger(trigger.id);

// Test a rule without creating
const result = await client.testTrigger({
  rule: { condition: { field: "data.size", op: "gt", value: "10" } },
  event: { data: { size: "50", market: "BTC-PERP" } },
});
console.log(result.matched); // true

Markets

// All currently-active markets (perp + spot, every issuer)
const all = await client.markets();

// Filter by class and issuer
const perps  = await client.markets({ market_class: "perp" });
const native = await client.markets({ issuer: "" });           // native non-builder only
const flxOnly = await client.markets({ issuer: "flx" });       // HIP-3 builder
const predictions = await client.markets({ market_class: "prediction" }); // HIP-4

// Each row carries the v3 identity tuple so it joins with /v1/* responses:
//   { market_id, source, market_class, issuer,
//     base_asset, quote_asset, base_market, display_symbol,
//     hl_coin, active_from_ms }
//
// `base_market` is the display symbol with any HIP-3 issuer prefix stripped:
//   "flx:GAS-PERP" -> "GAS-PERP" (pair with `issuer` to query across builders).

This endpoint reads the markets registry directly — no per-tier query window applies.

Cohorts (Enterprise)

const cohorts = await client.listCohorts();
const addrs = await client.cohortAddresses("top_pnl_30d");
await client.createCohort({ name: "my_whales", addresses: ["0xabc..."] });
await client.deleteCohort("my_whales");

Export (Builder+)

const data = await client.exportData({
  event_type: "fills",
  market: "BTC-PERP",
  format: "csv",
});
// data is Uint8Array — write to file or parse

Status

// Overall system status + per-venue freshness
const status = await client.status();
console.log(status.status); // "operational"
console.log(status.venues.hyperliquid.streams.fills.age_seconds);

// Rolling-window performance metrics (5-min API + pipeline + synthetic)
const metrics = await client.statusMetrics();
console.log(metrics.api.latency_p99_ms, metrics.pipeline.events_per_sec);

// Uptime / freshness timeline — "24h" (default) or "7d"
const history = await client.statusHistory("7d");
console.log(history.uptime_percent, history.points.length);

Info API Proxy

const meta = await client.info({ type: "metaAndAssetCtxs" });

WebSocket Streaming

All stream methods return typed AsyncIterable objects. Subscriptions auto-reconnect; iterate as long as you want data.

// Real-time trades
for await (const trade of client.stream.trades("BTC-PERP")) {
  console.log(trade.price, trade.size, trade.side);
}

// Wallet fills (copy trading)
for await (const fill of client.stream.fills("0xleader")) {
  console.log(fill.side, fill.size, fill.market);
}

// Order book updates
for await (const snap of client.stream.book("ETH-PERP")) {
  console.log(snap.bids[0].price, snap.asks[0].price);
}

// Filter by minimum size
for await (const trade of client.stream.trades("BTC-PERP", { min_size: "10" })) {
  // Only trades >= 10 BTC
}

Available streams: trades, fills, book, bookL4, orders, liquidations, fundingRates, deposits, withdrawals, vaultOperations.

Error Handling

import { Ironflow, RateLimitError, AuthError, TierError, QueryWindowError } from "@ironflowsh/sdk";

try {
  const trades = await client.trades("BTC-PERP");
} catch (err) {
  if (err instanceof RateLimitError) {
    // Retry after the specified delay
    console.log(`Rate limited, retry in ${err.retryAfterMs}ms`);
  } else if (err instanceof AuthError) {
    console.log("Invalid API key");
  } else if (err instanceof TierError) {
    console.log("Upgrade your plan for this endpoint");
  } else if (err instanceof QueryWindowError) {
    console.log("Time range too wide for your tier");
  }
}

Pagination

All list endpoints return a Page<T> with async pagination:

let page = await client.trades("BTC-PERP", { limit: 1000 });
const allTrades = [...page.data];

while (page.hasMore) {
  page = await page.next();
  allTrades.push(...page.data);
}

License

MIT