hyperliquid 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A Ruby SDK for interacting with the Hyperliquid decentralized exchange API.
4
4
 
5
- The latest version is v0.2.0 - a read-only implementation focusing on the Info API endpoints for market data, user information, and order book data.
5
+ The SDK supports both read operations (Info API) and authenticated write operations (Exchange API) for trading.
6
6
 
7
7
  ## Installation
8
8
 
@@ -27,364 +27,40 @@ Or install it yourself as:
27
27
  ```ruby
28
28
  require 'hyperliquid'
29
29
 
30
- # Create SDK instance (mainnet by default)
30
+ # Create SDK instance for read-only operations (mainnet by default)
31
31
  sdk = Hyperliquid.new
32
32
 
33
33
  # Or use testnet
34
34
  testnet_sdk = Hyperliquid.new(testnet: true)
35
35
 
36
- # Access the Info API
36
+ # Access the Info API (read operations)
37
37
  info = sdk.info
38
- ```
39
-
40
- ### Supported APIs
41
-
42
- The SDK provides access to the following Hyperliquid APIs:
43
-
44
- #### Info Methods
45
- - `all_mids()` - Retrieve mids for all coins
46
- - `open_orders(user)` - Retrieve a user's open orders
47
- - `frontend_open_orders(user, dex: nil)` - Retrieve a user's open orders with additional frontend info
48
- - `user_fills(user)` - Retrieve a user's fills
49
- - `user_fills_by_time(user, start_time, end_time = nil)` - Retrieve a user's fills by time (optional end time)
50
- - `user_rate_limit(user)` - Query user rate limits
51
- - `order_status(user, oid)` - Query order status by order id (oid)
52
- - `order_status_by_cloid(user, cloid)` - Query order status by client order id (cloid)
53
- - `l2_book(coin)` - L2 book snapshot (Perpetuals and Spot)
54
- - `candles_snapshot(coin, interval, start_time, end_time)` - Candle snapshot (Perpetuals and Spot)
55
- - `max_builder_fee(user, builder)` - Check builder fee approval
56
- - `historical_orders(user, start_time = nil, end_time = nil)` - Retrieve a user's historical orders
57
- - `user_twap_slice_fills(user, start_time = nil, end_time = nil)` - Retrieve a user's TWAP slice fills
58
- - `user_subaccounts(user)` - Retrieve a user's subaccounts
59
- - `vault_details(vault_address, user = nil)` - Retrieve details for a vault
60
- - `user_vault_equities(user)` - Retrieve a user's vault deposits
61
- - `user_role(user)` - Query a user's role
62
- - `portfolio(user)` - Query a user's portfolio
63
- - `referral(user)` - Query a user's referral information
64
- - `user_fees(user)` - Query a user's fees and fee schedule
65
- - `delegations(user)` - Query a user's staking delegations
66
- - `delegator_summary(user)` - Query a user's staking summary
67
- - `delegator_history(user)` - Query a user's staking history
68
- - `delegator_rewards(user)` - Query a user's staking rewards
69
-
70
- ##### Perpetuals Methods
71
- - `perp_dexs()` - Retrieve all perpetual DEXs
72
- - `meta(dex: nil)` - Get asset metadata (optionally for a specific perp DEX)
73
- - `meta_and_asset_ctxs()` - Get extended asset metadata
74
- - `user_state(user, dex: nil)` - Retrieve user's perpetuals account summary (optionally for a specific perp DEX)
75
- - `predicted_fundings()` - Retrieve predicted funding rates across venues
76
- - `perps_at_open_interest_cap()` - Query perps at open interest caps
77
- - `perp_deploy_auction_status()` - Retrieve Perp Deploy Auction status
78
- - `active_asset_data(user, coin)` - Retrieve a user's active asset data for a coin
79
- - `perp_dex_limits(dex)` - Retrieve builder-deployed perp market limits for a DEX
80
- - `user_funding(user, start_time, end_time = nil)` - Retrieve a user's funding history (optional end time)
81
- - `user_non_funding_ledger_updates(user, start_time, end_time = nil)` - Retrieve a user's non-funding ledger updates. Non-funding ledger updates include deposits, transfers, and withdrawals. (optional end time)
82
- - `funding_history(coin, start_time, end_time = nil)` - Retrieve historical funding rates (optional end time)
83
-
84
- ##### Spot Methods
85
- - `spot_meta()` - Retrieve spot metadata (tokens and universe)
86
- - `spot_meta_and_asset_ctxs()` - Retrieve spot metadata and asset contexts
87
- - `spot_balances(user)` - Retrieve a user's spot token balances
88
- - `spot_deploy_state(user)` - Retrieve Spot Deploy Auction information
89
- - `spot_pair_deploy_auction_status()` - Retrieve Spot Pair Deploy Auction status
90
- - `token_details(token_id)` - Retrieve information about a token by tokenId
91
-
92
- #### Examples: Info
93
-
94
- ```ruby
95
- # Retrieve mids for all coins
96
- mids = sdk.info.all_mids
97
- # => { "BTC" => "50000", "ETH" => "3000", ... }
98
-
99
- user_address = "0x..."
100
-
101
- # Retrieve a user's open orders
102
- orders = sdk.info.open_orders(user_address)
103
- # => [{ "coin" => "BTC", "sz" => "0.1", "px" => "50000", "side" => "A" }]
104
-
105
- # Retrieve a user's open orders with additional frontend info
106
- frontend_orders = sdk.info.frontend_open_orders(user_address)
107
- # => [{ "coin" => "BTC", "isTrigger" => false, ... }]
108
-
109
- # Retrieve a user's fills
110
- fills = sdk.info.user_fills(user_address)
111
- # => [{ "coin" => "BTC", "sz" => "0.1", "px" => "50000", "side" => "A", "time" => 1234567890 }]
112
-
113
- # Retrieve a user's fills by time
114
- start_time_ms = 1_700_000_000_000
115
- end_time_ms = start_time_ms + 86_400_000
116
- fills_by_time = sdk.info.user_fills_by_time(user_address, start_time_ms, end_time_ms)
117
- # => [{ "coin" => "ETH", "px" => "3000", "time" => start_time_ms }, ...]
118
-
119
- # Query user rate limits
120
- rate_limit = sdk.info.user_rate_limit(user_address)
121
- # => { "nRequestsUsed" => 100, "nRequestsCap" => 10000 }
122
-
123
- # Query order status by oid
124
- order_id = 12345
125
- status_by_oid = sdk.info.order_status(user_address, order_id)
126
- # => { "status" => "filled", ... }
127
-
128
- # Query order status by cloid
129
- cloid = "client-order-id-123"
130
- status_by_cloid = sdk.info.order_status_by_cloid(user_address, cloid)
131
- # => { "status" => "cancelled", ... }
132
-
133
- # L2 order book snapshot
134
- book = sdk.info.l2_book("BTC")
135
- # => { "coin" => "BTC", "levels" => [[asks], [bids]], "time" => ... }
136
-
137
- # Candle snapshot
138
- candles = sdk.info.candles_snapshot("BTC", "1h", start_time_ms, end_time_ms)
139
- # => [{ "t" => ..., "o" => "50000", "h" => "51000", "l" => "49000", "c" => "50500", "v" => "100" }]
140
-
141
- # Check builder fee approval
142
- builder_address = "0x..."
143
- fee_approval = sdk.info.max_builder_fee(user_address, builder_address)
144
- # => { "approved" => true, ... }
145
-
146
- # Retrieve a user's historical orders
147
- hist_orders = sdk.info.historical_orders(user_address)
148
- # => [{ "oid" => 123, "coin" => "BTC", ... }]
149
- hist_orders_ranged = sdk.info.historical_orders(user_address, start_time_ms, end_time_ms)
150
- # => []
151
38
 
152
- # Retrieve a user's TWAP slice fills
153
- twap_fills = sdk.info.user_twap_slice_fills(user_address)
154
- # => [{ "sliceId" => 1, "coin" => "ETH", "sz" => "1.0" }, ...]
155
- twap_fills_ranged = sdk.info.user_twap_slice_fills(user_address, start_time_ms, end_time_ms)
156
- # => []
39
+ # For trading operations, provide a private key
40
+ trading_sdk = Hyperliquid.new(
41
+ testnet: true,
42
+ private_key: ENV['HYPERLIQUID_PRIVATE_KEY']
43
+ )
157
44
 
158
- # Retrieve a user's subaccounts
159
- subaccounts = sdk.info.user_subaccounts(user_address)
160
- # => ["0x1111...", ...]
161
-
162
- # Retrieve details for a vault
163
- vault_addr = "0x..."
164
- vault = sdk.info.vault_details(vault_addr)
165
- # => { "vaultAddress" => vault_addr, ... }
166
- vault_with_user = sdk.info.vault_details(vault_addr, user_address)
167
- # => { "vaultAddress" => vault_addr, "user" => user_address, ... }
168
-
169
- # Retrieve a user's vault deposits
170
- vault_deposits = sdk.info.user_vault_equities(user_address)
171
- # => [{ "vaultAddress" => "0x...", "equity" => "123.45" }, ...]
172
-
173
- # Query a user's role
174
- role = sdk.info.user_role(user_address)
175
- # => { "role" => "tradingUser" }
176
-
177
- # Query a user's portfolio
178
- portfolio = sdk.info.portfolio(user_address)
179
- # => [["day", { "pnlHistory" => [...], "vlm" => "0.0" }], ...]
180
-
181
- # Query a user's referral information
182
- referral = sdk.info.referral(user_address)
183
- # => { "referredBy" => { "referrer" => "0x..." }, ... }
184
-
185
- # Query a user's fees
186
- fees = sdk.info.user_fees(user_address)
187
- # => { "userAddRate" => "0.0001", "feeSchedule" => { ... } }
188
-
189
- # Query a user's staking delegations
190
- delegations = sdk.info.delegations(user_address)
191
- # => [{ "validator" => "0x...", "amount" => "100.0" }, ...]
192
-
193
- # Query a user's staking summary
194
- summary = sdk.info.delegator_summary(user_address)
195
- # => { "delegated" => "12060.16529862", ... }
196
-
197
- # Query a user's staking history
198
- history = sdk.info.delegator_history(user_address)
199
- # => [{ "time" => 1_736_726_400_073, "delta" => { ... } }, ...]
200
-
201
- # Query a user's staking rewards
202
- rewards = sdk.info.delegator_rewards(user_address)
203
- # => [{ "time" => 1_736_726_400_073, "source" => "delegation", "totalAmount" => "0.123" }, ...]
45
+ # Access the Exchange API (write operations)
46
+ exchange = trading_sdk.exchange
204
47
  ```
