hyperliquid 0.2.0 → 0.4.0

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,64 +27,422 @@ 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
38
 
40
- ### Info API Methods
39
+ # For trading operations, provide a private key
40
+ trading_sdk = Hyperliquid.new(
41
+ testnet: true,
42
+ private_key: ENV['HYPERLIQUID_PRIVATE_KEY']
43
+ )
41
44
 
42
- The SDK provides access to all Hyperliquid Info API endpoints:
45
+ # Access the Exchange API (write operations)
46
+ exchange = trading_sdk.exchange
47
+ ```
43
48
 
44
- #### Market Data
49
+ ### Supported APIs
50
+
51
+ The SDK provides access to the following Hyperliquid APIs:
52
+
53
+ #### Info Methods
54
+ - `all_mids()` - Retrieve mids for all coins
55
+ - `open_orders(user)` - Retrieve a user's open orders
56
+ - `frontend_open_orders(user, dex: nil)` - Retrieve a user's open orders with additional frontend info
57
+ - `user_fills(user)` - Retrieve a user's fills
58
+ - `user_fills_by_time(user, start_time, end_time = nil)` - Retrieve a user's fills by time (optional end time)
59
+ - `user_rate_limit(user)` - Query user rate limits
60
+ - `order_status(user, oid)` - Query order status by order id (oid)
61
+ - `order_status_by_cloid(user, cloid)` - Query order status by client order id (cloid)
62
+ - `l2_book(coin)` - L2 book snapshot (Perpetuals and Spot)
63
+ - `candles_snapshot(coin, interval, start_time, end_time)` - Candle snapshot (Perpetuals and Spot)
64
+ - `max_builder_fee(user, builder)` - Check builder fee approval
65
+ - `historical_orders(user, start_time = nil, end_time = nil)` - Retrieve a user's historical orders
66
+ - `user_twap_slice_fills(user, start_time = nil, end_time = nil)` - Retrieve a user's TWAP slice fills
67
+ - `user_subaccounts(user)` - Retrieve a user's subaccounts
68
+ - `vault_details(vault_address, user = nil)` - Retrieve details for a vault
69
+ - `user_vault_equities(user)` - Retrieve a user's vault deposits
70
+ - `user_role(user)` - Query a user's role
71
+ - `portfolio(user)` - Query a user's portfolio
72
+ - `referral(user)` - Query a user's referral information
73
+ - `user_fees(user)` - Query a user's fees and fee schedule
74
+ - `delegations(user)` - Query a user's staking delegations
75
+ - `delegator_summary(user)` - Query a user's staking summary
76
+ - `delegator_history(user)` - Query a user's staking history
77
+ - `delegator_rewards(user)` - Query a user's staking rewards
78
+
79
+ ##### Perpetuals Methods
80
+ - `perp_dexs()` - Retrieve all perpetual DEXs
81
+ - `meta(dex: nil)` - Get asset metadata (optionally for a specific perp DEX)
82
+ - `meta_and_asset_ctxs()` - Get extended asset metadata
83
+ - `user_state(user, dex: nil)` - Retrieve user's perpetuals account summary (optionally for a specific perp DEX)
84
+ - `predicted_fundings()` - Retrieve predicted funding rates across venues
85
+ - `perps_at_open_interest_cap()` - Query perps at open interest caps
86
+ - `perp_deploy_auction_status()` - Retrieve Perp Deploy Auction status
87
+ - `active_asset_data(user, coin)` - Retrieve a user's active asset data for a coin
88
+ - `perp_dex_limits(dex)` - Retrieve builder-deployed perp market limits for a DEX
89
+ - `user_funding(user, start_time, end_time = nil)` - Retrieve a user's funding history (optional end time)
90
+ - `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)
91
+ - `funding_history(coin, start_time, end_time = nil)` - Retrieve historical funding rates (optional end time)
92
+
93
+ ##### Spot Methods
94
+ - `spot_meta()` - Retrieve spot metadata (tokens and universe)
95
+ - `spot_meta_and_asset_ctxs()` - Retrieve spot metadata and asset contexts
96
+ - `spot_balances(user)` - Retrieve a user's spot token balances
97
+ - `spot_deploy_state(user)` - Retrieve Spot Deploy Auction information
98
+ - `spot_pair_deploy_auction_status()` - Retrieve Spot Pair Deploy Auction status
99
+ - `token_details(token_id)` - Retrieve information about a token by tokenId
100
+
101
+ #### Examples: Info
45
102
 
