infinitefield/hypersdk/hyperliquid-rust-sdk
Claude Code and agent skill by infinitefield/hypersdk
- community
Checking that the SKILL.md file is still in the repository.
Write Rust code that uses the hypersdk crate to trade on Hyperliquid programmatically — placing/canceling orders, reading positions and account state, subscribing to market data via WebSocket, and signing/submitting transactions. Use this skill whenever writing or editing Rust code in a project that depends on hypersdk, for any order, position, balance, or market-data logic.
Install
npx vskill@latest install infinitefield/hypersdk/hyperliquid-rust-sdkSKILL.md
hypersdk (Rust)
Crate hypersdk 0.2.16 — the Rust library, called directly from bot code. Not the hypecli binary; never shell out.
Every signature and code block in this skill was checked against src/ at 0.2.16 and compile-checked in a consumer crate. The crate's own /// examples are not a reliable source: several reference items that do not exist (Client::mainnet(), ARBITRUM_SIGNATURE_CHAIN_ID, client.spot_meta(), Subscription::WebData2). If something is not in this skill, read src/hypercore/http.rs (all client methods) and src/hypercore/types/mod.rs (all types) before writing it.
Code blocks that end in fn main() {} are function-level snippets; the empty main is only there so each block compiles on its own. Blocks without fn main are signatures or type shapes for reference, not code to paste.
Where to look
| Task | File | |
|---|---|---|
| Market metadata, asset index, coin names, price ticks, size decimals, mids, book, candles | references/markets.md | |
| Place / market / cancel / modify orders, leverage, scheduled cancel, TWAP, order statuses | references/orders.md | |
| Positions, margin, balances, open orders, order status, fills, fees, rate limit | references/account.md | |
| WebSocket subscriptions, lifecycle, reconnects, posting over the socket | references/websocket.md | |
| USDC / spot transfers, withdrawals, agents, subaccounts, vaults, multisig | references/transfers.md | |
Complete programs taken from examples/ | references/recipes.md |
Setup
- The crate defines no Cargo features. Nothing to enable.
- It is edition 2024 with
rust-version = "1.94.1". Older toolchains are refused by cargo. - Keystore decryption (
PrivateKeySigner::decrypt_keystore) is not enabled by hypersdk's own
alloy features; it needs alloy = { version = "2", features = ["signer-keystore"] } in your crate. Raw hex keys need nothing extra.
Minimal working program:
Client / connection
HttpClient(=hypercore::http::Client) is not `Clone`. Share it asArc<HttpClient>.- The default inner
reqwest::Clienthas a 10 s timeout. - The chain decides the signing domain. A testnet client signs for testnet; you cannot reuse a
request across networks.
PrivateKeySigneris re-exported ashypersdk::hypercore::PrivateKeySigner(alloy's local
signer). signer.address() gives the account address.
- Creating a
WebSocketcallstokio::spawn, so it must happen inside a Tokio runtime.
A shape that fits a bot, following the patterns in examples/hypercore/:
Rules that keep generated code correct
- Prices and sizes are `rust_decimal::Decimal`, never
f64. Usedec!(0.01),.parse(),
or Decimal::try_from(f64) at the boundary (as examples/hypercore/market_order.rs does).
- Order and cancel `asset` is the market's `index` from
perps()/spot()/
outcomes(). Do not hardcode it; spot and HIP-3 indices are offset (see markets.md). Types differ: OrderRequest.asset, Cancel.asset, update_leverage take usize; CancelByCloid.asset and top_up_isolated_only_margin take u32.
- Info calls and WebSocket subscriptions take a coin string, not the index:
"BTC",
"xyz:XYZ100" (HIP-3), the spot market's name ("PURR/USDC", "@107"), or OutcomeMarket::coin() ("#42").
- Round every price with
market.round_price(px)or `market.round_by_side(side, px,
conservative); both return Option<Decimal> (None for zero/negative prices). There is **no size-rounding helper**: truncate sizes to sz_decimals` yourself (markets.md).
- Every signed action needs a fresh nonce. Use one
NonceHandlerper signing key and call
next() per request. For UsdSend.time, SpotSend.time and SendAsset.nonce, pass the same value you pass as nonce.
- A batch "succeeding" does not mean the orders did.
placereturns
Ok(Vec<OrderResponseStatus>), and a rejected order is OrderResponseStatus::Error(String) inside that Ok. Check every element.
- `vault_address` is
Nonefor your own account. Thesubaccounts()doc says to act on a
subaccount, the master signs with vault_address = Some(subaccount_address); the same parameter is used when trading for a vault.
- Agents (API wallets):
approve_agentis signed by the main account. When a bot signs
with an agent key, query positions/orders for the owning account, not signer.address(); client.user_role(agent) returns UserRole::Agent { user } with that account.
place,cancel,cancel_by_cloid,modify,send_asset,spot_sendand the outcome
methods are plain fns returning impl Future<Output = …> + Send + 'static. They sign at call time, don't borrow the client or signer, and can go straight into tokio::spawn.
Error handling
Every fallible call returns anyhow::Result, except the four batch order methods.
| Calls | Return type | What an error means | |
|---|---|---|---|
Info queries (perps, clearinghouse_state, open_orders, all_mids, …) | anyhow::Result<T> | ApiError = non-2xx HTTP (message has [label] HTTP <status> body=…); serde_json::Error (with body context) = response shape changed; reqwest::Error = network or timeout | |
place, cancel_by_cloid | Result<Vec<OrderResponseStatus>, ActionError<Cloid>> | The whole request failed: signing, network, HTTP, or the exchange answered {"status":"err"} | |
cancel | Result<Vec<OrderResponseStatus>, ActionError<u64>> | same, ids are oids | |
modify | Result<Vec<OrderResponseStatus>, ActionError<OidOrCloid>> | same | |
market_open, modify_order | anyhow::Result<Vec<OrderResponseStatus>> | same, converted into anyhow | |
Other signed actions returning () (update_leverage, send_usdc, withdraw, …) | anyhow::Result<()> | ApiError(msg) when the exchange answers {"status":"err"} or an unexpected response type | |
twap_order, twap_cancel, gossip_priority_bid | anyhow::Result<Response> | Transport/HTTP only; you match Response::Ok / Response::Err yourself |
ActionError<T> (hypersdk::hypercore::ActionError) has .message() -> &str, .ids() -> &[T] and .into_ids(). It stores the cause as a string: you cannot downcast it to reqwest::Error, so a timeout and a rejection look alike. Put a Cloid on orders you care about so you can reconcile with order_status(account, OidOrCloid::Right(cloid)) after an ambiguous failure. ActionError implements std::error::Error, so ? into anyhow works.
Downcasting an anyhow::Error, from examples/hypercore/error_handling.rs (needs reqwest and serde_json in your Cargo.toml):
Not in the crate — do not invent these
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/hyperliquid-rust-sdk/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/infinitefield/hypersdk/hyperliquid-rust-sdk)