From 2a2839c02c89dd38847e8b7a84ce730d95ded57c Mon Sep 17 00:00:00 2001 From: perplover <184728147+perplover@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:01:16 -0800 Subject: [PATCH 1/4] Add details into README to improve integrations --- README.md | 322 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 321 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da071431..640bee4b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,321 @@ pip install hyperliquid-python-sdk ### [Optional] Generate a new API key for an API Wallet Generate and authorize a new API private key on https://app.hyperliquid.xyz/API, and set the API wallet's private key as the `secret_key` in examples/config.json. Note that you must still set the public key of the main wallet *not* the API wallet as the `account_address` in examples/config.json +## Quick Start + +```python +from hyperliquid.info import Info +from hyperliquid.exchange import Exchange +from hyperliquid.utils import constants +import eth_account + +# Create wallet from private key +wallet = eth_account.Account.from_key("your_private_key") + +# Initialize Info and Exchange instances +info = Info(constants.TESTNET_API_URL) # Use MAINNET_API_URL for mainnet +exchange = Exchange(wallet, constants.TESTNET_API_URL) + +# Get user state +user_state = info.user_state(wallet.address) +print(user_state) + +# Place a limit order +order_result = exchange.order( + name="ETH", # Asset name + is_buy=True, # True for buy, False for sell + sz=0.1, # Order size + limit_px=1800, # Limit price + order_type={"limit": {"tif": "Gtc"}} # Good-till-cancel order +) +``` + +## Core Concepts + +### Info Class + +The `Info` class provides methods to query market data and user information: + +```python +from hyperliquid.info import Info + +info = Info(constants.TESTNET_API_URL) + +# Get order book +l2_book = info.l2_book("ETH") + +# Get user's open orders +open_orders = info.open_orders(wallet.address) + +# Get all asset mid prices +mid_prices = info.all_mids() +``` + +### Exchange Class + +The `Exchange` class handles all trading operations: + +```python +from hyperliquid.exchange import Exchange + +exchange = Exchange(wallet, constants.TESTNET_API_URL) + +# Market order +exchange.market_open( + name="BTC", + is_buy=True, + sz=0.01, + slippage=0.001 # 0.1% slippage tolerance +) + +# Close position +exchange.market_close("BTC") + +# Cancel order +exchange.cancel("ETH", order_id) +``` + +### Websockets +The SDK provides real-time market data and user events through WebSocket connections. The WebSocket manager automatically handles connection maintenance and reconnection. + +#### Basic Websockets Connection +```python +from hyperliquid.info import Info +from hyperliquid.utils import constants + +def handle_orderbook(message): + bids, asks = message["data"] + print(f"Top bid: {bids[0]['px']} | Top ask: {asks[0]['px']}") + +def handle_trades(message): + for trade in message["data"]: + print(f"Trade: {trade['sz']} @ {trade['px']}") + +def handle_user_events(message): + print(f"User event: {message}") + +# Initialize Info instance with WebSocket support +info = Info(constants.TESTNET_API_URL) + +# Subscribe to different data streams +info.subscribe( + {"type": "l2Book", "coin": "ETH"}, + handle_orderbook +) + +info.subscribe( + {"type": "trades", "coin": "BTC"}, + handle_trades +) + +info.subscribe( + {"type": "userEvents", "user": wallet.address}, + handle_user_events +) + +# The WebSocket connection will remain active and process messages +# until the program exits or the connection is explicitly closed +``` + +#### Available Subscription Types +1. Market Data + +```python +# All mid prices +info.subscribe({"type": "allMids"}, callback) + +# L2 Order Book for specific asset +info.subscribe({"type": "l2Book", "coin": "ETH"}, callback) + +# Recent trades for specific asset +info.subscribe({"type": "trades", "coin": "BTC"}, callback) + +# Candlestick data +info.subscribe({ + "type": "candle", + "coin": "ETH", + "interval": "1m" # Available intervals: 1m, 5m, 15m, 1h, 4h, 1d +}, callback) +``` + +2. User +```python +# All user events (orders, fills, etc.) +info.subscribe({"type": "userEvents", "user": wallet.address}, callback) + +# User trade fills +info.subscribe({"type": "userFills", "user": wallet.address}, callback) + +# Order status updates +info.subscribe({"type": "orderUpdates", "user": wallet.address}, callback) + +# Funding payments +info.subscribe({"type": "userFundings", "user": wallet.address}, callback) + +# Non-funding ledger updates +info.subscribe({"type": "userNonFundingLedgerUpdates", "user": wallet.address}, callback) + +# Web data updates +info.subscribe({"type": "webData2", "user": wallet.address}, callback) +``` + +#### Message Formats +1. L2 Book + +```python +{ + "channel": "l2Book", + "data": [ + # Bids array + [ + {"px": "1900.5", "sz": "1.5", "n": 3}, # price, size, number of orders + # ... more bid levels + ], + # Asks array + [ + {"px": "1901.0", "sz": "2.1", "n": 2}, + # ... more ask levels + ] + ] +} +``` + +2. Trades +```python +{ + "channel": "trades", + "data": [ + { + "coin": "ETH", + "side": "A", # "A" for ask (sell), "B" for bid (buy) + "px": "1900.5", + "sz": "1.5", + "hash": "0x...", + "timestamp": 1234567890 + } + # ... more trades + ] +} +``` + +3. User +```python +{ + "channel": "userEvents", + "data": { + "type": "fill", # or "order", "cancel", etc. + "data": { + # Event specific data + "oid": 123, + "px": "1900.5", + "sz": "1.5", + # ... other fields + } + } +} +``` + +#### Websocket Management +The WebSocket connection is automatically managed by the SDK, but you can control it if needed: + +```python +# Initialize Info with WebSocket support +info = Info(constants.TESTNET_API_URL) + +# Access the WebSocket manager +ws_manager = info.ws_manager + +# Check connection status +is_connected = ws_manager.is_connected() + +# Manually reconnect if needed +ws_manager.reconnect() + +# Close WebSocket connection +ws_manager.close() +``` + +#### Error Handling in WebSocket Callbacks +```python +def safe_callback(message): + try: + # Process the message + print(f"Received: {message}") + + # Add your processing logic here + if message["channel"] == "l2Book": + bids, asks = message["data"] + # Process order book data + elif message["channel"] == "trades": + # Process trades data + pass + + except Exception as e: + print(f"Error processing message: {e}") + # Handle the error appropriately + +# Subscribe with error-handled callback +info.subscribe({"type": "l2Book", "coin": "ETH"}, safe_callback) +``` + +## Advanced Features + +### Vault/SubAccount Trading +```python +# Create Exchange instance with vault address +vault_exchange = Exchange(wallet, base_url, vault_address="vault_address") + +# Place order through vault +vault_exchange.order("ETH", True, 0.1, 1800, {"limit": {"tif": "Gtc"}}) +``` + +### Client Order ID (cloid) + +```python +from hyperliquid.utils.types import Cloid + +# Create CLOID +cloid = Cloid.from_str("0x00000000000000000000000000000001") + +# Place order with CLOID +exchange.order( + "ETH", + True, + 0.1, + 1800, + {"limit": {"tif": "Gtc"}}, + cloid=cloid +) + +# Query order by CLOID +order_status = info.query_order_by_cloid(wallet.address, cloid) +``` + +## Error Handling +The SDK uses custom error classes for better error handling: + +```python +from hyperliquid.utils.error import ClientError, ServerError + +try: + result = exchange.order(...) +except ClientError as e: + print(f"Client error: {e.error_message}") +except ServerError as e: + print(f"Server error: {e.message}") +``` + + ## Usage Examples + +Check out the [examples](examples) directory for more complete examples: +- Basic order placement and management +- Market making strategies +- WebSocket usage +- Vault trading +- Leverage adjustment +- Asset transfers + ```python from hyperliquid.info import Info from hyperliquid.utils import constants @@ -37,10 +351,16 @@ info = Info(constants.TESTNET_API_URL, skip_ws=True) user_state = info.user_state("0xcd5051944f780a621ee62e39e493c489668acf4d") print(user_state) ``` -See [examples](examples) for more complete examples. You can also checkout the repo and run any of the examples after configuring your private key e.g. + +You can also checkout the repo and run any of the examples after configuring your private key e.g. ```bash +# Create a copy of the config template cp examples/config.json.example examples/config.json + +# Update the config with your key vim examples/config.json + +# Run a basic order python examples/basic_order.py ``` From b687c04f433049b0706ee1d001fe16eb92053710 Mon Sep 17 00:00:00 2001 From: perplover <184728147+perplover@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:23:23 -0800 Subject: [PATCH 2/4] Add reference to the API documentation for full specs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 640bee4b..9e966ea5 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ exchange.cancel("ETH", order_id) ``` ### Websockets -The SDK provides real-time market data and user events through WebSocket connections. The WebSocket manager automatically handles connection maintenance and reconnection. +The SDK provides real-time market data and user events through WebSocket connections. The WebSocket manager automatically handles connection maintenance and reconnection. The full specs are available on the [documentation](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions). #### Basic Websockets Connection ```python From 9b5da54e63e98fb7609c4d8ba2babe08f05a4870 Mon Sep 17 00:00:00 2001 From: perplover <184728147+perplover@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:32:15 -0800 Subject: [PATCH 3/4] Add reference to the API documentation for Info and Exchange --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9e966ea5..2cc642fd 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ order_result = exchange.order( ### Info Class -The `Info` class provides methods to query market data and user information: +The `Info` class provides methods to query market data and user information. The full [API specs](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint) are available in the documentation. ```python from hyperliquid.info import Info @@ -80,7 +80,7 @@ mid_prices = info.all_mids() ### Exchange Class -The `Exchange` class handles all trading operations: +The `Exchange` class handles all trading operations. The full [API specs](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint) are available in the documentation. ```python from hyperliquid.exchange import Exchange From 6d0335100bc0b604650fe1c612b15ebdf1d9d2cd Mon Sep 17 00:00:00 2001 From: perplover <184728147+perplover@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:35:00 -0800 Subject: [PATCH 4/4] Fix spacing in comments --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2cc642fd..9229c1f7 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,8 @@ print(user_state) # Place a limit order order_result = exchange.order( - name="ETH", # Asset name - is_buy=True, # True for buy, False for sell + name="ETH", # Asset name + is_buy=True, # True for buy, False for sell sz=0.1, # Order size limit_px=1800, # Limit price order_type={"limit": {"tif": "Gtc"}} # Good-till-cancel order