46
103
  ```ruby
47
- # Get all market mid prices
104
+ # Retrieve mids for all coins
48
105
  mids = sdk.info.all_mids
49
106
  # => { "BTC" => "50000", "ETH" => "3000", ... }
50
107
 
51
- # Get asset metadata
52
- meta = sdk.info.meta
53
- # => { "universe" => [...] }
108
+ user_address = "0x..."
54
109
 
55
- # Get extended asset metadata with contexts
56
- meta_ctxs = sdk.info.meta_and_asset_ctxs
57
- # => { "universe" => [...], "assetCtxs" => [...] }
110
+ # Retrieve a user's open orders
111
+ orders = sdk.info.open_orders(user_address)
112
+ # => [{ "coin" => "BTC", "sz" => "0.1", "px" => "50000", "side" => "A" }]
113
+
114
+ # Retrieve a user's open orders with additional frontend info
115
+ frontend_orders = sdk.info.frontend_open_orders(user_address)
116
+ # => [{ "coin" => "BTC", "isTrigger" => false, ... }]
58
117
 
59
- # Get L2 order book for a coin
118
+ # Retrieve a user's fills
119
+ fills = sdk.info.user_fills(user_address)
120
+ # => [{ "coin" => "BTC", "sz" => "0.1", "px" => "50000", "side" => "A", "time" => 1234567890 }]
121
+
122
+ # Retrieve a user's fills by time
123
+ start_time_ms = 1_700_000_000_000
124
+ end_time_ms = start_time_ms + 86_400_000
125
+ fills_by_time = sdk.info.user_fills_by_time(user_address, start_time_ms, end_time_ms)
126
+ # => [{ "coin" => "ETH", "px" => "3000", "time" => start_time_ms }, ...]
127
+
128
+ # Query user rate limits
129
+ rate_limit = sdk.info.user_rate_limit(user_address)
130
+ # => { "nRequestsUsed" => 100, "nRequestsCap" => 10000 }
131
+
132
+ # Query order status by oid
133
+ order_id = 12345
134
+ status_by_oid = sdk.info.order_status(user_address, order_id)
135
+ # => { "status" => "filled", ... }
136
+
137
+ # Query order status by cloid
138
+ cloid = "client-order-id-123"
139
+ status_by_cloid = sdk.info.order_status_by_cloid(user_address, cloid)
140
+ # => { "status" => "cancelled", ... }
141
+
142
+ # L2 order book snapshot
60
143
  book = sdk.info.l2_book("BTC")
61
144
  # => { "coin" => "BTC", "levels" => [[asks], [bids]], "time" => ... }
62
145
 
63
- # Get candlestick data
64
- candles = sdk.info.candles_snapshot("BTC", "1h", start_time, end_time)
146
+ # Candle snapshot
147
+ candles = sdk.info.candles_snapshot("BTC", "1h", start_time_ms, end_time_ms)
65
148
  # => [{ "t" => ..., "o" => "50000", "h" => "51000", "l" => "49000", "c" => "50500", "v" => "100" }]
149
+
150
+ # Check builder fee approval
151
+ builder_address = "0x..."
152
+ fee_approval = sdk.info.max_builder_fee(user_address, builder_address)
153
+ # => { "approved" => true, ... }
154
+
155
+ # Retrieve a user's historical orders
156
+ hist_orders = sdk.info.historical_orders(user_address)
157
+ # => [{ "oid" => 123, "coin" => "BTC", ... }]
158
+ hist_orders_ranged = sdk.info.historical_orders(user_address, start_time_ms, end_time_ms)
159
+ # => []
160
+
161
+ # Retrieve a user's TWAP slice fills
162
+ twap_fills = sdk.info.user_twap_slice_fills(user_address)
163
+ # => [{ "sliceId" => 1, "coin" => "ETH", "sz" => "1.0" }, ...]
164
+ twap_fills_ranged = sdk.info.user_twap_slice_fills(user_address, start_time_ms, end_time_ms)
165
+ # => []
166
+
167
+ # Retrieve a user's subaccounts
168
+ subaccounts = sdk.info.user_subaccounts(user_address)
169
+ # => ["0x1111...", ...]
170
+
171
+ # Retrieve details for a vault
172
+ vault_addr = "0x..."
173
+ vault = sdk.info.vault_details(vault_addr)
174
+ # => { "vaultAddress" => vault_addr, ... }
175
+ vault_with_user = sdk.info.vault_details(vault_addr, user_address)
176
+ # => { "vaultAddress" => vault_addr, "user" => user_address, ... }
177
+
178
+ # Retrieve a user's vault deposits
179
+ vault_deposits = sdk.info.user_vault_equities(user_address)
180
+ # => [{ "vaultAddress" => "0x...", "equity" => "123.45" }, ...]
181
+
182
+ # Query a user's role
183
+ role = sdk.info.user_role(user_address)
184
+ # => { "role" => "tradingUser" }
185
+
186
+ # Query a user's portfolio
187
+ portfolio = sdk.info.portfolio(user_address)
188
+ # => [["day", { "pnlHistory" => [...], "vlm" => "0.0" }], ...]
189
+
190
+ # Query a user's referral information
191
+ referral = sdk.info.referral(user_address)
192
+ # => { "referredBy" => { "referrer" => "0x..." }, ... }
193
+
194
+ # Query a user's fees
195
+ fees = sdk.info.user_fees(user_address)
196
+ # => { "userAddRate" => "0.0001", "feeSchedule" => { ... } }
197
+
198
+ # Query a user's staking delegations
199
+ delegations = sdk.info.delegations(user_address)
200
+ # => [{ "validator" => "0x...", "amount" => "100.0" }, ...]
201
+
202
+ # Query a user's staking summary
203
+ summary = sdk.info.delegator_summary(user_address)
204
+ # => { "delegated" => "12060.16529862", ... }
205
+
206
+ # Query a user's staking history
207
+ history = sdk.info.delegator_history(user_address)
208
+ # => [{ "time" => 1_736_726_400_073, "delta" => { ... } }, ...]
209
+
210
+ # Query a user's staking rewards
211
+ rewards = sdk.info.delegator_rewards(user_address)
212
+ # => [{ "time" => 1_736_726_400_073, "source" => "delegation", "totalAmount" => "0.123" }, ...]
66
213
  ```
