Metadata-Version: 2.4
Name: ironflow-sdk
Version: 0.5.1
Summary: Async Python SDK for Hyperliquid market data — fills, trades, liquidations, order books, HIP-3 + HIP-4, full wallet analytics — REST + WebSocket
Project-URL: Homepage, https://ironflow.sh
Project-URL: Documentation, https://docs.ironflow.sh
Project-URL: Support, https://docs.ironflow.sh
Author-email: Ironflow <hello@ironflow.sh>
License: MIT
License-File: LICENSE
Keywords: crypto,defi,hyperliquid,ironflow,market-data,perpetuals,sdk,trading,websocket
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Requires-Dist: websockets>=12
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# ironflow-sdk

Async Python SDK for [Ironflow](https://ironflow.sh) — 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. Pandas-friendly bulk export for analysis.

**[Get a free API key](https://ironflow.sh/dashboard/login)** 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

```bash
pip install ironflow-sdk
```

Python 3.11+. Built on `httpx` and `websockets`. Fully typed (`py.typed`).

## Quick Start

```python
import asyncio
from ironflow_sdk import Ironflow

async def main():
    async with Ironflow("if_your_api_key") as client:
        # Stream live trades (paid tiers)
        async for trade in client.stream.trades("BTC-PERP"):
            print(trade.price, trade.size, trade.side)
            break  # demo: take one and exit

        # Or fetch history with auto-pagination
        page = await client.trades("BTC-PERP", limit=100)
        for trade in page.data:
            print(trade)

asyncio.run(main())
```

## Recipes

### Copy-trade a wallet

Mirror every fill from a leader address as it lands.

```python
async with Ironflow("if_xxx") as client:
    async for fill in client.stream.fills("0xleader"):
        print(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.

```python
import httpx

async with Ironflow("if_xxx") as client, httpx.AsyncClient() as http:
    async for liq in client.stream.liquidations("BTC-PERP"):
        if float(liq.size) >= 10:
            await http.post(SLACK_WEBHOOK, json={
                "text": f"{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.

```python
async with Ironflow("if_xxx") as client:
    markets = await client.markets(market_class="perp")
    for m in markets:
        page = await client.funding(m.display_symbol, limit=1)
        if page.data and abs(float(page.data[0].rate)) > 0.0005:
            print(m.display_symbol, page.data[0].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.

```python
async with Ironflow("if_xxx") as client:
    addr = "0xabc..."

    # Live snapshot (HL clearinghouseState shape)
    state = await client.user_state(addr)
    print(state.margin_summary.account_value, len(state.positions))

    # Funding payments — positive = paid, negative = received
    funding = await client.user_funding(addr, from_ts=int(time.time() * 1000) - 14 * 86_400_000)
    total = sum(float(p.usdc) for p in funding)

    # Maker/taker split, per market + a synthetic TOTAL row
    mt = await client.user_maker_taker(addr, from_ts=int(time.time() * 1000) - 14 * 86_400_000)
    total_row = next(r for r in mt.breakdown if r.market == "TOTAL")

    # Unified ledger: deposits, withdrawals, funding, transfers
    page = await client.user_ledger(addr, limit=200)
```

### Bulk export to pandas

Bulk historical data exports as CSV or Parquet (Builder+ tier). Pipe straight into pandas for analysis.

```python
import io
import pandas as pd

async with Ironflow("if_xxx") as client:
    data = await client.export_data("fills", market="BTC-PERP", format="csv")
    df = pd.read_csv(io.BytesIO(data))
    print(df.describe())
```

### 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.

```python
async with Ironflow("if_xxx") as client:
    predictions = await client.markets(market_class="prediction")
    # predictions[0].display_symbol -> e.g. "BTC-78213-20260503-Yes"
```

## Configuration

```python
client = Ironflow(
    "if_your_api_key",
    base_url="https://api.ironflow.sh",  # default
    source="hyperliquid",                # default
    timeout=30.0,                        # request timeout in seconds (default: 30)
)
```

## REST Endpoints

### Market Data

```python
async with Ironflow("if_your_api_key") as client:
    # Trades
    trades = await client.trades("BTC-PERP", limit=100)

    # Fills (requires address)
    fills = await client.fills("0xabc...", market="ETH-PERP")

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

    # OHLCV candles
    candles = await client.candles("BTC-PERP", "1h", limit=24)

    # Liquidations
    liqs = await client.liquidations("BTC-PERP")

    # Funding rates
    rates = await client.funding("BTC-PERP")

    # Open interest
    oi = await client.open_interest("BTC-PERP")

    # Mark prices
    prices = await client.mark_prices("BTC-PERP")

    # Deposits & withdrawals
    deps = await client.deposits(address="0xabc...")
    wds = await client.withdrawals(address="0xabc...")

    # Order statuses
    orders = await client.order_statuses(address="0xabc...")

    # Vault operations
    vaults = await client.vault_operations(vault="HLP")
```

### Wallet Analytics

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

```python
addr = "0xabc..."

# Open positions + margin summary (HL clearinghouseState shape)
state = await client.user_state(addr)

# Funding payments — paid (positive) and received (negative)
funding = await client.user_funding(addr, from_ts=from_ms, to_ts=to_ms)

# Maker vs taker breakdown per market + a synthetic TOTAL row
mt = await client.user_maker_taker(addr, from_ts=from_ms, to_ts=to_ms)
# mt.breakdown[i].market, .maker_volume, .taker_volume, .maker_pct, .taker_pct

# Unified ledger: deposits / withdrawals / funding / transfers
page = await client.user_ledger(addr, limit=200, cursor=None)
```

### Analytics (Builder+)

```python
flows = await client.net_flows(interval="1d", limit=7)
# flows[0].deposits, flows[0].withdrawals, flows[0].net_flow

levels = await client.liquidation_levels("BTC-PERP", bucket_size=100)
# levels[0].price_bucket, levels[0].count, levels[0].total_size

order_flow = await client.order_flow()
# order_flow[0].total_orders, order_flow[0].filled_orders, order_flow[0].fill_rate

leaderboard = await client.vault_leaderboard()
# leaderboard[0].vault, leaderboard[0].total_deposits, leaderboard[0].net_flow

funding = await client.funding_stats("BTC-PERP", interval="8h")
# funding[0].avg_rate, funding[0].min_rate, funding[0].max_rate
```

### Triggers

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

# List, toggle, delete
triggers = await client.list_triggers()
await client.toggle_trigger(trigger.id, is_active=False)
await client.delete_trigger(trigger.id)

# Test a rule without creating
matched = await client.test_trigger(
    rule={"condition": {"field": "data.size", "op": "gt", "value": "10"}},
    event={"data": {"size": "50", "market": "BTC-PERP"}},
)
print(matched)  # True
```

### Markets

```python
# All currently-active markets (perp + spot, every issuer)
all_markets = await client.markets()

# Filter by class and issuer
perps   = await client.markets(market_class="perp")
native  = await client.markets(issuer="")           # native non-builder only
flx_only = await client.markets(issuer="flx")       # HIP-3 builder
predictions = await client.markets(market_class="prediction")  # HIP-4

# Each Market 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)

```python
cohorts = await client.list_cohorts()
addrs = await client.cohort_addresses("top_pnl_30d")
await client.create_cohort("my_whales", ["0xabc...", "0xdef..."])
await client.delete_cohort("my_whales")
```

### Export (Builder+)

```python
data = await client.export_data(
    "fills",
    market="BTC-PERP",
    format="csv",
)
# data is bytes — write to file or parse with pandas
import io
import pandas as pd
df = pd.read_csv(io.BytesIO(data))
```

### Status

```python
# Overall system status + per-venue freshness
status = await client.status()
print(status.status)  # "operational"
print(status.venues["hyperliquid"].streams["fills"].age_seconds)

# Rolling-window performance metrics (5-min API + pipeline + synthetic)
metrics = await client.status_metrics()
print(metrics.api.latency_p99_ms, metrics.pipeline.events_per_sec)

# Uptime / freshness timeline — "24h" (default) or "7d"
history = await client.status_history("7d")
print(history.uptime_percent, len(history.points))
```

### Info API Proxy

```python
meta = await client.info({"type": "metaAndAssetCtxs"})
```

## WebSocket Streaming

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

```python
# Real-time trades
async for trade in client.stream.trades("BTC-PERP"):
    print(trade.price, trade.size, trade.side)

# Wallet fills (copy trading)
async for fill in client.stream.fills("0xleader"):
    print(fill.side, fill.size, fill.market)

# Order book updates
async for snap in client.stream.book("ETH-PERP"):
    print(snap.bids[0].price, snap.asks[0].price)

# Filter by minimum size
async for trade in client.stream.trades("BTC-PERP", min_size="10"):
    pass  # Only trades >= 10 BTC
```

Available streams: `trades`, `fills`, `book`, `book_l4`, `orders`, `liquidations`, `funding_rates`, `deposits`, `withdrawals`, `vault_operations`.

## Error Handling

```python
from ironflow_sdk import Ironflow, RateLimitError, AuthError, TierError, QueryWindowError

try:
    trades = await client.trades("BTC-PERP")
except RateLimitError as e:
    print(f"Rate limited, retry in {e.retry_after_ms}ms")
except AuthError:
    print("Invalid API key")
except TierError:
    print("Upgrade your plan for this endpoint")
except QueryWindowError:
    print("Time range too wide for your tier")
```

## Pagination

All list endpoints return a `Page[T]` with async pagination:

```python
page = await client.trades("BTC-PERP", limit=1000)
all_trades = list(page.data)

while page.has_more:
    page = await page.next()
    all_trades.extend(page.data)
```

## Links

- Dashboard: [ironflow.sh/dashboard](https://ironflow.sh/dashboard)
- Docs: [docs.ironflow.sh](https://docs.ironflow.sh)
- API reference: [docs.ironflow.sh/api-reference](https://docs.ironflow.sh/api-reference)
- TypeScript SDK: [`@ironflowsh/sdk`](https://www.npmjs.com/package/@ironflowsh/sdk)
- MCP server (for AI agents): [`@ironflowsh/mcp`](https://www.npmjs.com/package/@ironflowsh/mcp)

## License

MIT