205
48
 
206
- Note: `l2_book` and `candles_snapshot` work for both Perpetuals and Spot. For spot, use `"{BASE}/USDC"` when available (e.g., `"PURR/USDC"`). Otherwise, use the index alias `"@{index}"` from `spot_meta["universe"]`.
207
-
208
- ##### Examples: Perpetuals
209
-
210
- ```ruby
211
- # Retrieve all perpetual DEXs
212
- perp_dexs = sdk.info.perp_dexs
213
- # => [nil, { "name" => "test", "full_name" => "test dex", ... }]
214
-
215
- # Retrieve perpetuals metadata (optionally for a specific perp dex)
216
- meta = sdk.info.meta
217
- # => { "universe" => [...] }
218
- meta = sdk.info.meta(dex: "perp-dex-name")
219
- # => { "universe" => [...] }
220
-
221
- # Retrieve perpetuals asset contexts (includes mark price, current funding, open interest, etc.)
222
- meta_ctxs = sdk.info.meta_and_asset_ctxs
223
- # => { "universe" => [...], "assetCtxs" => [...] }
224
-
225
- # Retrieve user's perpetuals account summary (optionally for a specific perp dex)
226
- state = sdk.info.user_state(user_address)
227
- # => { "assetPositions" => [...], "marginSummary" => {...} }
228
- state = sdk.info.user_state(user_address, dex: "perp-dex-name")
229
- # => { "assetPositions" => [...], "marginSummary" => {...} }
230
-
231
- # Retrieve a user's funding history or non-funding ledger updates (optional end_time)
232
- funding = sdk.info.user_funding(user_address, start_time)
233
- # => [{ "delta" => { "type" => "funding", ... }, "time" => ... }]
234
- funding = sdk.info.user_funding(user_address, start_time, end_time)
235
- # => [{ "delta" => { "type" => "funding", ... }, "time" => ... }]
236
-
237
- # Retrieve historical funding rates
238
- hist = sdk.info.funding_history("ETH", start_time)
239
- # => [{ "coin" => "ETH", "fundingRate" => "...", "time" => ... }]
240
-
241
- # Retrieve predicted funding rates for different venues
242
- pred = sdk.info.predicted_fundings
243
- # => [["AVAX", [["HlPerp", { "fundingRate" => "0.0000125", "nextFundingTime" => ... }], ...]], ...]
244
-
245
- # Query perps at open interest caps
246
- oi_capped = sdk.info.perps_at_open_interest_cap
247
- # => ["BADGER", "CANTO", ...]
49
+ ### Documentation
248
50
 
249
- # Retrieve information about the Perp Deploy Auction
250
- auction = sdk.info.perp_deploy_auction_status
251
- # => { "startTimeSeconds" => ..., "durationSeconds" => ..., "startGas" => "500.0", ... }
252
-
253
- # Retrieve User's Active Asset Data
254
- aad = sdk.info.active_asset_data(user_address, "APT")
255
- # => { "user" => user_address, "coin" => "APT", "leverage" => { "type" => "cross", "value" => 3 }, ... }
256
-
257
- # Retrieve Builder-Deployed Perp Market Limits
258
- limits = sdk.info.perp_dex_limits("builder-dex")
259
- # => { "totalOiCap" => "10000000.0", "oiSzCapPerPerp" => "...", ... }
260
- ```
261
-
262
- ##### Examples: Spot
263
-
264
- ```ruby
265
- # Retrieve spot metadata
266
- spot_meta = sdk.info.spot_meta
267
- # => { "tokens" => [...], "universe" => [...] }
268
-
269
- # Retrieve spot asset contexts
270
- spot_meta_ctxs = sdk.info.spot_meta_and_asset_ctxs
271
- # => [ { "tokens" => [...], "universe" => [...] }, [ { "midPx" => "...", ... } ] ]
272
-
273
- # Retrieve a user's token balances
274
- balances = sdk.info.spot_balances(user_address)
275
- # => { "balances" => [{ "coin" => "USDC", "token" => 0, "total" => "..." }, ...] }
276
-
277
- # Retrieve information about the Spot Deploy Auction
278
- deploy_state = sdk.info.spot_deploy_state(user_address)
279
- # => { "states" => [...], "gasAuction" => { ... } }
280
-
281
- # Retrieve information about the Spot Pair Deploy Auction
282
- pair_status = sdk.info.spot_pair_deploy_auction_status
283
- # => { "startTimeSeconds" => ..., "durationSeconds" => ..., "startGas" => "...", ... }
284
-
285
- # Retrieve information about a token by onchain id in 34-character hexadecimal format
286
- details = sdk.info.token_details("0x00000000000000000000000000000000")
287
- # => { "name" => "TEST", "maxSupply" => "...", "midPx" => "...", ... }
288
- ```
289
-
290
- ### Configuration
291
-
292
- ```ruby
293
- # Custom timeout (default: 30 seconds)
294
- sdk = Hyperliquid.new(timeout: 60)
295
-
296
- # Enable retry logic for handling transient failures (default: disabled)
297
- sdk = Hyperliquid.new(retry_enabled: true)
298
-
299
- # Combine multiple configuration options
300
- sdk = Hyperliquid.new(testnet: true, timeout: 60, retry_enabled: true)
301
-
302
- # Check which environment you're using
303
- sdk.testnet? # => false
304
- sdk.base_url # => "https://api.hyperliquid.xyz"
305
- ```
306
-
307
- #### Retry Configuration
308
-
309
- By default, retry logic is **disabled** for predictable API behavior. When enabled, the SDK will automatically retry requests that fail due to:
310
-
311
- - Network connectivity issues (connection failed, timeouts)
312
- - Server errors (5xx status codes)
313
- - Rate limiting (429 status codes)
314
-
315
- **Retry Settings:**
316
- - Maximum retries: 2
317
- - Base interval: 0.5 seconds
318
- - Backoff factor: 2x (exponential backoff)
319
- - Randomness: ±50% to prevent thundering herd
320
-
321
- **Note:** Retries are disabled by default to avoid unexpected delays in time-sensitive trading applications. Enable only when you want automatic handling of transient failures.
322
-
323
- ### Error Handling
324
-
325
- The SDK provides comprehensive error handling:
326
-
327
- ```ruby
328
- begin
329
- orders = sdk.info.open_orders(user_address)
330
- rescue Hyperliquid::AuthenticationError
331
- # Handle authentication issues
332
- rescue Hyperliquid::RateLimitError
333
- # Handle rate limiting
334
- rescue Hyperliquid::ServerError
335
- # Handle server errors
336
- rescue Hyperliquid::NetworkError
337
- # Handle network connectivity issues
338
- rescue Hyperliquid::Error => e
339
- # Handle any other Hyperliquid API errors
340
- puts "Error: #{e.message}"
341
- puts "Status: #{e.status_code}" if e.status_code
342
- puts "Response: #{e.response_body}" if e.response_body
343
- end
344
- ```
345
-
346
- Available error classes:
347
- - `Hyperliquid::Error` - Base error class
348
- - `Hyperliquid::ClientError` - 4xx errors
349
- - `Hyperliquid::ServerError` - 5xx errors
350
- - `Hyperliquid::AuthenticationError` - 401 errors
351
- - `Hyperliquid::BadRequestError` - 400 errors
352
- - `Hyperliquid::NotFoundError` - 404 errors
353
- - `Hyperliquid::RateLimitError` - 429 errors
354
- - `Hyperliquid::NetworkError` - Connection issues
355
- - `Hyperliquid::TimeoutError` - Request timeouts
356
-
357
- ## Development
358
-
359
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
360
-
361
- Run the example:
362
- ```bash
363
- ruby example.rb
364
- ```
365
-
366
- Run tests:
367
- ```bash
368
- rake spec
369
- ```
370
-
371
- Run tests and linting together:
372
- ```bash
373
- rake
374
- ```
375
-
376
- Run linting:
377
- ```bash
378
- rake rubocop
379
- ```
51
+ - [API Reference](docs/API.md) - Complete list of available methods
52
+ - [Examples](docs/EXAMPLES.md) - Code examples for Info and Exchange APIs
53
+ - [Configuration](docs/CONFIGURATION.md) - SDK configuration options
54
+ - [Error Handling](docs/ERRORS.md) - Error types and handling
55
+ - [Development](docs/DEVELOPMENT.md) - Contributing and running tests
380
56
 
