hyperliquid 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 789cad57e75566edeaeb09a8437763d716caa6978c8a2ed9322623eb223c40a7
4
- data.tar.gz: f2e68884aedf2f33cf4b66d811e02fe1f3fdaf4e1b77793b29b64b52934773ad
3
+ metadata.gz: 184e215d2d80056cb19bd6a20b273134d9997979d160d154318c5e155cdf02bb
4
+ data.tar.gz: 1f2bd8b08ef2e99e3732bd7775eeb70fe00ad7c2f4210312d07d237d28e670ed
5
5
  SHA512:
6
- metadata.gz: 271fd73adff54d249d4ca2bf2b9f16aacdba8519ea0891e36b2315781019e231ddc158e2a0caeb401d2b43c3cf34f5cee68a0f1c15b183f41f2a1363a98af05b
7
- data.tar.gz: 8b0c7fe1e353bdd6aa01d745708c0dfd7b3909bd95185c88ce9cd7fa93204535cccea04f47ad22d786f068c6e3f2cee77a69ce81df6aa1615e700743248e35fa
6
+ metadata.gz: 1b8645b6f40ae9163343fbc6d7d5c814417643469d75ac320073546243d601055c26f92e1ecb272baf9d839dc4b983b19d56be01cc2bcf4709de9f0e6bf81116
7
+ data.tar.gz: 462b64553e8ee0939bf0284b0647ec602f9be2f3b2389144e64188813cf52d1bca1daf3feb233eab1167fb1337bda7028208acc38398e55a6279e2593ab26181
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## [Ruby Hyperliquid SDK Changelog]
2
2
 
3
+ ## [0.4.1] - 2025-01-28
4
+
5
+ - Reorganize documentation for improved readability
6
+ - Streamline README with basic setup and links to detailed docs
7
+ - Add `docs/API.md` with complete method reference
8
+ - Add `docs/EXAMPLES.md` with Info and Exchange code examples
9
+ - Add `docs/CONFIGURATION.md` with SDK options and retry settings
10
+ - Add `docs/ERRORS.md` with error handling guide
11
+ - Add `docs/DEVELOPMENT.md` with setup and testing instructions
12
+
3
13
  ## [0.4.0] - 2025-01-27
4
14
 
5
15
  - Add Exchange API for authenticated write operations (trading)
