hyperliquid 1.8.0 → 1.9.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14a1a12bfa26b33260f7f2b0eacd8aeeb6762fc5d7d678f44cd63d6b492dcdd2
4
- data.tar.gz: b0d4516d805842818e5d71b904a1f707014446802ad8efe60a7b6a6ed6a27853
3
+ metadata.gz: 9a6d420027ac68a2d2959293fd9735798e80ad39f484dd2f43f1f808d5964944
4
+ data.tar.gz: 89c4e1688d7a5ac9d4cba3a214de798ec333161a0d6053abeac5d6d4da4916f3
5
5
  SHA512:
6
- metadata.gz: 2e0419a6fc7501f2c3a3b4085d35fc495a88840a295a2017a60934f5e906f51b98bdd0be178d2474eb9be0414a6b435fed19e258235e30043ca1808af8e7144a
7
- data.tar.gz: 3de78e11757c22db4a7d59880fd14e0d28a3e31721054bb22d5368adf48a0e1fa2a9ca7c67fa75ffce2d88115a9973fa5fdc92f285b62836f657c4518c7fe585
6
+ metadata.gz: 7ca76a9847766153f734661dd91f9d62bb1c87e2c43aacb4dd63e20904a1f3ddff505b4e8f92eb80b0bf6624e584560c121a901e2a1865617062b0e1cc1963c4
7
+ data.tar.gz: 43d32462a0350f7f733f50cd1190b6acfde8647b141665998bf5e1fb6f6b3fc24c348ba04dbb6ca35d3aef8e8bce0770445ab44991e65d566c58a9ce01c928c3
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.4.9
1
+ 3.4.10
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  ## [Ruby Hyperliquid SDK Changelog]
2
2
 
3
+ ## [1.9.0] - 2026-08-31
4
+
5
+ ### New Exchange actions
6
+
7
+ - `Exchange#activate_outcome_deployer(is_deactivate:)` activates or deactivates a HIP-4 outcome deployer.
8
+
9
+ ### New Info methods
10
+
11
+ - `Info#outcome_templates` retrieves HIP-4 prediction-market deployer templates.
12
+ - `Info#usdc_routing` retrieves the active USDC deposit and withdrawal routing configuration.
13
+
14
+ ### Extended API support
15
+
16
+ - Added fast-cancel support to `Exchange#cancel`, `Exchange#cancel_by_cloid`, and `l2Book` WebSocket subscriptions.
17
+ - Added always-place support to individual `Exchange#modify_order` and `Exchange#batch_modify` entries.
18
+ - Added optional sub-account routing to `Exchange#usd_class_transfer`.
19
+ - Added optional trigger and stop-price details to `Exchange#twap_order`.
20
+ - Added optional destination routing to `Exchange#reserve_request_weight`.
21
+ - Added optional DEX selection to `Info#margin_table`.
22
+
23
+ ### Tooling
24
+
25
+ - Added weekly Dependabot checks for Bundler and GitHub Actions dependencies.
26
+ - Updated the repository Ruby version to 3.4.10.
27
+
3
28
  ## [1.8.0] - 2026-06-16
4
29
 
5
30
  ### New WebSocket endpoints
data/CLAUDE.md CHANGED
@@ -27,11 +27,11 @@ Integration scripts live in `scripts/` as standalone files (`test_NN_<name>.rb`)
27
27
 
28
28
  ```bash
29
29
  HYPERLIQUID_PRIVATE_KEY=0x... ruby scripts/test_all.rb # all 20
30
- HYPERLIQUID_PRIVATE_KEY=0x... ruby scripts/test_automated.rb # CI-friendly subset (13)
30
+ HYPERLIQUID_PRIVATE_KEY=0x... ruby scripts/test_automated.rb # CI-friendly subset (14)
31
31
  HYPERLIQUID_PRIVATE_KEY=0x... ruby scripts/test_08_usd_class_transfer.rb # single
32
32
  ```
33
33
 