67
214
 
68
- #### User Data
215
+ 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"]`.
216
+
217
+ ##### Examples: Perpetuals
69
218
 
70
219
  ```ruby
71
- user_address = "0x..." # Wallet address
220
+ # Retrieve all perpetual DEXs
221
+ perp_dexs = sdk.info.perp_dexs
222
+ # => [nil, { "name" => "test", "full_name" => "test dex", ... }]
72
223
 
73
- # Get user's open orders
74
- orders = sdk.info.open_orders(user_address)
75
- # => [{ "coin" => "BTC", "sz" => "0.1", "px" => "50000", "side" => "A" }]
224
+ # Retrieve perpetuals metadata (optionally for a specific perp dex)
225
+ meta = sdk.info.meta
226
+ # => { "universe" => [...] }
227
+ meta = sdk.info.meta(dex: "perp-dex-name")
228
+ # => { "universe" => [...] }
76
229
 
77
- # Get user's fill history
78
- fills = sdk.info.user_fills(user_address)
79
- # => [{ "coin" => "BTC", "sz" => "0.1", "px" => "50000", "side" => "A", "time" => 1234567890 }]
230
+ # Retrieve perpetuals asset contexts (includes mark price, current funding, open interest, etc.)
231
+ meta_ctxs = sdk.info.meta_and_asset_ctxs
232
+ # => { "universe" => [...], "assetCtxs" => [...] }
80
233
 
81
- # Get user's trading state (positions, balances)
234
+ # Retrieve user's perpetuals account summary (optionally for a specific perp dex)
82
235
  state = sdk.info.user_state(user_address)
83
236
  # => { "assetPositions" => [...], "marginSummary" => {...} }
237
+ state = sdk.info.user_state(user_address, dex: "perp-dex-name")
238
+ # => { "assetPositions" => [...], "marginSummary" => {...} }
239
+
240
+ # Retrieve a user's funding history or non-funding ledger updates (optional end_time)
241
+ funding = sdk.info.user_funding(user_address, start_time)
242
+ # => [{ "delta" => { "type" => "funding", ... }, "time" => ... }]
243
+ funding = sdk.info.user_funding(user_address, start_time, end_time)
244
+ # => [{ "delta" => { "type" => "funding", ... }, "time" => ... }]
245
+
246
+ # Retrieve historical funding rates
247
+ hist = sdk.info.funding_history("ETH", start_time)
248
+ # => [{ "coin" => "ETH", "fundingRate" => "...", "time" => ... }]
249
+
250
+ # Retrieve predicted funding rates for different venues
251
+ pred = sdk.info.predicted_fundings
252
+ # => [["AVAX", [["HlPerp", { "fundingRate" => "0.0000125", "nextFundingTime" => ... }], ...]], ...]
253
+
254
+ # Query perps at open interest caps
255
+ oi_capped = sdk.info.perps_at_open_interest_cap
256
+ # => ["BADGER", "CANTO", ...]
257
+
258
+ # Retrieve information about the Perp Deploy Auction
259
+ auction = sdk.info.perp_deploy_auction_status
260
+ # => { "startTimeSeconds" => ..., "durationSeconds" => ..., "startGas" => "500.0", ... }
261
+
262
+ # Retrieve User's Active Asset Data
263
+ aad = sdk.info.active_asset_data(user_address, "APT")
264
+ # => { "user" => user_address, "coin" => "APT", "leverage" => { "type" => "cross", "value" => 3 }, ... }
265
+
266
+ # Retrieve Builder-Deployed Perp Market Limits
267
+ limits = sdk.info.perp_dex_limits("builder-dex")
268
+ # => { "totalOiCap" => "10000000.0", "oiSzCapPerPerp" => "...", ... }
269
+ ```
84
270
 
