hyperliquid 1.0.0 → 1.0.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: 7c9ed1fef8ad29ab90cbc1ba13a6dc7ceed9267ff98ec97ed6748f71e1ff8289
4
- data.tar.gz: 10268ae8868d6b46a1a91a853c80f5009b7586d8bed449488ec1db2923a6a3ad
3
+ metadata.gz: 1e1cb7c8ae1c1b83ab34eaba6f6bf9ce34b620ca1af4500912d62e54d75a95ab
4
+ data.tar.gz: 9d026ad803f2fe0d2983c3dd242ee5d901cf56677e7c32cf756b5da38eb39c68
5
5
  SHA512:
6
- metadata.gz: ab9e06936e8a3417d074f9102463d309c5c7527f945a6165a592ff57124772ce946248b9d6582a281071fc0520fd42136bce3a00cf62e60af02fc1cd3e1ecaaa
7
- data.tar.gz: 665b93a26551b493309a14aa29d4a795d5e701a54bd55ba66bbbaa3fc20cc30eca6b98224e0bd3bfc538ab87884479918a95fccf49eece876347b61d4914b850
6
+ metadata.gz: 99a8f5cf7847c9236f3b4b48cfb83734ecb6ae8b7679d8d5cc1aef003b1a510df3edefdf9f6481d7bdb4ff7d22546549247b9aa17771e95d58307eb93bdd0448
7
+ data.tar.gz: d649b243e0aab4ae25ffcd3c452878cce1be94dd86dde1aeb151b9478bba1c42fe534ec485f4ddd896e0f358b705d4b063180b26e23fcf7d09d42a9f71ffbc64
data/.rubocop.yml CHANGED
@@ -5,6 +5,7 @@ AllCops:
5
5
  Exclude:
6
6
  - 'test_*.rb' # Exclude ad-hoc integration test scripts
7
7
  - 'scripts/**/*' # Exclude integration test scripts
8
+ - 'local/**/*' # Exclude local test scripts
8
9
  - 'vendor/**/*' # Exclude vendored gems (CI bundles here)
9
10
 
10
11
  # Allow longer methods for complex logic
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Ruby Hyperliquid SDK Changelog]
2
2
 
3
+ ## [1.0.1] - 2026-02-03
4
+
5
+ - Minor refactors to reduce method complexity
6
+
3
7
  ## [1.0.0] - 2026-02-03
4
8
 
5
9
  ### WebSocket Support
@@ -355,34 +355,18 @@ module Hyperliquid
355
355
  # @return [Hash] Order response
356
356
  def market_close(coin:, size: nil, slippage: DEFAULT_SLIPPAGE, cloid: nil, vault_address: nil, builder: nil)
357
357
  address = vault_address || @signer.address
358
- dex_prefix = extract_dex_prefix(coin)
359
- state = dex_prefix ? @info.user_state(address, dex: dex_prefix) : @info.user_state(address)
360
-
361
- position = state['assetPositions']&.find do |pos|
362
- pos.dig('position', 'coin') == coin
363
- end
358
+ position = find_position(coin, address)
364
359
  raise ArgumentError, "No open position found for #{coin}" unless position
365
360
 
366
361
  szi = position.dig('position', 'szi').to_f
367
362
  is_buy = szi.negative?
368
363
  close_size = size || szi.abs
369
-
370
- mids = dex_prefix ? @info.all_mids(dex: dex_prefix) : @info.all_mids
371
- mid = mids[coin]&.to_f
372
- raise ArgumentError, "Unknown asset or no price available: #{coin}" unless mid&.positive?
373
-
374
- slippage_price = calculate_slippage_price(coin, mid, is_buy, slippage)
364
+ slippage_price = calculate_slippage_price(coin, get_mid_price(coin), is_buy, slippage)
375
365
 
376
366
  order(
377
- coin: coin,
378
- is_buy: is_buy,
379
- size: close_size,
380
- limit_px: slippage_price,
381
- order_type: { limit: { tif: 'Ioc' } },
382
- reduce_only: true,
383
- cloid: cloid,
384
- vault_address: vault_address,
385
- builder: builder
367
+ coin: coin, is_buy: is_buy, size: close_size, limit_px: slippage_price,
368
+ order_type: { limit: { tif: 'Ioc' } }, reduce_only: true,
369
+ cloid: cloid, vault_address: vault_address, builder: builder
386
370
  )
387
371
  end
388
372
 
@@ -718,6 +702,23 @@ module Hyperliquid
718
702
  (Time.now.to_f * 1000).to_i
719
703
  end
720
704
 