data/README.md CHANGED
@@ -46,514 +46,13 @@ trading_sdk = Hyperliquid.new(
46
46
  exchange = trading_sdk.exchange
47
47
  ```
48
48
 
49
- ### Supported APIs
49
+ ### Documentation
50
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
102
-
103
- ```ruby
104
- # Retrieve mids for all coins
105
- mids = sdk.info.all_mids
106
- # => { "BTC" => "50000", "ETH" => "3000", ... }
107
-
108
- user_address = "0x..."
109
-
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, ... }]
117
-
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
143
- book = sdk.info.l2_book("BTC")
144
- # => { "coin" => "BTC", "levels" => [[asks], [bids]], "time" => ... }
145
-
146
- # Candle snapshot
147
- candles = sdk.info.candles_snapshot("BTC", "1h", start_time_ms, end_time_ms)
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" }, ...]
213
- ```
214
-
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
218
-
219
- ```ruby
220
- # Retrieve all perpetual DEXs
221
- perp_dexs = sdk.info.perp_dexs
222
- # => [nil, { "name" => "test", "full_name" => "test dex", ... }]
223
-
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" => [...] }
229
-
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" => [...] }
233
-
234
- # Retrieve user's perpetuals account summary (optionally for a specific perp dex)
235
- state = sdk.info.user_state(user_address)
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
- ```
270
-
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
446
- ```
447
-
448
- ### Configuration
449
-
450
- ```ruby
451
- # Custom timeout (default: 30 seconds)
452
- sdk = Hyperliquid.new(timeout: 60)
453
-
454
- # Enable retry logic for handling transient failures (default: disabled)
455
- sdk = Hyperliquid.new(retry_enabled: true)
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
-
467
- # Combine multiple configuration options
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
- )
475
-
476
- # Check which environment you're using
477
- sdk.testnet? # => false
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
482
- ```
483
-
484
- #### Retry Configuration
485
-
486
- By default, retry logic is **disabled** for predictable API behavior. When enabled, the SDK will automatically retry requests that fail due to:
487
-
488
- - Network connectivity issues (connection failed, timeouts)
489
- - Server errors (5xx status codes)
490
- - Rate limiting (429 status codes)
491
-
492
- **Retry Settings:**
493
- - Maximum retries: 2
494
- - Base interval: 0.5 seconds
495
- - Backoff factor: 2x (exponential backoff)
496
- - Randomness: ±50% to prevent thundering herd
497
-
498
- **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.
499
-
500
- ### Error Handling
501
-
502
- The SDK provides comprehensive error handling:
503
-
504
- ```ruby
505
- begin
506
- orders = sdk.info.open_orders(user_address)
507
- rescue Hyperliquid::AuthenticationError
508
- # Handle authentication issues
509
- rescue Hyperliquid::RateLimitError
510
- # Handle rate limiting
511
- rescue Hyperliquid::ServerError
512
- # Handle server errors
513
- rescue Hyperliquid::NetworkError
514
- # Handle network connectivity issues
515
- rescue Hyperliquid::Error => e
516
- # Handle any other Hyperliquid API errors
517
- puts "Error: #{e.message}"
518
- puts "Status: #{e.status_code}" if e.status_code
519
- puts "Response: #{e.response_body}" if e.response_body
520
- end
521
- ```
522
-
523
- Available error classes:
524
- - `Hyperliquid::Error` - Base error class
525
- - `Hyperliquid::ClientError` - 4xx errors
526
- - `Hyperliquid::ServerError` - 5xx errors
527
- - `Hyperliquid::AuthenticationError` - 401 errors
528
- - `Hyperliquid::BadRequestError` - 400 errors
529
- - `Hyperliquid::NotFoundError` - 404 errors
530
- - `Hyperliquid::RateLimitError` - 429 errors
531
- - `Hyperliquid::NetworkError` - Connection issues
532
- - `Hyperliquid::TimeoutError` - Request timeouts
533
-
534
- ## Development
535
-
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.
537
-
538
- Run the example:
539
- ```bash
540
- ruby example.rb
541
- ```
542
-
543
- Run tests:
544
- ```bash
545
- rake spec
546
- ```
547
-
548
- Run tests and linting together:
549
- ```bash
550
- rake
551
- ```
552
-
553
- Run linting:
554
- ```bash
555
- rake rubocop
556
- ```
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
557
56
 
558
57
  ## Roadmap