85
- # Get order status
86
- status = sdk.info.order_status(user_address, order_id)
87
- # => { "status" => "filled", "sz" => "0.1", "px" => "50000" }
271
+ ##### Examples: Spot
272
+
273
+ ```ruby
274
+ # Retrieve spot metadata
275
+ spot_meta = sdk.info.spot_meta
276
+ # => { "tokens" => [...], "universe" => [...] }
277
+
278
+ # Retrieve spot asset contexts
279
+ spot_meta_ctxs = sdk.info.spot_meta_and_asset_ctxs
280
+ # => [ { "tokens" => [...], "universe" => [...] }, [ { "midPx" => "...", ... } ] ]
281
+
282
+ # Retrieve a user's token balances
283
+ balances = sdk.info.spot_balances(user_address)
284
+ # => { "balances" => [{ "coin" => "USDC", "token" => 0, "total" => "..." }, ...] }
285
+
286
+ # Retrieve information about the Spot Deploy Auction
287
+ deploy_state = sdk.info.spot_deploy_state(user_address)
288
+ # => { "states" => [...], "gasAuction" => { ... } }
289
+
290
+ # Retrieve information about the Spot Pair Deploy Auction
291
+ pair_status = sdk.info.spot_pair_deploy_auction_status
292
+ # => { "startTimeSeconds" => ..., "durationSeconds" => ..., "startGas" => "...", ... }
293
+
294
+ # Retrieve information about a token by onchain id in 34-character hexadecimal format
295
+ details = sdk.info.token_details("0x00000000000000000000000000000000")
296
+ # => { "name" => "TEST", "maxSupply" => "...", "midPx" => "...", ... }
297
+ ```
298
+
299
+ #### Exchange Methods (Trading)
300
+
301
+ **Note:** Exchange methods require initializing the SDK with a `private_key`.
302
+
303
+ - `order(coin:, is_buy:, size:, limit_px:, ...)` - Place a single limit order
304
+ - `bulk_orders(orders:, grouping:, ...)` - Place multiple orders in a batch
305
+ - `market_order(coin:, is_buy:, size:, slippage:, ...)` - Place a market order with slippage
306
+ - `cancel(coin:, oid:, ...)` - Cancel an order by order ID
307
+ - `cancel_by_cloid(coin:, cloid:, ...)` - Cancel an order by client order ID
308
+ - `bulk_cancel(cancels:, ...)` - Cancel multiple orders by order ID
309
+ - `bulk_cancel_by_cloid(cancels:, ...)` - Cancel multiple orders by client order ID
310
+ - `address` - Get the wallet address associated with the private key
311
+
312
+ All exchange methods support an optional `vault_address:` parameter for vault trading.
313
+
314
+ ##### Examples: Exchange (Trading)
315
+
316
+ ```ruby
317
+ # Initialize SDK with private key for trading
318
+ sdk = Hyperliquid.new(
319
+ testnet: true,
320
+ private_key: ENV['HYPERLIQUID_PRIVATE_KEY']
321
+ )
322
+
323
+ # Get wallet address
324
+ address = sdk.exchange.address
325
+ # => "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
326
+
327
+ # Place a limit buy order
328
+ result = sdk.exchange.order(
329
+ coin: 'BTC',
330
+ is_buy: true,
331
+ size: '0.01',
332
+ limit_px: '95000',
333
+ order_type: { limit: { tif: 'Gtc' } } # Good-til-canceled (default)
334
+ )
335
+ # => { "status" => "ok", "response" => { "type" => "order", "data" => { "statuses" => [...] } } }
336
+
337
+ # Place a limit sell order with client order ID
338
+ cloid = Hyperliquid::Cloid.from_int(123) # Or Cloid.random
339
+ result = sdk.exchange.order(
340
+ coin: 'ETH',
341
+ is_buy: false,
342
+ size: '0.5',
343
+ limit_px: '3500',
344
+ cloid: cloid
345
+ )
346
+
347
+ # Place a market order (IoC with slippage)
348
+ result = sdk.exchange.market_order(
349
+ coin: 'BTC',
350
+ is_buy: true,
351
+ size: '0.01',
352
+ slippage: 0.03 # 3% slippage tolerance (default: 5%)
353
+ )
354
+
355
+ # Place multiple orders at once
356
+ orders = [
357
+ { coin: 'BTC', is_buy: true, size: '0.01', limit_px: '94000' },
358
+ { coin: 'BTC', is_buy: false, size: '0.01', limit_px: '96000' }
359
+ ]
360
+ result = sdk.exchange.bulk_orders(orders: orders)
361
+
362
+ # Cancel an order by order ID
363
+ oid = result.dig('response', 'data', 'statuses', 0, 'resting', 'oid')
364
+ sdk.exchange.cancel(coin: 'BTC', oid: oid)
365
+
366
+ # Cancel an order by client order ID
367
+ sdk.exchange.cancel_by_cloid(coin: 'ETH', cloid: cloid)
368
+
369
+ # Cancel multiple orders by order ID
370
+ cancels = [
371
+ { coin: 'BTC', oid: 12345 },
372
+ { coin: 'ETH', oid: 12346 }
373
+ ]
374
+ sdk.exchange.bulk_cancel(cancels: cancels)
375
+
376
+ # Cancel multiple orders by client order ID
377
+ cloid_cancels = [
378
+ { coin: 'BTC', cloid: Hyperliquid::Cloid.from_int(1) },
379
+ { coin: 'ETH', cloid: Hyperliquid::Cloid.from_int(2) }
380
+ ]
381
+ sdk.exchange.bulk_cancel_by_cloid(cancels: cloid_cancels)
382
+
383
+ # Vault trading (trade on behalf of a vault)
384
+ vault_address = '0x...'
385
+ sdk.exchange.order(
386
+ coin: 'BTC',
387
+ is_buy: true,
388
+ size: '1.0',
389
+ limit_px: '95000',
390
+ vault_address: vault_address
391
+ )
392
+ ```
393
+
394
+ **Order Types:**
395
+ - `{ limit: { tif: 'Gtc' } }` - Good-til-canceled (default)
396
+ - `{ limit: { tif: 'Ioc' } }` - Immediate-or-cancel
397
+ - `{ limit: { tif: 'Alo' } }` - Add-liquidity-only (post-only)
398
+
399
+ **Trigger Orders (Stop Loss / Take Profit):**
400
+ ```ruby
401
+ # Stop loss: Sell when price drops to trigger level
402
+ sdk.exchange.order(
403
+ coin: 'BTC',
404
+ is_buy: false,
405
+ size: '0.1',
406
+ limit_px: '89900',
407
+ order_type: {
408
+ trigger: {
409
+ trigger_px: 90_000,
410
+ is_market: true, # Execute as market order when triggered
411
+ tpsl: 'sl' # Stop loss
412
+ }
413
+ }
414
+ )
415
+
416
+ # Take profit: Sell when price rises to trigger level
417
+ sdk.exchange.order(
418
+ coin: 'BTC',
419
+ is_buy: false,
420
+ size: '0.1',
421
+ limit_px: '100100',
422
+ order_type: {
423
+ trigger: {
424
+ trigger_px: 100_000,
425
+ is_market: false, # Execute as limit order when triggered
426
+ tpsl: 'tp' # Take profit
427
+ }
428
+ }
429
+ )
430
+ ```
431
+
432
+ **Client Order IDs (Cloid):**
433
+ ```ruby
434
+ # Create from integer (zero-padded to 16 bytes)
435
+ cloid = Hyperliquid::Cloid.from_int(42)
436
+ # => "0x0000000000000000000000000000002a"
437
+
438
+ # Create from hex string
439
+ cloid = Hyperliquid::Cloid.from_str('0x1234567890abcdef1234567890abcdef')
440
+
441
+ # Create from UUID
442
+ cloid = Hyperliquid::Cloid.from_uuid('550e8400-e29b-41d4-a716-446655440000')
443
+
444
+ # Generate random
445
+ cloid = Hyperliquid::Cloid.random
88
446
  ```
