Python SDK for Hyperliquid HIP-4 prediction markets
Project description
hip4-python
Python SDK for Hyperliquid HIP-4 prediction markets. Sync and async clients, with EIP-712 signing handled internally.
This is the Python port of @perps/hip4. The TypeScript SDK remains the reference implementation; this port mirrors its public surface, types, and signing behaviour.
Install
pip install hip4 # sync (requests + websocket-client)
pip install hip4[async] # also installs httpx + websockets for the async client
from hip4 import create_hip4_adapter
adapter = create_hip4_adapter() # testnet by default
adapter.initialize()
events = adapter.events.fetch_events(active=True, limit=20)
For async, use hip4.aio.create_async_hip4_adapter with async with.
Examples
auth_eoa.py– Agent key approval and auth setupget_all_markets.py– Fetch all markets grouped by typeplace_limit_order.py– Limit order with price validationplace_market_order.py– Market order withFrontendMarketTIFstream_prices.py– Stream live prices via WebSocketasync_get_all_markets.py– Async market fetch
Quickstart (sync)
import os
from hip4 import LocalSigner, create_hip4_adapter
from hip4.types import PredictionOrderParams
adapter = create_hip4_adapter()
adapter.initialize()
# Agent key (separate from the user's wallet - sign with the user's wallet
# once via auth_eoa.py to approve, then store the agent key for trading).
agent = LocalSigner(os.environ["HIP4_AGENT_PRIVATE_KEY"])
adapter.auth.init_auth(os.environ["HIP4_USER_ADDRESS"], agent)
result = adapter.trading.place_order(PredictionOrderParams(
market_id="123",
outcome="#1230",
side="buy",
type="limit",
price="0.5",
amount="20",
time_in_force="GTC",
))
print(result) # PredictionOrderResult(success=True, order_id="...", ...)
adapter.destroy()
Quickstart (async)
import asyncio
from hip4.aio import create_async_hip4_adapter
async def main():
async with create_async_hip4_adapter() as adapter:
await adapter.initialize()
events = await adapter.events.fetch_events(active=True, limit=20)
print(len(events), "active events")
asyncio.run(main())
API
The Python API is a snake_case mirror of the TypeScript SDK. All sub-adapters live on the top-level HIP4Adapter (sync) / AsyncHIP4Adapter (async) facade.
adapter.events
| Method | Description |
|---|---|
fetch_events(category, active, limit, offset, query) |
List events with optional filters |
fetch_event(event_id) |
Single event by ID |
fetch_categories() |
Available categories |
fetch_markets(params) |
Typed HIP-4 markets with optional grouping by type or question |
fetch_settled_outcome(outcome_id) |
Settlement details for a resolved outcome |
ensure_side_names() |
Pre-load side-name mappings |
get_side_name_resolver() |
Returns a sync resolver for side names by outcome ID |
adapter.market_data
| Method | Description |
|---|---|
fetch_order_book(market_id, side_index=0) |
L2 snapshot |
fetch_price(market_id) |
Both sides, 5s cache |
fetch_trades(market_id, limit=50, side_index=0) |
Recent trades |
fetch_candles(market_id, interval, start_time, end_time) |
OHLCV candles |
subscribe_order_book(market_id, on_data) |
Real-time L2 book |
subscribe_price(market_id, on_data) |
Real-time prices |
subscribe_trades(market_id, on_data) |
Real-time trades |
subscribe_all_mids(on_data) |
Bulk mid-price updates |
subscribe_active_asset_ctx(coin, on_data) |
Spot asset context |
subscribe_perp_asset_ctx(coin, on_data) |
Perp asset context |
Subscriptions return an unsubscribe callable.
adapter.account
| Method | Description |
|---|---|
fetch_positions(address) |
Outcome positions with resolved side names |
fetch_activity(address) |
Fills, last 30 days |
fetch_balance(address) |
Spot balances (incl. USDH) |
fetch_open_orders(address) |
Resting orders |
subscribe_positions(address, on_data) |
Polls every 10 s |
adapter.trading
| Method | Description |
|---|---|
place_order(params) |
Place a market or limit order |
place_orders(params_list) |
Batch order placement |
cancel_order(params_list) |
Cancel one or more resting orders |
modify_order(params) |
Modify a resting order (preserves queue priority on size-only changes) |
split_outcome(...), merge_outcome(...), merge_question(...), negate_outcome(...) |
HIP-4 share-conversion primitives |
schedule_cancel(time_ms) |
HL "dead-man's switch" |
adapter.wallet
| Method | Signing | Description |
|---|---|---|
set_signer(signer) |
– | Set user wallet for EIP-712 ops |
buy_usdh(amount) |
L1 agent | Buy USDH on spot |
sell_usdh(amount) |
L1 agent | Sell USDH on spot |
transfer_to_spot(amount) |
EIP-712 | Perp → Spot |
transfer_to_perps(amount) |
EIP-712 | Spot → Perp |
withdraw(...) |
EIP-712 | Withdraw to external address |
usd_send(...) |
EIP-712 | Send USDC to another HL address |
spot_send(...) |
EIP-712 | Send arbitrary spot token |
send_asset(...) |
EIP-712 | Unified-account-compatible transfer primitive |
adapter.auth
| Method | Description |
|---|---|
init_auth(wallet_address, signer) |
Sets the active signer used by trading & USDH ops |
get_auth_status() |
"disconnected" | "pending_approval" | "ready" |
clear_auth() |
Reset auth state |
The signer must implement the hip4.types.hl.Signer protocol (get_address() + sign_typed_data(domain, types, value)). Use hip4.LocalSigner for in-memory keys, or wrap your own custodian / hardware-wallet bridge.
Market Types
adapter.events.fetch_markets() classifies every HIP-4 outcome into one of four types:
| Type | Description | Parsed Fields |
|---|---|---|
defaultBinary |
Recurring price markets (BTC > $67,250 1d) | underlying, target_price, expiry, period |
labelledBinary |
Standalone binary with custom sides (Hypurr vs Usain Bolt) | Custom side labels |
multiOutcome |
Outcomes grouped under a question with fallback | question_id, question_name, is_fallback |
priceBucket |
Recurring multi-bucket price markets | underlying, expiry, price_thresholds, period, lower_bound, upper_bound |
from hip4.types import FetchMarketsParams
# Filter by type
binaries = adapter.events.fetch_markets(FetchMarketsParams(type="defaultBinary"))
# Group by type
grouped = adapter.events.fetch_markets(FetchMarketsParams(group_by="type"))
# Group multi-outcome by question
by_question = adapter.events.fetch_markets(FetchMarketsParams(group_by="question"))
Signing
Both Hyperliquid signing flows are implemented from scratch, using msgpack, eth-utils.keccak, and eth-account for EIP-712. They produce byte-for-byte equivalent signatures to the TypeScript SDK (verified by parity tests).
L1 agent signing (orders, cancels, USDH spot, share conversions, scheduleCancel):
- Sort action keys in canonical order
- MessagePack-encode
- Append nonce as big-endian u64
- Append vault marker byte
- Keccak-256 hash →
connectionId - EIP-712 sign with
Agenttype on chainId1337
User-signed EIP-712 (transfers, withdrawals, sends):
- Domain:
HyperliquidSignTransaction,signatureChainId: 0x66eee(testnet) or0xa4b1(mainnet) - Message filtered to EIP-712 type keys only
- Requires the user wallet (agent keys are rejected)
The pure helpers (sign_l1_action, sign_user_signed_action, sort_*, encode_msgpack, create_l1_action_hash) are exposed at the top level for callers who want to sign outside the adapter.
Development
poetry install --all-extras --with dev
make test # pytest
make lint # ruff + mypy
make format # black + isort
Python 3.10+ is required (uses kw_only dataclasses and PEP 604 unions in some places).
Acknowledgements
Signing implementation inspired by @nktkas/hyperliquid (TS) and the official Hyperliquid Python SDK.
License
BUSL-1.1 - same as the TypeScript SDK.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hip4-0.1.0.tar.gz.
File metadata
- Download URL: hip4-0.1.0.tar.gz
- Upload date:
- Size: 92.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e54050a9843c439f635485286224124c056fd30786cd917fcd2c59d70ef297a
|
|
| MD5 |
e4eb8ba01bf88449ad7dedd2578d90a0
|
|
| BLAKE2b-256 |
308737846a613540680dc4aacbe5729a1beaf18b409e3774d371bc642e134585
|
File details
Details for the file hip4-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hip4-0.1.0-py3-none-any.whl
- Upload date:
- Size: 120.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a68a9bd49daeb7972bbb8a0ac990059765027050b87bcc1c6131429d202a526
|
|
| MD5 |
888279e8df0d7bc93ddc7f3d0c03fddb
|
|
| BLAKE2b-256 |
d5acc96d11047b57bc3b3be5dbc879d2cfc8e636cf0978ed217cdaf5df060661
|