559
58
 
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 |
data/docs/EXAMPLES.md ADDED
@@ -0,0 +1,342 @@
1
+ # Examples
2
+
3
+ ## Info API
4
+
5
+ ### General Info
6
+
7
+ ```ruby
8
+ # Retrieve mids for all coins
9
+ mids = sdk.info.all_mids
10
+ # => { "BTC" => "50000", "ETH" => "3000", ... }
11
+
12
+ user_address = "0x..."
13
+
14
+ # Retrieve a user's open orders
15
+ orders = sdk.info.open_orders(user_address)
16
+ # => [{ "coin" => "BTC", "sz" => "0.1", "px" => "50000", "side" => "A" }]
17
+
18
+ # Retrieve a user's open orders with additional frontend info
19
+ frontend_orders = sdk.info.frontend_open_orders(user_address)
20
+ # => [{ "coin" => "BTC", "isTrigger" => false, ... }]
21
+
22
+ # Retrieve a user's fills
23
+ fills = sdk.info.user_fills(user_address)
24
+ # => [{ "coin" => "BTC", "sz" => "0.1", "px" => "50000", "side" => "A", "time" => 1234567890 }]
25
+
26
+ # Retrieve a user's fills by time
27
+ start_time_ms = 1_700_000_000_000
28
+ end_time_ms = start_time_ms + 86_400_000
29
+ fills_by_time = sdk.info.user_fills_by_time(user_address, start_time_ms, end_time_ms)
30
+ # => [{ "coin" => "ETH", "px" => "3000", "time" => start_time_ms }, ...]
31
+
32
+ # Query user rate limits
33
+ rate_limit = sdk.info.user_rate_limit(user_address)
34
+ # => { "nRequestsUsed" => 100, "nRequestsCap" => 10000 }
35
+
36
+ # Query order status by oid
37
+ order_id = 12345
38
+ status_by_oid = sdk.info.order_status(user_address, order_id)
39
+ # => { "status" => "filled", ... }
40
+
41
+ # Query order status by cloid
42
+ cloid = "client-order-id-123"
43
+ status_by_cloid = sdk.info.order_status_by_cloid(user_address, cloid)
44
+ # => { "status" => "cancelled", ... }
45
+
46
+ # L2 order book snapshot
47
+ book = sdk.info.l2_book("BTC")
48
+ # => { "coin" => "BTC", "levels" => [[asks], [bids]], "time" => ... }
49
+
50
+ # Candle snapshot
51
+ candles = sdk.info.candles_snapshot("BTC", "1h", start_time_ms, end_time_ms)
52
+ # => [{ "t" => ..., "o" => "50000", "h" => "51000", "l" => "49000", "c" => "50500", "v" => "100" }]
53
+
54
+ # Check builder fee approval
55
+ builder_address = "0x..."
56
+ fee_approval = sdk.info.max_builder_fee(user_address, builder_address)
57
+ # => { "approved" => true, ... }
58
+
59
+ # Retrieve a user's historical orders
60
+ hist_orders = sdk.info.historical_orders(user_address)
61
+ # => [{ "oid" => 123, "coin" => "BTC", ... }]
62
+ hist_orders_ranged = sdk.info.historical_orders(user_address, start_time_ms, end_time_ms)
63
+ # => []
64
+
65
+ # Retrieve a user's TWAP slice fills
66
+ twap_fills = sdk.info.user_twap_slice_fills(user_address)
67
+ # => [{ "sliceId" => 1, "coin" => "ETH", "sz" => "1.0" }, ...]
68
+ twap_fills_ranged = sdk.info.user_twap_slice_fills(user_address, start_time_ms, end_time_ms)
69
+ # => []
70
+
71
+ # Retrieve a user's subaccounts
72
+ subaccounts = sdk.info.user_subaccounts(user_address)
73
+ # => ["0x1111...", ...]
74
+
75
+ # Retrieve details for a vault
76
+ vault_addr = "0x..."
77
+ vault = sdk.info.vault_details(vault_addr)
78
+ # => { "vaultAddress" => vault_addr, ... }
79
+ vault_with_user = sdk.info.vault_details(vault_addr, user_address)
80
+ # => { "vaultAddress" => vault_addr, "user" => user_address, ... }
81
+
82
+ # Retrieve a user's vault deposits
83
+ vault_deposits = sdk.info.user_vault_equities(user_address)
84
+ # => [{ "vaultAddress" => "0x...", "equity" => "123.45" }, ...]
85
+
86
+ # Query a user's role
87
+ role = sdk.info.user_role(user_address)
88
+ # => { "role" => "tradingUser" }
89
+
90
+ # Query a user's portfolio
91
+ portfolio = sdk.info.portfolio(user_address)
92
+ # => [["day", { "pnlHistory" => [...], "vlm" => "0.0" }], ...]
93
+
94
+ # Query a user's referral information
95
+ referral = sdk.info.referral(user_address)
96
+ # => { "referredBy" => { "referrer" => "0x..." }, ... }
97
+
98
+ # Query a user's fees
99
+ fees = sdk.info.user_fees(user_address)
100
+ # => { "userAddRate" => "0.0001", "feeSchedule" => { ... } }
101
+
102
+ # Query a user's staking delegations
103
+ delegations = sdk.info.delegations(user_address)
104
+ # => [{ "validator" => "0x...", "amount" => "100.0" }, ...]
105
+
106
+ # Query a user's staking summary
107
+ summary = sdk.info.delegator_summary(user_address)
108
+ # => { "delegated" => "12060.16529862", ... }
109
+
110
+ # Query a user's staking history
111
+ history = sdk.info.delegator_history(user_address)
112
+ # => [{ "time" => 1_736_726_400_073, "delta" => { ... } }, ...]
113
+
114
+ # Query a user's staking rewards
115
+ rewards = sdk.info.delegator_rewards(user_address)
116
+ # => [{ "time" => 1_736_726_400_073, "source" => "delegation", "totalAmount" => "0.123" }, ...]
117
+ ```
118
+
119
+ **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"]`.
120
+
121
+ ### Perpetuals
122
+
123
+ ```ruby
124
+ # Retrieve all perpetual DEXs
125
+ perp_dexs = sdk.info.perp_dexs
126
+ # => [nil, { "name" => "test", "full_name" => "test dex", ... }]
127
+
128
+ # Retrieve perpetuals metadata (optionally for a specific perp dex)
129
+ meta = sdk.info.meta
130
+ # => { "universe" => [...] }
131
+ meta = sdk.info.meta(dex: "perp-dex-name")
132
+ # => { "universe" => [...] }
133
+
134
+ # Retrieve perpetuals asset contexts (includes mark price, current funding, open interest, etc.)
135
+ meta_ctxs = sdk.info.meta_and_asset_ctxs
136
+ # => { "universe" => [...], "assetCtxs" => [...] }
137
+
138
+ # Retrieve user's perpetuals account summary (optionally for a specific perp dex)
139
+ state = sdk.info.user_state(user_address)
140
+ # => { "assetPositions" => [...], "marginSummary" => {...} }
141
+ state = sdk.info.user_state(user_address, dex: "perp-dex-name")
142
+ # => { "assetPositions" => [...], "marginSummary" => {...} }
143
+
144
+ # Retrieve a user's funding history or non-funding ledger updates (optional end_time)
145
+ funding = sdk.info.user_funding(user_address, start_time)
146
+ # => [{ "delta" => { "type" => "funding", ... }, "time" => ... }]
147
+ funding = sdk.info.user_funding(user_address, start_time, end_time)
148
+ # => [{ "delta" => { "type" => "funding", ... }, "time" => ... }]
149
+
150
+ # Retrieve historical funding rates
151
+ hist = sdk.info.funding_history("ETH", start_time)
152
+ # => [{ "coin" => "ETH", "fundingRate" => "...", "time" => ... }]
153
+
154
+ # Retrieve predicted funding rates for different venues
155
+ pred = sdk.info.predicted_fundings
156
+ # => [["AVAX", [["HlPerp", { "fundingRate" => "0.0000125", "nextFundingTime" => ... }], ...]], ...]
157
+
158
+ # Query perps at open interest caps
159
+ oi_capped = sdk.info.perps_at_open_interest_cap
160
+ # => ["BADGER", "CANTO", ...]
161
+
162
+ # Retrieve information about the Perp Deploy Auction
163
+ auction = sdk.info.perp_deploy_auction_status
164
+ # => { "startTimeSeconds" => ..., "durationSeconds" => ..., "startGas" => "500.0", ... }
165
+
166
+ # Retrieve User's Active Asset Data
167
+ aad = sdk.info.active_asset_data(user_address, "APT")
168
+ # => { "user" => user_address, "coin" => "APT", "leverage" => { "type" => "cross", "value" => 3 }, ... }
169
+
170
+ # Retrieve Builder-Deployed Perp Market Limits
171
+ limits = sdk.info.perp_dex_limits("builder-dex")
172
+ # => { "totalOiCap" => "10000000.0", "oiSzCapPerPerp" => "...", ... }
173
+ ```
174
+
175
+ ### Spot
176
+
177
+ ```ruby
178
+ # Retrieve spot metadata
179
+ spot_meta = sdk.info.spot_meta
180
+ # => { "tokens" => [...], "universe" => [...] }
181
+
182
+ # Retrieve spot asset contexts
183
+ spot_meta_ctxs = sdk.info.spot_meta_and_asset_ctxs
184
+ # => [ { "tokens" => [...], "universe" => [...] }, [ { "midPx" => "...", ... } ] ]
185
+
186
+ # Retrieve a user's token balances
187
+ balances = sdk.info.spot_balances(user_address)
188
+ # => { "balances" => [{ "coin" => "USDC", "token" => 0, "total" => "..." }, ...] }
189
+
190
+ # Retrieve information about the Spot Deploy Auction
191
+ deploy_state = sdk.info.spot_deploy_state(user_address)
192
+ # => { "states" => [...], "gasAuction" => { ... } }
193
+
194
+ # Retrieve information about the Spot Pair Deploy Auction
195
+ pair_status = sdk.info.spot_pair_deploy_auction_status
196
+ # => { "startTimeSeconds" => ..., "durationSeconds" => ..., "startGas" => "...", ... }
197
+
198
+ # Retrieve information about a token by onchain id in 34-character hexadecimal format
199
+ details = sdk.info.token_details("0x00000000000000000000000000000000")
200
+ # => { "name" => "TEST", "maxSupply" => "...", "midPx" => "...", ... }
201
+ ```
202
+
203
+ ## Exchange API (Trading)
204
+
205
+ ### Basic Orders
206
+
207
+ ```ruby
208
+ # Initialize SDK with private key for trading
209
+ sdk = Hyperliquid.new(
210
+ testnet: true,
211
+ private_key: ENV['HYPERLIQUID_PRIVATE_KEY']
212
+ )
213
+
214
+ # Get wallet address
215
+ address = sdk.exchange.address
216
+ # => "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
217
+
218
+ # Place a limit buy order
219
+ result = sdk.exchange.order(
220
+ coin: 'BTC',
221
+ is_buy: true,
222
+ size: '0.01',
223
+ limit_px: '95000',
224
+ order_type: { limit: { tif: 'Gtc' } } # Good-til-canceled (default)
225
+ )
226
+ # => { "status" => "ok", "response" => { "type" => "order", "data" => { "statuses" => [...] } } }
227
+
228
+ # Place a limit sell order with client order ID
229
+ cloid = Hyperliquid::Cloid.from_int(123) # Or Cloid.random
230
+ result = sdk.exchange.order(
231
+ coin: 'ETH',
232
+ is_buy: false,
233
+ size: '0.5',
234
+ limit_px: '3500',
235
+ cloid: cloid
236
+ )
237
+
238
+ # Place a market order (IoC with slippage)
239
+ result = sdk.exchange.market_order(
240
+ coin: 'BTC',
241
+ is_buy: true,
242
+ size: '0.01',
243
+ slippage: 0.03 # 3% slippage tolerance (default: 5%)
244
+ )
245
+
246
+ # Place multiple orders at once
247
+ orders = [
248
+ { coin: 'BTC', is_buy: true, size: '0.01', limit_px: '94000' },
249
+ { coin: 'BTC', is_buy: false, size: '0.01', limit_px: '96000' }
250
+ ]
251
+ result = sdk.exchange.bulk_orders(orders: orders)
252
+ ```
253
+
254
+ ### Canceling Orders
255
+
256
+ ```ruby
257
+ # Cancel an order by order ID
258
+ oid = result.dig('response', 'data', 'statuses', 0, 'resting', 'oid')
259
+ sdk.exchange.cancel(coin: 'BTC', oid: oid)
260
+
261
+ # Cancel an order by client order ID
262
+ sdk.exchange.cancel_by_cloid(coin: 'ETH', cloid: cloid)
263
+
264
+ # Cancel multiple orders by order ID
265
+ cancels = [
266
+ { coin: 'BTC', oid: 12345 },
267
+ { coin: 'ETH', oid: 12346 }
268
+ ]
269
+ sdk.exchange.bulk_cancel(cancels: cancels)
270
+
271
+ # Cancel multiple orders by client order ID
272
+ cloid_cancels = [
273
+ { coin: 'BTC', cloid: Hyperliquid::Cloid.from_int(1) },
274
+ { coin: 'ETH', cloid: Hyperliquid::Cloid.from_int(2) }
275
+ ]
276
+ sdk.exchange.bulk_cancel_by_cloid(cancels: cloid_cancels)
277
+ ```
278
+
279
+ ### Vault Trading
280
+
281
+ ```ruby
282
+ # Vault trading (trade on behalf of a vault)
283
+ vault_address = '0x...'
284
+ sdk.exchange.order(
285
+ coin: 'BTC',
286
+ is_buy: true,
287
+ size: '1.0',
288
+ limit_px: '95000',
289
+ vault_address: vault_address
290
+ )
291
+ ```
292
+
293
+ ### Trigger Orders (Stop Loss / Take Profit)
294
+
295
+ ```ruby
296
+ # Stop loss: Sell when price drops to trigger level
297
+ sdk.exchange.order(
298
+ coin: 'BTC',
299
+ is_buy: false,
300
+ size: '0.1',
301
+ limit_px: '89900',
302
+ order_type: {
303
+ trigger: {
304
+ trigger_px: 90_000,
305
+ is_market: true, # Execute as market order when triggered
306
+ tpsl: 'sl' # Stop loss
307
+ }
308
+ }
309
+ )
310
+
311
+ # Take profit: Sell when price rises to trigger level
312
+ sdk.exchange.order(
313
+ coin: 'BTC',
314
+ is_buy: false,
315
+ size: '0.1',
316
+ limit_px: '100100',
317
+ order_type: {
318
+ trigger: {
319
+ trigger_px: 100_000,
320
+ is_market: false, # Execute as limit order when triggered
321
+ tpsl: 'tp' # Take profit
322
+ }
323
+ }
324
+ )
325
+ ```
326
+
327
+ ### Client Order IDs (Cloid)
328
+
329
+ ```ruby
330
+ # Create from integer (zero-padded to 16 bytes)
331
+ cloid = Hyperliquid::Cloid.from_int(42)
332
+ # => "0x0000000000000000000000000000002a"
333
+
334
+ # Create from hex string
335
+ cloid = Hyperliquid::Cloid.from_str('0x1234567890abcdef1234567890abcdef')
336
+
337
+ # Create from UUID
338
+ cloid = Hyperliquid::Cloid.from_uuid('550e8400-e29b-41d4-a716-446655440000')
339
+
340
+ # Generate random
341
+ cloid = Hyperliquid::Cloid.random
342
+ ```
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hyperliquid
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyperliquid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - carter2099
@@ -82,6 +82,11 @@ files:
82
82
  - LICENSE.txt
83
83
  - README.md
84
84
  - Rakefile
85
+ - docs/API.md
86
+ - docs/CONFIGURATION.md
87
+ - docs/DEVELOPMENT.md
88
+ - docs/ERRORS.md
89
+ - docs/EXAMPLES.md
85
90
  - example.rb
86
91
  - lib/hyperliquid.rb
87
92
  - lib/hyperliquid/client.rb