89
447
 
90
448
  ### Configuration
@@ -96,12 +454,31 @@ sdk = Hyperliquid.new(timeout: 60)
96
454
  # Enable retry logic for handling transient failures (default: disabled)
97
455
  sdk = Hyperliquid.new(retry_enabled: true)
98
456
 
457
+ # Enable trading with a private key
458
+ sdk = Hyperliquid.new(private_key: ENV['HYPERLIQUID_PRIVATE_KEY'])
459
+
460
+ # Set global order expiration (orders expire after this timestamp)
461
+ expires_at_ms = (Time.now.to_f * 1000).to_i + 30_000 # 30 seconds from now
462
+ sdk = Hyperliquid.new(
463
+ private_key: ENV['HYPERLIQUID_PRIVATE_KEY'],
464
+ expires_after: expires_at_ms
465
+ )
466
+
99
467
  # Combine multiple configuration options
100
- sdk = Hyperliquid.new(testnet: true, timeout: 60, retry_enabled: true)
468
+ sdk = Hyperliquid.new(
469
+ testnet: true,
470
+ timeout: 60,
471
+ retry_enabled: true,
472
+ private_key: ENV['HYPERLIQUID_PRIVATE_KEY'],
473
+ expires_after: expires_at_ms
474
+ )
101
475
 
