Hyperliquid vs Binance API: agent wallets, EIP-712 and nonces
Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs.
Comparing two centralised exchanges is mostly a question of which headers go where. Hyperliquid vs Binance is different, because almost nothing ports: no API key, no HMAC secret, no receive window, no numeric error code. What replaces them solves the same problems differently, and mapping them one-to-one gets both the code and the security reasoning wrong.
This page is for developers adding one to the other. It covers mechanism, quotes no fees or quotas, and recommends neither venue. For the wider checklist, see choosing an exchange for automation.
Short answer
- You want a credential whose permissions you can inspect and tie to an IP
→ Binance. Permissions are flags on the key, withdrawals require IP
restriction, and
GET /sapi/v1/account/apiRestrictionsreports them. - You want to delegate trading without handing over the account’s own key → Hyperliquid’s agent wallets: the master approves a separate signing key.
- You want to branch error handling on numeric codes → Binance. Hyperliquid returns human-readable strings.
- You are porting working HMAC code → it will not transfer. Plan to rewrite signing against Hyperliquid’s official Python SDK.
What they have in common
- Separate mainnet and testnet hosts.
- An IP-based, weighted request budget.
- Sub-accounts under a master account.
- A mechanism that rejects stale or replayed requests — though, as below, they are not the same mechanism.
Where they actually differ
The credential: API key vs agent wallet
Binance issues an API key and secret (Spot also supports RSA and Ed25519
pairs), sent in X-MBX-APIKEY; permissions and IP restrictions belong to the
key.
Hyperliquid has no API key. Authorisation is delegation:
- A master account approves an API wallet (also called an agent wallet)
with a signed
approveAgentaction carryingagentAddress, an optionalagentNameand anonce. An expiry can be set; the maximum is on the exchange-endpoint page. - API wallets only sign. To query account data you pass the master or sub-account address. Querying with the agent’s address is what the docs call “a common pitfall” that “leads to an empty result”.
- Sub-accounts and vaults have no private keys. You sign with the master or its
agent and set
vaultAddress. - Agents may be pruned when deregistered (a new unnamed agent replaces the previous unnamed one), when they expire, or when the registering account has no funds. Since “previously signed actions can be replayed once the nonce set is pruned”, the docs advise new wallets rather than reused addresses.
The practical trap: a second tool that “sets up its own API wallet” without a name silently disables the first. See what an agent wallet is and Hyperliquid API setup.
Signing: HMAC vs EIP-712
Binance signs the query string concatenated with the body using HMAC-SHA256
and sends the hex result as signature. A mismatch returns -1022
“Signature for this request is not valid.”
Hyperliquid uses EIP-712 typed-data signatures with an Ethereum (secp256k1) key, in two schemes — confusing them is the docs’ first listed common error:
| L1 actions | User-signed actions | |
|---|---|---|
| Used for | Orders, cancels, leverage, vaultTransfer | approveAgent, withdraw3, usdSend, spotSend and similar |
| What is signed | A “phantom agent” built from a hash of the msgpack-encoded action, the nonce and the vault address | The action itself as typed data |
| Environment in the signature | source "a" mainnet / "b" testnet | hyperliquidChain "Mainnet" / "Testnet" |
Other listed errors: msgpack field order, trailing zeroes on numbers, and addresses not lowercased before signing.
A bad signature on Hyperliquid does not say “invalid signature”: the exchange
recovers a different signer and returns L1 error: User or API Wallet 0x… does not exist., with an
address that changes between requests. Third-party sources report the same
string for an expired or replaced agent. See
the “User or API Wallet does not exist” error
and API signature methods compared.
Replay protection: nonces vs recvWindow
Binance checks freshness. A signed request carries timestamp, and the
server rejects it if it is older than recvWindow (default 5000 ms) or more
than one second ahead, with -1021.
Hyperliquid checks uniqueness. Every action carries a nonce (the docs
recommend current milliseconds). A set of the highest recent nonces is stored
per signer; a new nonce must exceed the smallest in that set, be unused, and
fall within a window around block time (details on the nonces page).
Two consequences for a ported Binance bot:
- Nonces are tracked per signer. Sub-accounts signed by the same API wallet share one nonce set, so the docs recommend a separate API wallet per process.
- Freshness is opt-in. The CEX-style “reject if stale” check is the
optional
expiresAfterfield, which user-signed actions such as USDC transfers do not support.
See clock sync and timestamps.
Rate limits
Binance meters request weight per IP and order counts per account; 429
escalates to a 418 IP ban.
Hyperliquid has two meters. The IP-based one is familiar: weighted
requests. The address-based one is not: each address earns an action allowance
from its cumulative trading volume, starting from an initial buffer; once
it runs out, requests are throttled hard, though cancels have a higher limit. A batch of n orders counts once
for the IP meter and n times for the address meter. Sub-accounts are treated
as separate users.
A new, low-volume address has a small action budget however light its IP traffic. Numbers are on the rate-limits page. See rate-limit models compared.
Errors: numeric codes vs strings
Binance returns { "code": -1121, "msg": "Invalid symbol." } with a meaningful
HTTP status, and 5XX means the outcome is unknown.
Hyperliquid returns strings. Per-order failures arrive inside an HTTP 200
"status":"ok" envelope, at response.data.statuses[i].error, as a vector the
same length as the batch — for example Price must be divisible by tick size.
or Reduce only order would increase position. Some errors are deterministic
from the payload, and then one error covers the whole batch. A top-level
"status":"err" envelope has been reported in the official SDK’s issue
tracker but is not shown in Hyperliquid’s docs.
Log the raw string and match defensively; some strings embed changing values, such as the minimum order value — see the minimum value error.
Withdrawals
Binance makes withdrawal a key permission. It cannot be enabled without IP
restriction, and apiRestrictions reports enableWithdrawals, so a process
can verify at startup that its key cannot withdraw. See
disabling withdrawals on a Binance key.
Hyperliquid’s docs do not say whether an API wallet can sign withdrawals. The official SDK handles withdrawals and transfers with a different signing scheme from trading, and third-party integrations (e.g. NautilusTrader) state that these require the master key. Verify against your own setup before treating it as a security boundary. The withdrawal fee and settlement time are on the exchange-endpoint page, which hedges them itself.
Test environments
Binance runs separate testnet and demo hosts per product. Hyperliquid’s
testnet, https://api.hyperliquid-testnet.xyz, takes the same requests, and
the environment is inside the signature too. Its faucet requires a prior
mainnet deposit from the same address.
SDKs
Binance ships official connectors in Python, JavaScript, Java, Go, Rust, PHP and Ruby. Hyperliquid lists one official SDK, in Python; its Rust and TypeScript SDKs are labelled community-written.
Which to pick
| Your situation | Lean toward | Why |
|---|---|---|
| You need to prove at startup that the credential cannot withdraw | Binance | Documented permission flag and query endpoint |
| You want to delegate signing without exposing the account key | Hyperliquid | Agent wallets approved by the master |
| Your error handling is keyed on numeric codes | Binance | Hyperliquid returns strings |
| You run many processes on one account | Either, with care | Binance shares IP weight; Hyperliquid needs one API wallet per process for nonces |
| Your stack is not Python and you want an official SDK | Binance | The one SDK Hyperliquid lists as its own is Python |
Can you use both
Yes, but share less code than you expect: keep signing, nonces and error parsing venue-specific, and normalise only to “accepted, rejected, unknown”. Reconcile after any ambiguous result — see why retrying a failed order is not safe.
FAQ
Does Hyperliquid have API keys?
No. A master account approves an API wallet, also called an agent wallet, to sign actions on its behalf using an Ethereum key and EIP-712 signatures. The agent only signs; account queries must use the master or sub-account address, or they return an empty result.
Can a Hyperliquid agent wallet withdraw funds?
Hyperliquid’s docs do not say whether an API wallet can sign withdrawals. The official SDK handles withdrawals and transfers with a different signing scheme from trading, and third-party integrations such as NautilusTrader state that these require the master key. Verify against your own setup before treating it as a security boundary.
What replaces recvWindow on Hyperliquid?
A nonce. Each signer has a stored set of its highest recent nonces; a new one
must be larger than the smallest of them and never used before. The docs
recommend the current time in milliseconds. A staleness check exists only as
the optional expiresAfter field on some actions.
Why does Hyperliquid say my wallet does not exist when it does?
User or API Wallet 0x… does not exist usually means the signature was
computed over different bytes than expected, so a different signer was
recovered. If the address in the error is not yours and changes between
requests, look for msgpack field order, trailing zeroes or upper-case
addresses. Third-party sources also report it for an expired or replaced
agent wallet.