Skip to content

Repository files navigation

hip4-python

PyPI versionPython versionslicense


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
fromhip4importcreate_hip4_adapteradapter=create_hip4_adapter() # testnet by defaultadapter.initialize()
events=adapter.events.fetch_events(active=True, limit=20)

For async, use hip4.aio.create_async_hip4_adapter with async with.

Examples

Quickstart (sync)

importosfromhip4importLocalSigner, create_hip4_adapterfromhip4.typesimportPredictionOrderParamsadapter=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)

importasynciofromhip4.aioimportcreate_async_hip4_adapterasyncdefmain():
asyncwithcreate_async_hip4_adapter() asadapter:
awaitadapter.initialize()
events=awaitadapter.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

MethodDescription
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

MethodDescription
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

MethodDescription
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

MethodDescription
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

MethodSigningDescription
set_signer(signer)Set user wallet for EIP-712 ops
buy_usdh(amount)L1 agentBuy USDH on spot
sell_usdh(amount)L1 agentSell USDH on spot
transfer_to_spot(amount)EIP-712Perp → Spot
transfer_to_perps(amount)EIP-712Spot → Perp
withdraw(...)EIP-712Withdraw to external address
usd_send(...)EIP-712Send USDC to another HL address
spot_send(...)EIP-712Send arbitrary spot token
send_asset(...)EIP-712Unified-account-compatible transfer primitive

adapter.auth

MethodDescription
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:

TypeDescriptionParsed Fields
defaultBinaryRecurring price markets (BTC > $67,250 1d)underlying, target_price, expiry, period
labelledBinaryStandalone binary with custom sides (Hypurr vs Usain Bolt)Custom side labels
multiOutcomeOutcomes grouped under a question with fallbackquestion_id, question_name, is_fallback
priceBucketRecurring multi-bucket price marketsunderlying, expiry, price_thresholds, period, lower_bound, upper_bound
fromhip4.typesimportFetchMarketsParams# Filter by typebinaries=adapter.events.fetch_markets(FetchMarketsParams(type="defaultBinary"))
# Group by typegrouped=adapter.events.fetch_markets(FetchMarketsParams(group_by="type"))
# Group multi-outcome by questionby_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):

  1. Sort action keys in canonical order
  2. MessagePack-encode
  3. Append nonce as big-endian u64
  4. Append vault marker byte
  5. Keccak-256 hash → connectionId
  6. EIP-712 sign with Agent type on chainId 1337

User-signed EIP-712 (transfers, withdrawals, sends):

  • Domain: HyperliquidSignTransaction, signatureChainId: 0x66eee (testnet) or 0xa4b1 (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.