102
476
  # Check which environment you're using
103
477
  sdk.testnet? # => false
104
478
  sdk.base_url # => "https://api.hyperliquid.xyz"
479
+
480
+ # Check if exchange is available (private_key was provided)
481
+ sdk.exchange # => nil if no private_key, Hyperliquid::Exchange instance otherwise
105
482
  ```
106
483
 
107
484
  #### Retry Configuration
@@ -154,34 +531,6 @@ Available error classes:
154
531
  - `Hyperliquid::NetworkError` - Connection issues
155
532
  - `Hyperliquid::TimeoutError` - Request timeouts
156
533
 
157
- ## API Reference
158
-
159
- ### Hyperliquid.new(options = {})
160
-
161
- Creates a new SDK instance.
162
-
163
- **Parameters:**
164
- - `testnet` (Boolean) - Use testnet instead of mainnet (default: false)
165
- - `timeout` (Integer) - Request timeout in seconds (default: 30)
166
- - `retry_enabled` (Boolean) - Enable automatic retry logic for transient failures (default: false)
167
-
168
- ### Info API Methods
169
-
170
- All Info methods return parsed JSON responses from the Hyperliquid API.
171
-
172
- #### Market Data Methods
173
- - `all_mids()` - Get all market mid prices
174
- - `meta()` - Get asset metadata
175
- - `meta_and_asset_ctxs()` - Get extended asset metadata
176
- - `l2_book(coin)` - Get L2 order book for a coin
177
- - `candles_snapshot(coin, interval, start_time, end_time)` - Get candlestick data
178
-
179
- #### User Data Methods
180
- - `open_orders(user)` - Get user's open orders
181
- - `user_fills(user)` - Get user's fill history
182
- - `user_state(user)` - Get user's trading state
183
- - `order_status(user, oid)` - Get order status
184
-
185
534
  ## Development
186
535
 
187
536
  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.
@@ -208,11 +557,11 @@ rake rubocop
208
557
 
209
558
  ## Roadmap
210
559
 
211
- The latest version is v0.2.0 with read-only Info API support. Future versions will include:
560
+ The SDK now supports both Info API (read) and Exchange API (trading). Future versions will include:
212
561
 
213
- - Trading API (place orders, cancel orders, etc.)
214
562
  - WebSocket support for real-time data
215
- - Advanced trading features
563
+ - Additional exchange operations (leverage, margin adjustments, transfers)
564
+ - Advanced trading features (TWAP, etc.)
216
565
 
217
566
  ## Contributing
218
567