381
57
  ## Roadmap
382
58
 
383
- The latest version implements read-only Info API support. Future versions will include:
59
+ The SDK now supports both Info API (read) and Exchange API (trading). Future versions will include:
384
60
 
385
- - Trading API (place orders, cancel orders, etc.)
386
61
  - WebSocket support for real-time data
387
- - Advanced trading features
62
+ - Additional exchange operations (leverage, margin adjustments, transfers)
63
+ - Advanced trading features (TWAP, etc.)
388
64
 
389
65
  ## Contributing
390
66
 
data/docs/API.md ADDED
@@ -0,0 +1,95 @@
1
+ # API Reference
2
+
3
+ ## Info Methods
4
+
5
+ Read-only methods for querying market data and user information.
6
+
7
+ ### General Info
8
+
9
+ - `all_mids()` - Retrieve mids for all coins
10
+ - `open_orders(user)` - Retrieve a user's open orders
11
+ - `frontend_open_orders(user, dex: nil)` - Retrieve a user's open orders with additional frontend info
12
+ - `user_fills(user)` - Retrieve a user's fills
13
+ - `user_fills_by_time(user, start_time, end_time = nil)` - Retrieve a user's fills by time (optional end time)
14
+ - `user_rate_limit(user)` - Query user rate limits
15
+ - `order_status(user, oid)` - Query order status by order id (oid)
16
+ - `order_status_by_cloid(user, cloid)` - Query order status by client order id (cloid)
17
+ - `l2_book(coin)` - L2 book snapshot (Perpetuals and Spot)
18
+ - `candles_snapshot(coin, interval, start_time, end_time)` - Candle snapshot (Perpetuals and Spot)
19
+ - `max_builder_fee(user, builder)` - Check builder fee approval
20
+ - `historical_orders(user, start_time = nil, end_time = nil)` - Retrieve a user's historical orders
21
+ - `user_twap_slice_fills(user, start_time = nil, end_time = nil)` - Retrieve a user's TWAP slice fills
22
+ - `user_subaccounts(user)` - Retrieve a user's subaccounts
23
+ - `vault_details(vault_address, user = nil)` - Retrieve details for a vault
24
+ - `user_vault_equities(user)` - Retrieve a user's vault deposits
25
+ - `user_role(user)` - Query a user's role
26
+ - `portfolio(user)` - Query a user's portfolio
27
+ - `referral(user)` - Query a user's referral information
28
+ - `user_fees(user)` - Query a user's fees and fee schedule
29
+ - `delegations(user)` - Query a user's staking delegations
30
+ - `delegator_summary(user)` - Query a user's staking summary
31
+ - `delegator_history(user)` - Query a user's staking history
32
+ - `delegator_rewards(user)` - Query a user's staking rewards
33
+
34
+ ### Perpetuals Methods
35
+
36
+ - `perp_dexs()` - Retrieve all perpetual DEXs
37
+ - `meta(dex: nil)` - Get asset metadata (optionally for a specific perp DEX)
38
+ - `meta_and_asset_ctxs()` - Get extended asset metadata
39
+ - `user_state(user, dex: nil)` - Retrieve user's perpetuals account summary (optionally for a specific perp DEX)
40
+ - `predicted_fundings()` - Retrieve predicted funding rates across venues
41
+ - `perps_at_open_interest_cap()` - Query perps at open interest caps
42
+ - `perp_deploy_auction_status()` - Retrieve Perp Deploy Auction status
43
+ - `active_asset_data(user, coin)` - Retrieve a user's active asset data for a coin
44
+ - `perp_dex_limits(dex)` - Retrieve builder-deployed perp market limits for a DEX
45
+ - `user_funding(user, start_time, end_time = nil)` - Retrieve a user's funding history (optional end time)
46
+ - `user_non_funding_ledger_updates(user, start_time, end_time = nil)` - Retrieve a user's non-funding ledger updates. Non-funding ledger updates include deposits, transfers, and withdrawals. (optional end time)
47
+ - `funding_history(coin, start_time, end_time = nil)` - Retrieve historical funding rates (optional end time)
48
+
49
+ ### Spot Methods
50
+
51
+ - `spot_meta()` - Retrieve spot metadata (tokens and universe)
52
+ - `spot_meta_and_asset_ctxs()` - Retrieve spot metadata and asset contexts
53
+ - `spot_balances(user)` - Retrieve a user's spot token balances
54
+ - `spot_deploy_state(user)` - Retrieve Spot Deploy Auction information
55
+ - `spot_pair_deploy_auction_status()` - Retrieve Spot Pair Deploy Auction status
56
+ - `token_details(token_id)` - Retrieve information about a token by tokenId
57
+
58
+ ## Exchange Methods (Trading)
59
+
60
+ **Note:** Exchange methods require initializing the SDK with a `private_key`.
61
+
62
+ - `order(coin:, is_buy:, size:, limit_px:, ...)` - Place a single limit order
63
+ - `bulk_orders(orders:, grouping:, ...)` - Place multiple orders in a batch
64
+ - `market_order(coin:, is_buy:, size:, slippage:, ...)` - Place a market order with slippage
65
+ - `cancel(coin:, oid:, ...)` - Cancel an order by order ID
66
+ - `cancel_by_cloid(coin:, cloid:, ...)` - Cancel an order by client order ID
67
+ - `bulk_cancel(cancels:, ...)` - Cancel multiple orders by order ID
68
+ - `bulk_cancel_by_cloid(cancels:, ...)` - Cancel multiple orders by client order ID
69
+ - `address` - Get the wallet address associated with the private key
70
+
71
+ All exchange methods support an optional `vault_address:` parameter for vault trading.
72
+
73
+ ### Order Types
74
+
75
+ - `{ limit: { tif: 'Gtc' } }` - Good-til-canceled (default)
76
+ - `{ limit: { tif: 'Ioc' } }` - Immediate-or-cancel
77
+ - `{ limit: { tif: 'Alo' } }` - Add-liquidity-only (post-only)
78
+
79
+ ### Trigger Orders (Stop Loss / Take Profit)
80
+
81
+ Trigger orders execute when a price threshold is reached:
82
+
83
+ - `tpsl: 'sl'` - Stop loss
84
+ - `tpsl: 'tp'` - Take profit
85
+ - `is_market: true/false` - Execute as market or limit order when triggered
86
+
87
+ ### Client Order IDs (Cloid)
88
+
89
+ Client order IDs must be 16 bytes in hex format (`0x` + 32 hex characters).
90
+
91
+ Factory methods:
92
+ - `Hyperliquid::Cloid.from_int(n)` - Create from integer (zero-padded)
93
+ - `Hyperliquid::Cloid.from_str(s)` - Create from hex string
94
+ - `Hyperliquid::Cloid.from_uuid(uuid)` - Create from UUID
95
+ - `Hyperliquid::Cloid.random` - Generate random
@@ -0,0 +1,53 @@
1
+ # Configuration
2
+
3
+ ## Basic Options
4
+
5
+ ```ruby
6
+ # Custom timeout (default: 30 seconds)
7
+ sdk = Hyperliquid.new(timeout: 60)
8
+
9
+ # Enable retry logic for handling transient failures (default: disabled)
10
+ sdk = Hyperliquid.new(retry_enabled: true)
11
+
12
+ # Enable trading with a private key
13
+ sdk = Hyperliquid.new(private_key: ENV['HYPERLIQUID_PRIVATE_KEY'])
14
+
15
+ # Set global order expiration (orders expire after this timestamp)
16
+ expires_at_ms = (Time.now.to_f * 1000).to_i + 30_000 # 30 seconds from now
17
+ sdk = Hyperliquid.new(
18
+ private_key: ENV['HYPERLIQUID_PRIVATE_KEY'],
19
+ expires_after: expires_at_ms
20
+ )
21
+
22
+ # Combine multiple configuration options
23
+ sdk = Hyperliquid.new(
24
+ testnet: true,
25
+ timeout: 60,
26
+ retry_enabled: true,
27
+ private_key: ENV['HYPERLIQUID_PRIVATE_KEY'],
28
+ expires_after: expires_at_ms
29
+ )
30
+
31
+ # Check which environment you're using
32
+ sdk.testnet? # => false
33
+ sdk.base_url # => "https://api.hyperliquid.xyz"
34
+
35
+ # Check if exchange is available (private_key was provided)
36
+ sdk.exchange # => nil if no private_key, Hyperliquid::Exchange instance otherwise
37
+ ```
38
+
39
+ ## Retry Configuration
40
+
41
+ By default, retry logic is **disabled** for predictable API behavior. When enabled, the SDK will automatically retry requests that fail due to:
42
+
43
+ - Network connectivity issues (connection failed, timeouts)
44
+ - Server errors (5xx status codes)
45
+ - Rate limiting (429 status codes)
46
+
47
+ **Retry Settings:**
48
+ - Maximum retries: 2
49
+ - Base interval: 0.5 seconds
50
+ - Backoff factor: 2x (exponential backoff)
51
+ - Randomness: ±50% to prevent thundering herd
52
+
53
+ **Note:** Retries are disabled by default to avoid unexpected delays in time-sensitive trading applications. Enable only when you want automatic handling of transient failures.
@@ -0,0 +1,54 @@
1
+ # Development
2
+
3
+ ## Setup
4
+
5
+ After checking out the repo, run `bin/setup` to install dependencies.
6
+
7
+ ```bash
8
+ bin/setup
9
+ ```
10
+
11
+ ## Running Tests
12
+
13
+ ```bash
14
+ # Run all tests
15
+ rake spec
16
+
17
+ # Run tests and linting together (default)
18
+ rake
19
+ ```
20
+
21
+ ## Linting
22
+
23
+ ```bash
24
+ rake rubocop
25
+ ```
26
+
27
+ ## Interactive Console
28
+
29
+ ```bash
30
+ bin/console
31
+ ```
32
+
33
+ This opens an interactive prompt with the SDK loaded for experimentation.
34
+
35
+ ## Example Script
36
+
37
+ ```bash
38
+ ruby example.rb
39
+ ```
40
+
41
+ ## Integration Testing (Testnet)
42
+
43
+ For real trading tests on testnet:
44
+
45
+ ```bash
46
+ # Get testnet funds from: https://app.hyperliquid-testnet.xyz
47
+ HYPERLIQUID_PRIVATE_KEY=0x... ruby test_integration.rb
48
+ ```
49
+
50
+ The integration test executes real trades on testnet:
51
+ 1. Spot market roundtrip (buy/sell PURR/USDC)
52
+ 2. Spot limit order (place and cancel)
53
+ 3. Perp market roundtrip (long/close BTC)
54
+ 4. Perp limit order (place short, cancel)
data/docs/ERRORS.md ADDED
@@ -0,0 +1,38 @@
1
+ # Error Handling
2
+
3
+ The SDK provides comprehensive error handling with typed exceptions.
4
+
5
+ ## Usage
6
+
7
+ ```ruby
8
+ begin
9
+ orders = sdk.info.open_orders(user_address)
10
+ rescue Hyperliquid::AuthenticationError
11
+ # Handle authentication issues
12
+ rescue Hyperliquid::RateLimitError
13
+ # Handle rate limiting
14
+ rescue Hyperliquid::ServerError
15
+ # Handle server errors
16
+ rescue Hyperliquid::NetworkError
17
+ # Handle network connectivity issues
18
+ rescue Hyperliquid::Error => e
19
+ # Handle any other Hyperliquid API errors
20
+ puts "Error: #{e.message}"
21
+ puts "Status: #{e.status_code}" if e.status_code
22
+ puts "Response: #{e.response_body}" if e.response_body
23
+ end
24
+ ```
25
+
26
+ ## Error Classes
27
+
28
+ | Error Class | Description |
29
+ |-------------|-------------|
30
+ | `Hyperliquid::Error` | Base error class |
31
+ | `Hyperliquid::ClientError` | 4xx errors |
32
+ | `Hyperliquid::ServerError` | 5xx errors |
33
+ | `Hyperliquid::AuthenticationError` | 401 errors |
34
+ | `Hyperliquid::BadRequestError` | 400 errors |
35
+ | `Hyperliquid::NotFoundError` | 404 errors |
36
+ | `Hyperliquid::RateLimitError` | 429 errors |
37
+ | `Hyperliquid::NetworkError` | Connection issues |
38
+ | `Hyperliquid::TimeoutError` | Request timeouts |