Overview
Hyperliquid uses two distinct signing mechanisms with different chain IDs and purposes:Type | Chain ID | Domain | Purpose |
---|---|---|---|
L1 Actions | 1337 | ”Exchange” | Trading operations: order, cancel, cancelByCloid, modify, batchModify, scheduleCancel, updateLeverage, updateIsolatedMargin, vaultTransfer, subAccountTransfer |
User-Signed | 0x66eee | ”HyperliquidSignTransaction” | Administrative operations: approveAgent, usdSend, spotSend, usdClassTransfer, withdraw, approveBuilderFee, tokenDelegate |
See also the Hyperliquid API reference.
Exchange endpoints will not work without proper signatures. The Hyperliquid Python SDK v0.18.0+ handles signing complexity internally.
Types of signatures
1. L1 Action signatures (Trading operations)
L1 actions use a phantom agent construction - a temporary signing identity created from your action’s hash:- Chain ID: 1337 (NOT Arbitrum’s 42161)
- Domain: “Exchange”
- Serialization: Msgpack binary format
- Implementation guide: L1 Action signing guide
2. User-Signed actions (Administrative operations)
User-signed actions use direct EIP-712 signing without phantom agent abstraction:- Chain ID: 0x66eee (421614 in decimal)
- Domain: “HyperliquidSignTransaction”
- Serialization: Direct JSON structure
- Implementation guide: User-signed actions guide
Key concepts
Phantom Agent
A cryptographic construct (not a real wallet) used for L1 actions:- Action serialized with msgpack
- Nonce and vault address appended
- Data hashed with keccak256
- Temporary “agent” object created with hash as connectionId
- This phantom agent is signed via EIP-712
Agent Wallet
A separate keypair authorized to sign L1 actions on behalf of your account:- Stateless: No funds or positions
- Nonce isolation: Independent nonce tracking
- Limited scope: Can only sign L1 actions, not transfers
- Approved via: User-signed action (approveAgent)
Signature components
Every signature consists of three components:- r — First 32 bytes of the ECDSA signature
- s — Second 32 bytes of the ECDSA signature
- v — Recovery ID (27 or 28) used to recover the public key
Architecture
Authentication flow
1
Choose signing mechanism
Determine if you need L1 actions (trading) or user-signed actions (admin/transfers)
2
Prepare the action
Create the action object with operation details
3
Add timestamp
Use current timestamp in milliseconds as nonce
4
Sign appropriately
L1 actions: Use phantom agent construction
User-signed: Use direct EIP-712 signing
5
Send the request
Include signature, action, and nonce in request body
Complete list of supported actions
L1 Actions (Chain ID: 1337)
These actions use phantom agent construction with msgpack serialization.Action | Description | Category |
---|---|---|
order | Place new orders | Trading |
cancel | Cancel orders by order ID | Trading |
cancelByCloid | Cancel orders by client order ID | Trading |
modify | Modify existing orders | Trading |
batchModify | Modify multiple orders at once | Trading |
scheduleCancel | Schedule order cancellation | Trading |
updateLeverage | Adjust leverage for positions | Position Management |
updateIsolatedMargin | Manage isolated margin | Position Management |
vaultTransfer | Transfer between vault accounts | Internal Transfers |
subAccountTransfer | Transfer between sub-accounts | Internal Transfers |
noop | No operation (for testing signatures) | Utility |
For implementation details and code examples, see the L1 Action signing guide.
User-Signed Actions (Chain ID: 0x66eee)
These actions use direct EIP-712 signing with JSON structure.Action | Description | Category |
---|---|---|
approveAgent | Authorize an agent wallet to trade on your behalf | Agent Management |
usdSend | Transfer USDC between accounts | Fund Transfers |
spotSend | Transfer spot tokens | Fund Transfers |
usdClassTransfer | Transfer between USD classes | Fund Transfers |
withdraw | Withdraw funds to Layer 1 | Withdrawals |
approveBuilderFee | Approve builder fee structures | Advanced |
tokenDelegate | Delegate token voting rights | Advanced |
For implementation details and code examples, see the User-signed actions guide.
Common issues and solutions
Wrong chain ID
Error: Signature verification failedCause: Using incorrect chain ID (especially using Arbitrum’s 42161)
Solution:
- L1 actions: Use Chain ID 1337 (NOT 42161)
- User-signed: Use Chain ID 0x66eee (421614 in decimal)
Invalid nonce
Error: Invalid or expired nonceCause: Nonce is too old, in the future, or not in milliseconds
Solution: Use current timestamp in milliseconds:
get_timestamp_ms()
or Date.now()
Signature type mismatch
Error: Unauthorized or invalid signatureCause: Mixing up signing mechanisms or serialization
Solution:
- L1 actions: Use phantom agent with msgpack serialization
- User-signed: Use direct EIP-712 with JSON structure
Agent issues
Error: Agent not approved / Agent already existsCause: Using unapproved agent or duplicate agent name
Solution:
- Approve agent first with
exchange.approve_agent()
- Use unique agent names for each bot/integration
Invalid action format
Error: Failed to deserialize / Invalid actionCause: Missing required fields or wrong structure
Solution: Ensure action payloads include all required fields (e.g.,
grouping
for orders)
Best practices
DO
- Use the official SDK when possible for automatic signature handling
- Keep your private keys secure and never expose them in code
- Use environment variables or secure key management systems
- Implement proper error handling for signature failures
- Test with small amounts on mainnet or use testnet first
DON’T
- Share your private keys or commit them to version control
- Reuse nonces across different requests
- Use placeholder signatures in production
- Skip signature validation in your implementation
Official SDKs
The official SDKs handle all signing complexity internally, including phantom agent construction and EIP-712 formatting.
Python SDK
- Repository: hyperliquid-python-sdk
- Version: v0.18.0+ required
- Features:
- Automatic phantom agent construction for L1 actions
- Built-in wrapper functions for all user-signed actions
- Support for both mainnet and testnet
Rust SDK
- Repository: hyperliquid-rust-sdk
- Features:
- Full L1 action support
- User-signed action support
- High-performance implementation
Installation
Python:Testing your implementation
- Start with testnet: Use
https://api.hyperliquid-testnet.xyz
for testing - Verify signatures locally: Ensure your signatures are properly formatted before sending
- Use small amounts: Test with minimal amounts when moving to mainnet
- Monitor rate limits: Respect API rate limits to avoid being blocked
Implementation guides
Quick Reference
Side-by-side comparison of both signing mechanisms
L1 Action Signing
Complete guide with code examples for trading operations
User-Signed Actions
Detailed guide for administrative operations and agent management
API Reference
Full API documentation for all exchange endpoints
Key points to remember
- Info endpoints don’t require signatures and can be accessed directly
- Exchange endpoints require appropriate signing based on the action type
- L1 actions use phantom agent construction with Chain ID 1337
- User-signed actions use direct EIP-712 signing with Chain ID 0x66eee
- Agent wallets can only perform L1 actions, not transfers or withdrawals