705
+ # Find a position for a coin
706
+ def find_position(coin, address)
707
+ dex_prefix = extract_dex_prefix(coin)
708
+ state = dex_prefix ? @info.user_state(address, dex: dex_prefix) : @info.user_state(address)
709
+ state['assetPositions']&.find { |pos| pos.dig('position', 'coin') == coin }
710
+ end
711
+
712
+ # Get mid price for a coin
713
+ def get_mid_price(coin)
714
+ dex_prefix = extract_dex_prefix(coin)
715
+ mids = dex_prefix ? @info.all_mids(dex: dex_prefix) : @info.all_mids
716
+ mid = mids[coin]&.to_f
717
+ raise ArgumentError, "Unknown asset or no price available: #{coin}" unless mid&.positive?
718
+
719
+ mid
720
+ end
721
+
721
722
  # Get asset index for a coin symbol
722
723
  # @param coin [String] Asset symbol (supports HIP-3 prefixed names like "xyz:GOLD")
723
724
  # @return [Integer] Asset index
@@ -766,30 +767,27 @@ module Hyperliquid
766
767
  @asset_cache = { indices: {}, metadata: {} }
767
768
  @loaded_dexes = Set.new
768
769
 
769
- # Load perpetual assets from default dex
770
- meta = @info.meta
771
- meta['universe'].each_with_index do |asset, index|
772
- name = asset['name']
773
- @asset_cache[:indices][name] = index
774
- @asset_cache[:metadata][name] = {
775
- sz_decimals: asset['szDecimals'],
776
- is_spot: false
777
- }
770
+ load_perp_assets
771
+ load_spot_assets
772
+ end
773
+
774
+ def load_perp_assets
775
+ @info.meta['universe'].each_with_index do |asset, index|
776
+ cache_asset(asset['name'], index, asset['szDecimals'], is_spot: false)
778
777
  end
778
+ end
779
779
 
780
- # Load spot assets (index starts at SPOT_ASSET_THRESHOLD)
781
- spot_meta = @info.spot_meta
782
- spot_meta['universe'].each_with_index do |pair, index|
783
- name = pair['name']
784
- spot_index = index + SPOT_ASSET_THRESHOLD
785
- @asset_cache[:indices][name] = spot_index
786
- @asset_cache[:metadata][name] = {
787
- sz_decimals: pair['szDecimals'] || 0,
788
- is_spot: true
789
- }
780
+ def load_spot_assets
781
+ @info.spot_meta['universe'].each_with_index do |pair, index|
782
+ cache_asset(pair['name'], index + SPOT_ASSET_THRESHOLD, pair['szDecimals'] || 0, is_spot: true)
790
783
  end
791
784
  end
792
785
 
786
+ def cache_asset(name, index, sz_decimals, is_spot:, dex: nil)
787
+ @asset_cache[:indices][name] = index
788
+ @asset_cache[:metadata][name] = { sz_decimals: sz_decimals, is_spot: is_spot, dex: dex }.compact
789
+ end
790
+
793
791
  # Load asset metadata for a HIP-3 dex
794
792
  # HIP-3 asset IDs use formula: 100000 + perp_dex_index * 10000 + index_in_meta
795
793
  # @param dex [String] Dex name (e.g., "xyz")
@@ -803,17 +801,9 @@ module Hyperliquid
803
801
  perp_dex_index = perp_dexs.index { |d| d && d['name'] == dex }
804
802
  return unless perp_dex_index
805
803
 
806
- meta = @info.meta(dex: dex)
807
- meta['universe']&.each_with_index do |asset, index|
808
- name = asset['name']
809
- # HIP-3 asset ID: 100000 + perp_dex_index * 10000 + index_in_meta
804
+ @info.meta(dex: dex)['universe']&.each_with_index do |asset, index|
810
805
  hip3_asset_id = 100_000 + (perp_dex_index * 10_000) + index
811
- @asset_cache[:indices][name] = hip3_asset_id
812
- @asset_cache[:metadata][name] = {
813
- sz_decimals: asset['szDecimals'],
814
- is_spot: false,
815
- dex: dex
816
- }
806
+ cache_asset(asset['name'], hip3_asset_id, asset['szDecimals'], is_spot: false, dex: dex)
817
807
  end
818
808
  end
819
809
 
@@ -12,7 +12,8 @@ module Hyperliquid
12
12
  # ============================
13
13
 
14
14
  # Get all market mid prices
15
- # @param dex [String, nil] Optional perp dex name (defaults to first perp dex; spot mids only included with first perp dex)
15
+ # @param dex [String, nil] Optional perp dex name (defaults to first perp dex;
16
+ # spot mids only included with first perp dex)
16
17
  # @return [Hash] Hash containing mid prices for all markets
17
18
  def all_mids(dex: nil)
18
19
  body = { type: 'allMids' }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hyperliquid
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.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: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - carter2099