hyperliquid 1.0.2 → 1.1.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 +4 -4
- data/CHANGELOG.md +20 -0
- data/lib/hyperliquid/info.rb +77 -1
- data/lib/hyperliquid/version.rb +1 -1
- data/scripts/test_automated.rb +80 -0
- data/scripts/test_helpers.rb +10 -2
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a9976736621e86406eb3de9e8e4827b59d1c96c86aac1efcff2ee700afa78429
|
|
4
|
+
data.tar.gz: 79c0a9f8587b1af017f02539e2c35b27e7311ba7e00328c0147db636483aed28
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 89e3b1c854bdb152494abc51ed5f7a3dcfe3c354226d7d92ed994ef8f99d9d5fabcf91d81ddedb18bf083bcc9f3cc4952578b2bfe1d95cc2d8c35b359eb392b1
|
|
7
|
+
data.tar.gz: c8fd08574cfa29c927bd5c848ca5bd578914bc82150af2ab0305c38ea84785b22f4f92bed0ca07e49f86f31c8dde089fd83c47e73c58678c807a0dacf5dc9b75
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
## [Ruby Hyperliquid SDK Changelog]
|
|
2
2
|
|
|
3
|
+
## [1.1.0] - 2026-04-24
|
|
4
|
+
|
|
5
|
+
### New Info endpoints
|
|
6
|
+
|
|
7
|
+
- `Info#validator_summaries` — validator status/stake summaries
|
|
8
|
+
- `Info#exchange_status` — exchange-wide status
|
|
9
|
+
- `Info#max_market_order_ntls` — per-coin max market order notionals
|
|
10
|
+
- `Info#pre_transfer_check` — pre-flight checks for transfers
|
|
11
|
+
- `Info#vip?` — VIP status lookup
|
|
12
|
+
- `Info#liquidatable` — open positions flagged liquidatable
|
|
13
|
+
- `Info#recent_trades(coin)` — recent trades feed
|
|
14
|
+
- `Info#block_details(height)` — block detail lookup by height
|
|
15
|
+
- `Info#user_abstraction` — account abstraction state (unifiedAccount, portfolioMargin, dexAbstraction, etc.)
|
|
16
|
+
- `Info#vault_summaries` — vaults less than 2 hours old
|
|
17
|
+
- `Info#user_fills_by_time` now accepts `aggregate_by_time` and `reversed` kwargs (matches upstream Python/TS SDKs)
|
|
18
|
+
|
|
19
|
+
### Fixes
|
|
20
|
+
|
|
21
|
+
- Fix `TypeError` in `dump_status`/`check_result` when `response.data` is a String (e.g. `usdClassTransfer`, `approveBuilderFee` style actions)
|
|
22
|
+
|
|
3
23
|
## [1.0.2] - 2026-02-05
|
|
4
24
|
|
|
5
25
|
- Lower minimum Ruby requirement to 3.3 and align RuboCop target
|
data/lib/hyperliquid/info.rb
CHANGED
|
@@ -52,10 +52,15 @@ module Hyperliquid
|
|
|
52
52
|
# @param user [String] Wallet address
|
|
53
53
|
# @param start_time [Integer] Start timestamp in milliseconds
|
|
54
54
|
# @param end_time [Integer, nil] Optional end timestamp in milliseconds
|
|
55
|
+
# @param aggregate_by_time [Boolean, nil] If true, partial fills are aggregated when a
|
|
56
|
+
# crossing order fills multiple resting orders
|
|
57
|
+
# @param reversed [Boolean, nil] If true, fills are returned in reverse chronological order (newest first)
|
|
55
58
|
# @return [Array]
|
|
56
|
-
def user_fills_by_time(user, start_time, end_time = nil)
|
|
59
|
+
def user_fills_by_time(user, start_time, end_time = nil, aggregate_by_time: nil, reversed: nil)
|
|
57
60
|
body = { type: 'userFillsByTime', user: user, startTime: start_time }
|
|
58
61
|
body[:endTime] = end_time if end_time
|
|
62
|
+
body[:aggregateByTime] = aggregate_by_time unless aggregate_by_time.nil?
|
|
63
|
+
body[:reversed] = reversed unless reversed.nil?
|
|
59
64
|
@client.post(Constants::INFO_ENDPOINT, body)
|
|
60
65
|
end
|
|
61
66
|
|
|
@@ -89,6 +94,20 @@ module Hyperliquid
|
|
|
89
94
|
@client.post(Constants::INFO_ENDPOINT, { type: 'l2Book', coin: coin })
|
|
90
95
|
end
|
|
91
96
|
|
|
97
|
+
# Get recent trades for a coin
|
|
98
|
+
# @param coin [String] Asset symbol (e.g., "BTC")
|
|
99
|
+
# @return [Array] Recent trades with coin, side, px, sz, time, hash, tid, users (maker, taker)
|
|
100
|
+
def recent_trades(coin)
|
|
101
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'recentTrades', coin: coin })
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Get block details by block height
|
|
105
|
+
# @param height [Integer] Block height
|
|
106
|
+
# @return [Hash] Block details including blockTime, hash, height, numTxs, proposer, txs
|
|
107
|
+
def block_details(height)
|
|
108
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'blockDetails', height: height })
|
|
109
|
+
end
|
|
110
|
+
|
|
92
111
|
# Get candlestick data
|
|
93
112
|
# @param coin [String] Coin symbol
|
|
94
113
|
# @param interval [String] Time interval (e.g., "1m", "1h", "1d")
|
|
@@ -163,6 +182,13 @@ module Hyperliquid
|
|
|
163
182
|
@client.post(Constants::INFO_ENDPOINT, { type: 'userVaultEquities', user: user })
|
|
164
183
|
end
|
|
165
184
|
|
|
185
|
+
# Retrieve a list of vaults less than 2 hours old
|
|
186
|
+
# @return [Array] Recently created vaults with name, address, leader, tvl, isClosed,
|
|
187
|
+
# relationship, createTimeMillis
|
|
188
|
+
def vault_summaries
|
|
189
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'vaultSummaries' })
|
|
190
|
+
end
|
|
191
|
+
|
|
166
192
|
# Query a user's role
|
|
167
193
|
# @param user [String]
|
|
168
194
|
# @return [Hash]
|
|
@@ -240,6 +266,56 @@ module Hyperliquid
|
|
|
240
266
|
@client.post(Constants::INFO_ENDPOINT, { type: 'userDexAbstraction', user: user })
|
|
241
267
|
end
|
|
242
268
|
|
|
269
|
+
# Query a user's abstraction state
|
|
270
|
+
# @param user [String] Wallet address
|
|
271
|
+
# @return [String] Abstraction state (e.g., "unifiedAccount", "portfolioMargin", "disabled",
|
|
272
|
+
# "default", "dexAbstraction")
|
|
273
|
+
def user_abstraction(user)
|
|
274
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'userAbstraction', user: user })
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# Check user existence, activation fee, and sanctions status before a transfer
|
|
278
|
+
# @param user [String] Destination user address
|
|
279
|
+
# @param source [String] Source (funding) address
|
|
280
|
+
# @return [Hash] Keys: fee (String), isSanctioned (Boolean), userExists (Boolean),
|
|
281
|
+
# userHasSentTx (Boolean)
|
|
282
|
+
def pre_transfer_check(user, source)
|
|
283
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'preTransferCheck', user: user, source: source })
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# Check whether a user is a VIP
|
|
287
|
+
# @param user [String] Wallet address
|
|
288
|
+
# @return [Boolean, nil] True/false VIP status, or nil if the user is unknown
|
|
289
|
+
def vip?(user)
|
|
290
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'isVip', user: user })
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Retrieve addresses of currently liquidatable users
|
|
294
|
+
# @return [Array] Array of liquidatable user entries
|
|
295
|
+
def liquidatable
|
|
296
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'liquidatable' })
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Retrieve validator performance summaries
|
|
300
|
+
# @return [Array] Array of validator entries with validator, signer, name, description,
|
|
301
|
+
# nRecentBlocks, stake, isJailed, unjailableAfter, isActive, commission, and stats
|
|
302
|
+
# (day/week/month uptime fraction, predicted APR, and sample count)
|
|
303
|
+
def validator_summaries
|
|
304
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'validatorSummaries' })
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Retrieve exchange system status information
|
|
308
|
+
# @return [Hash] Keys: time (Integer, ms since epoch), specialStatuses (Object or nil)
|
|
309
|
+
def exchange_status
|
|
310
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'exchangeStatus' })
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Retrieve maximum market order notionals per asset
|
|
314
|
+
# @return [Array<Array>] Array of [notional (Numeric), symbol (String)] tuples
|
|
315
|
+
def max_market_order_ntls
|
|
316
|
+
@client.post(Constants::INFO_ENDPOINT, { type: 'maxMarketOrderNtls' })
|
|
317
|
+
end
|
|
318
|
+
|
|
243
319
|
# ============================
|
|
244
320
|
# Info: Perpetuals
|
|
245
321
|
# ============================
|
data/lib/hyperliquid/version.rb
CHANGED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Hyperliquid Ruby SDK - Automated Integration Test Runner
|
|
5
|
+
#
|
|
6
|
+
# Same as test_all.rb but excludes tests unsuitable for unattended runs:
|
|
7
|
+
# - test_09_sub_account_lifecycle.rb: requires $100k traded volume on testnet to create sub-accounts
|
|
8
|
+
# - test_12_staking.rb: requires HYPE token balance (locking issues)
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# HYPERLIQUID_PRIVATE_KEY=0x... ruby scripts/test_automated.rb
|
|
12
|
+
|
|
13
|
+
SCRIPTS = [
|
|
14
|
+
'test_01_spot_market_roundtrip.rb',
|
|
15
|
+
'test_02_spot_limit_order.rb',
|
|
16
|
+
'test_03_perp_market_roundtrip.rb',
|
|
17
|
+
'test_04_perp_limit_order.rb',
|
|
18
|
+
'test_05_update_leverage.rb',
|
|
19
|
+
'test_06_modify_order.rb',
|
|
20
|
+
'test_07_market_close.rb',
|
|
21
|
+
'test_08_usd_class_transfer.rb',
|
|
22
|
+
'test_10_vault.rb',
|
|
23
|
+
'test_11_builder_fee.rb',
|
|
24
|
+
'test_13_ws_l2_book.rb',
|
|
25
|
+
'test_14_ws_candle.rb'
|
|
26
|
+
].freeze
|
|
27
|
+
|
|
28
|
+
def green(text)
|
|
29
|
+
"\e[32m#{text}\e[0m"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def red(text)
|
|
33
|
+
"\e[31m#{text}\e[0m"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
unless ENV['HYPERLIQUID_PRIVATE_KEY']
|
|
37
|
+
puts red('Error: Set HYPERLIQUID_PRIVATE_KEY environment variable')
|
|
38
|
+
puts 'Usage: HYPERLIQUID_PRIVATE_KEY=0x... ruby scripts/test_automated.rb'
|
|
39
|
+
exit 1
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
scripts_dir = __dir__
|
|
43
|
+
passed = []
|
|
44
|
+
failed = []
|
|
45
|
+
|
|
46
|
+
SCRIPTS.each do |script|
|
|
47
|
+
path = File.join(scripts_dir, script)
|
|
48
|
+
puts
|
|
49
|
+
puts '#' * 60
|
|
50
|
+
puts "# Running: #{script}"
|
|
51
|
+
puts '#' * 60
|
|
52
|
+
|
|
53
|
+
success = system(RbConfig.ruby, path)
|
|
54
|
+
|
|
55
|
+
if success
|
|
56
|
+
passed << script
|
|
57
|
+
else
|
|
58
|
+
failed << script
|
|
59
|
+
puts red("!!! #{script} exited with error !!!")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
puts
|
|
64
|
+
puts '=' * 60
|
|
65
|
+
puts 'INTEGRATION TEST SUMMARY'
|
|
66
|
+
puts '=' * 60
|
|
67
|
+
puts
|
|
68
|
+
puts "Passed: #{passed.length}/#{SCRIPTS.length}"
|
|
69
|
+
passed.each { |s| puts green(" [PASS] #{s}") }
|
|
70
|
+
if failed.any?
|
|
71
|
+
puts
|
|
72
|
+
puts "Failed: #{failed.length}/#{SCRIPTS.length}"
|
|
73
|
+
failed.each { |s| puts red(" [FAIL] #{s}") }
|
|
74
|
+
end
|
|
75
|
+
puts
|
|
76
|
+
puts 'Check your testnet wallet for trade history:'
|
|
77
|
+
puts 'https://app.hyperliquid-testnet.xyz'
|
|
78
|
+
puts
|
|
79
|
+
|
|
80
|
+
exit(failed.empty? ? 0 : 1)
|
data/scripts/test_helpers.rb
CHANGED
|
@@ -49,7 +49,13 @@ end
|
|
|
49
49
|
def dump_status(result)
|
|
50
50
|
return unless result.is_a?(Hash)
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
response = result['response']
|
|
53
|
+
return unless response.is_a?(Hash)
|
|
54
|
+
|
|
55
|
+
data = response['data']
|
|
56
|
+
return unless data.is_a?(Hash)
|
|
57
|
+
|
|
58
|
+
status = data.dig('statuses', 0)
|
|
53
59
|
return unless status
|
|
54
60
|
|
|
55
61
|
puts " API status: #{status.inspect}"
|
|
@@ -60,7 +66,9 @@ def check_result(result, operation)
|
|
|
60
66
|
|
|
61
67
|
return false if api_error?(result)
|
|
62
68
|
|
|
63
|
-
|
|
69
|
+
response = result['response']
|
|
70
|
+
data = response.is_a?(Hash) ? response['data'] : nil
|
|
71
|
+
status = data.is_a?(Hash) ? data.dig('statuses', 0) : nil
|
|
64
72
|
|
|
65
73
|
if status.is_a?(Hash) && status['error']
|
|
66
74
|
$test_failed = true
|
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.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- carter2099
|
|
@@ -131,6 +131,7 @@ files:
|
|
|
131
131
|
- scripts/test_13_ws_l2_book.rb
|
|
132
132
|
- scripts/test_14_ws_candle.rb
|
|
133
133
|
- scripts/test_all.rb
|
|
134
|
+
- scripts/test_automated.rb
|
|
134
135
|
- scripts/test_helpers.rb
|
|
135
136
|
- sig/hyperliquid.rbs
|
|
136
137
|
- test_integration.rb
|