34
- `test_automated.rb` is the unattended runner — same as `test_all.rb` but excludes scripts that require manual testnet preconditions (e.g. `test_09_sub_account_lifecycle` needs $100k traded volume; `test_12_staking` needs HYPE balance; `test_20_explorer_ws` is new and not yet in automated). Some included tests (e.g. `test_08`, `test_11`) are also coded to skip-with-warning when known testnet preconditions aren't met, so the suite stays green on a stable wallet.
34
+ `test_automated.rb` is the unattended runner — same as `test_all.rb` but excludes scripts that require manual testnet preconditions (e.g. `test_09_sub_account_lifecycle` needs $100k traded volume; `test_12_staking` needs HYPE balance). Some included tests (e.g. `test_08`, `test_11`) are also coded to skip-with-warning when known testnet preconditions aren't met, so the suite stays green on a stable wallet.
35
35
 
36
36
  `test_integration.rb` at the project root is a thin convenience wrapper.
37
37
 
@@ -93,7 +93,7 @@ Predicate methods follow Ruby style (`vip?`, `connected?`, `testnet?`) — not `
93
93
 
94
94
  ### CI
95
95
 
96
- GitHub Actions (`.github/workflows/main.yml`): runs `bundle exec rake` (tests + lint) on the Ruby matrix defined in that workflow, for pushes to `main` and on all PRs. The release workflow creates GitHub releases from `CHANGELOG.md` on version tags.
96
+ GitHub Actions (`.github/workflows/main.yml`): runs `bundle exec rake` (tests + lint) on the Ruby matrix defined in that workflow, for pushes to `main` and on all PRs. The release workflow creates GitHub releases from `CHANGELOG.md` on version tags. Dependabot checks Bundler and GitHub Actions dependencies weekly with a 14-day default cooldown; Bundler major updates use a 30-day cooldown.
97
97
 
98
98
  ## Release Flow
99
99
 
@@ -144,13 +144,17 @@ module Hyperliquid
144
144
  # @param coin [String] Asset symbol
145
145
  # @param oid [Integer] Order ID
146
146
  # @param vault_address [String, nil] Vault address for vault trading (optional)
147
+ # @param fast [Boolean, nil] Whether to use fast cancel (optional)
147
148
  # @return [Hash] Cancel response
148
- def cancel(coin:, oid:, vault_address: nil)
149
+ def cancel(coin:, oid:, vault_address: nil, fast: nil)
149
150
  nonce = timestamp_ms
150
151
 
152
+ cancel_entry = { a: asset_index(coin), o: oid }
153
+ cancel_entry[:f] = true if fast
154
+
151
155
  action = {
152
156
  type: 'cancel',
153
- cancels: [{ a: asset_index(coin), o: oid }]
157
+ cancels: [cancel_entry]
154
158
  }
155
159
 
156
160
  signature = @signer.sign_l1_action(
@@ -165,14 +169,18 @@ module Hyperliquid
165
169
  # @param coin [String] Asset symbol
166
170
  # @param cloid [Cloid, String] Client order ID
167
171
  # @param vault_address [String, nil] Vault address for vault trading (optional)
172
+ # @param fast [Boolean, nil] Whether to use fast cancel (optional)
168
173
  # @return [Hash] Cancel response
169
- def cancel_by_cloid(coin:, cloid:, vault_address: nil)
174
+ def cancel_by_cloid(coin:, cloid:, vault_address: nil, fast: nil)
170
175
  nonce = timestamp_ms
171
176
  cloid_raw = normalize_cloid(cloid)
172
177
 
178
+ cancel_entry = { asset: asset_index(coin), cloid: cloid_raw }
179
+ cancel_entry[:f] = true if fast
180
+
173
181
  action = {
174
182
  type: 'cancelByCloid',
175
- cancels: [{ asset: asset_index(coin), cloid: cloid_raw }]
183
+ cancels: [cancel_entry]
176
184
  }
177
185
 
178
186
  signature = @signer.sign_l1_action(
@@ -233,15 +241,17 @@ module Hyperliquid
233
241
  # @param reduce_only [Boolean] Reduce-only flag (default: false)
234
242
  # @param cloid [Cloid, String, nil] Client order ID for the modified order (optional)
235
243
  # @param vault_address [String, nil] Vault address for vault trading (optional)
244
+ # @param always_place [Boolean, nil] Always place the order even if cancel fails (optional)
236
245
  # @return [Hash] Modify response
237
246
  def modify_order(oid:, coin:, is_buy:, size:, limit_px:,
238
247
  order_type: { limit: { tif: 'Gtc' } },
239
- reduce_only: false, cloid: nil, vault_address: nil)
248
+ reduce_only: false, cloid: nil, vault_address: nil, always_place: nil)
240
249
  batch_modify(
241
250
  modifies: [{
242
251
  oid: oid, coin: coin, is_buy: is_buy, size: size,
243
252
  limit_px: limit_px, order_type: order_type,
244
- reduce_only: reduce_only, cloid: cloid
253
+ reduce_only: reduce_only, cloid: cloid,
254
+ always_place: always_place
245
255
  }],
246
256
  vault_address: vault_address
247
257
  )
@@ -249,7 +259,7 @@ module Hyperliquid
249
259
 
250
260
  # Modify multiple orders at once
251
261
  # @param modifies [Array<Hash>] Array of modify hashes with keys:
252
- # :oid, :coin, :is_buy, :size, :limit_px, :order_type, :reduce_only, :cloid
262
+ # :oid, :coin, :is_buy, :size, :limit_px, :order_type, :reduce_only, :cloid, :always_place
253
263
  # @param vault_address [String, nil] Vault address for vault trading (optional)
254
264
  # @return [Hash] Batch modify response
255
265
  def batch_modify(modifies:, vault_address: nil)
@@ -265,7 +275,9 @@ module Hyperliquid
265
275
  reduce_only: m[:reduce_only] || false,
266
276
  cloid: m[:cloid]
267
277
  )
268
- { oid: normalize_oid(m[:oid]), order: order_wire }
278
+ entry = { oid: normalize_oid(m[:oid]), order: order_wire }
279
+ entry[:a] = true if m[:always_place]
280
+ entry
269
281
  end
270
282
 
271
283
  action = {
@@ -420,19 +432,25 @@ module Hyperliquid
420
432
  # Move USDC between perp and spot accounts
421
433
  # @param amount [String, Numeric] Amount to transfer
422
434
  # @param to_perp [Boolean] True to move to perp, false to move to spot
435
+ # @param sub_account [String, nil] Optional sub-account address (0x-prefixed hex).
436
+ # When provided, the transfer targets the sub-account rather than the
437
+ # master account; the suffix ` subaccount:<address>` is appended to the
438
+ # signed amount string (mirrors TS SDK v0.33.1's amount union shape).
423
439
  # @return [Hash] Transfer response
424
- def usd_class_transfer(amount:, to_perp:)
440
+ def usd_class_transfer(amount:, to_perp:, sub_account: nil)
425
441
  nonce = timestamp_ms
442
+ amount_str = amount.to_s
443
+ amount_str = "#{amount_str} subaccount:#{sub_account}" if sub_account
426
444
  action = {
427
445
  type: 'usdClassTransfer',
428
446
  signatureChainId: '0x66eee',
429
447
  hyperliquidChain: Signing::EIP712.hyperliquid_chain(testnet: @testnet),
430
- amount: amount.to_s,
448
+ amount: amount_str,
431
449
  toPerp: to_perp,
432
450
  nonce: nonce
433
451
  }
434
452
  signature = @signer.sign_user_signed_action(
435
- { amount: amount.to_s, toPerp: to_perp, nonce: nonce },
453
+ { amount: amount_str, toPerp: to_perp, nonce: nonce },
436
454
  'HyperliquidTransaction:UsdClassTransfer',
437
455
  Signing::EIP712::USD_CLASS_TRANSFER_TYPES
438
456
  )
@@ -1211,8 +1229,9 @@ module Hyperliquid
1211
1229
  # @param minutes [Integer] TWAP duration in minutes (5..1440)
1212
1230
  # @param randomize [Boolean] Randomize order timing
1213
1231
  # @param vault_address [String, nil] Vault address if acting on behalf of a vault
1232
+ # @param details [Hash, nil] Optional trigger/stop price config: { t: { p:, a: } | nil, s: <UnsignedDecimal> | nil }
1214
1233
  # @return [Hash] Exchange response — on success `response.data.status.running.twapId`
1215
- def twap_order(coin:, is_buy:, size:, reduce_only:, minutes:, randomize:, vault_address: nil)
1234
+ def twap_order(coin:, is_buy:, size:, reduce_only:, minutes:, randomize:, vault_address: nil, details: nil)
1216
1235
  nonce = timestamp_ms
1217
1236
  action = {
1218
1237
  type: 'twapOrder',
@@ -1225,6 +1244,7 @@ module Hyperliquid
1225
1244
  t: randomize
1226
1245
  }
1227
1246
  }
1247
+ action[:details] = details unless details.nil?
1228
1248
  signature = @signer.sign_l1_action(
1229
1249
  action, nonce,
1230
1250
  vault_address: vault_address,
@@ -1251,10 +1271,12 @@ module Hyperliquid
1251
1271
 
1252
1272
  # Reserve additional rate-limited actions for a fee (`reserveRequestWeight` L1 action).
1253
1273
  # @param weight [Integer] Amount of request weight to reserve
1274
+ # @param destination [String, nil] Address of an existing user to reserve the weight for; nil omits the field
1254
1275
  # @return [Hash] Exchange response
1255
- def reserve_request_weight(weight:)
1276
+ def reserve_request_weight(weight:, destination: nil)
1256
1277
  nonce = timestamp_ms
1257
1278
  action = { type: 'reserveRequestWeight', weight: weight }
1279
+ action[:destination] = destination unless destination.nil?
1258
1280
  signature = @signer.sign_l1_action(
1259
1281
  action, nonce,
1260
1282
  expires_after: @expires_after
@@ -1338,6 +1360,20 @@ module Hyperliquid
1338
1360
  post_action(action, signature, nonce, nil)
1339
1361
  end
1340
1362
 
1363
+ # Activate or deactivate the signer as an outcome deployer
1364
+ # (`activateOutcomeDeployer` L1 action, HIP-4).
1365
+ # @param is_deactivate [Boolean] True to deactivate, false to activate
1366
+ # @return [Hash] Exchange response
1367
+ def activate_outcome_deployer(is_deactivate:)
1368
+ nonce = timestamp_ms
1369
+ action = { type: 'activateOutcomeDeployer', isDeactivate: is_deactivate }
1370
+ signature = @signer.sign_l1_action(
1371
+ action, nonce,
1372
+ expires_after: @expires_after
1373
+ )
1374
+ post_action(action, signature, nonce, nil)
1375
+ end
1376
+
1341
1377
  # Finalize the link between a HyperCore spot token and an ERC-20 contract on
1342
1378
  # HyperEVM (`finalizeEvmContract` L1 action). `input` selects the verification method
1343
1379
  # and is passed through verbatim — accepts a Hash `{ create: { nonce: <int> } }` for an
@@ -375,9 +375,12 @@ module Hyperliquid
375
375
 
376
376
  # Retrieve the margin requirements table for a given id
377
377
  # @param id [Integer] Margin table id
378
+ # @param dex [String, nil] DEX name (empty string for main dex); nil omits the field
378
379
  # @return [Hash] Keys: description (String), marginTiers (Array of { lowerBound, maxLeverage })
379
- def margin_table(id)
380
- @client.post(Constants::INFO_ENDPOINT, { type: 'marginTable', id: id })
380
+ def margin_table(id, dex: nil)
381
+ body = { type: 'marginTable', id: id }
382
+ body[:dex] = dex unless dex.nil?
383
+ @client.post(Constants::INFO_ENDPOINT, body)
381
384
  end
382
385
 
383
386
  # Retrieve the vaults a user is leading
@@ -522,6 +525,20 @@ module Hyperliquid
522
525
  @client.post(Constants::INFO_ENDPOINT, { type: 'settledOutcome', outcome: outcome.to_i })
523
526
  end
524
527
 
528
+ # Retrieve outcome templates for HIP-4 prediction market deployers
529
+ # @return [Array<Hash>] Array of templates, each with id, role (standaloneOutcome
530
+ # with sideNames), name, description (both with {keyword} placeholders), and
531
+ # keywords (array of [name, type] where type is "dateTime", "date", "string", or "hlPerp")
532
+ def outcome_templates
533
+ @client.post(Constants::INFO_ENDPOINT, { type: 'outcomeTemplates' })
534
+ end
535
+
536
+ # Retrieve USDC transfer routing configuration
537
+ # @return [Hash] Hash with depositRoute and withdrawalRoute, each "bridge" or "cctp"
538
+ def usdc_routing
539
+ @client.post(Constants::INFO_ENDPOINT, { type: 'usdcRouting' })
540
+ end
541
+
525
542
  # Retrieve a user's funding history
526
543
  # @param user [String]
527
544
  # @param start_time [Integer]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hyperliquid
4
- VERSION = '1.8.0'
4
+ VERSION = '1.9.0'
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: 1.8.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - carter2099