Class: Honeymaker::Clients::Hyperliquid

Inherits:
Honeymaker::Client show all
Defined in:
lib/honeymaker/clients/hyperliquid.rb

Constant Summary collapse

URL =
"https://api.hyperliquid.xyz"
RATE_LIMITS =
{ default: 200, orders: 200 }.freeze

Constants inherited from Honeymaker::Client

Honeymaker::Client::OPTIONS

Instance Attribute Summary

Attributes inherited from Honeymaker::Client

#api_key, #api_secret

Instance Method Summary collapse

Methods inherited from Honeymaker::Client

rate_limits, #validate

Constructor Details

#initialize(api_key: nil, api_secret: nil, proxy: nil, logger: nil) ⇒ Hyperliquid

Returns a new instance of Hyperliquid.



9
10
11
# File 'lib/honeymaker/clients/hyperliquid.rb', line 9

def initialize(api_key: nil, api_secret: nil, proxy: nil, logger: nil)
  super
end

Instance Method Details

#all_midsObject



25
26
27
# File 'lib/honeymaker/clients/hyperliquid.rb', line 25

def all_mids
  ({ type: "allMids" })
end

#cancel(coin:, oid:) ⇒ Object



114
115
116
117
118
# File 'lib/honeymaker/clients/hyperliquid.rb', line 114

def cancel(coin:, oid:)
  with_rescue do
    exchange_client.cancel(coin, oid)
  end
end

#candles_snapshot(coin:, interval:, start_time:, end_time:) ⇒ Object



38
39
40
# File 'lib/honeymaker/clients/hyperliquid.rb', line 38

def candles_snapshot(coin:, interval:, start_time:, end_time:)
  ({ type: "candleSnapshot", req: { coin: coin, interval: interval, startTime: start_time, endTime: end_time } })
end

#get_balances(user: nil) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/honeymaker/clients/hyperliquid.rb', line 42

def get_balances(user: nil)
  user ||= @api_key
  result = spot_clearinghouse_state(user: user)
  return result if result.failure?

  balances = {}
  (result.data["balances"] || []).each do |balance|
    symbol = balance["coin"]
    total = BigDecimal((balance["total"] || "0").to_s)
    hold = BigDecimal((balance["hold"] || "0").to_s)
    free = total - hold
    next if free.zero? && hold.zero?
    balances[symbol] = { free: free, locked: hold }
  end

  Result::Success.new(balances)
end

#l2_book(coin:) ⇒ Object



34
35
36
# File 'lib/honeymaker/clients/hyperliquid.rb', line 34

def l2_book(coin:)
  ({ type: "l2Book", coin: coin })
end

#open_orders(user:) ⇒ Object



89
90
91
# File 'lib/honeymaker/clients/hyperliquid.rb', line 89

def open_orders(user:)
  ({ type: "openOrders", user: user })
end

#order(coin:, is_buy:, size:, limit_px:, order_type: { limit: { tif: "Gtc" } }) ⇒ Object

— Trading (requires hyperliquid-rb gem) —



108
109
110
111
112
# File 'lib/honeymaker/clients/hyperliquid.rb', line 108

def order(coin:, is_buy:, size:, limit_px:, order_type: { limit: { tif: "Gtc" } })
  with_rescue do
    exchange_client.order(coin, is_buy: is_buy, sz: size, limit_px: limit_px, order_type: order_type)
  end
end

#order_status(user:, oid:) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/honeymaker/clients/hyperliquid.rb', line 60

def order_status(user:, oid:)
  result = ({ type: "orderStatus", user: user, oid: oid })
  return result if result.failure?

  raw = result.data
  order = raw["order"] || {}
  fills = raw["fills"] || []
  status_str = raw["status"]

  coin = order["coin"]
  side = order["side"] == "B" ? :buy : :sell
  limit_price = BigDecimal((order["limitPx"] || "0").to_s)
  ordered_size = BigDecimal((order["sz"] || "0").to_s)

  amount_exec = fills.sum { |f| BigDecimal(f["sz"].to_s) }
  quote_amount_exec = fills.sum { |f| BigDecimal(f["px"].to_s) * BigDecimal(f["sz"].to_s) }
  avg_price = amount_exec.positive? ? (quote_amount_exec / amount_exec) : limit_price
  avg_price = nil if avg_price.zero?

  status = parse_order_status(status_str)

  Result::Success.new({
    order_id: "#{coin}-#{oid}",
    status: status, side: side, order_type: :limit,
    price: avg_price, amount: ordered_size, quote_amount: nil,
    amount_exec: amount_exec, quote_amount_exec: quote_amount_exec, raw: raw
  })
end

#spot_balances(user: nil) ⇒ Object



29
30
31
32
# File 'lib/honeymaker/clients/hyperliquid.rb', line 29

def spot_balances(user: nil)
  user ||= @api_key
  spot_clearinghouse_state(user: user)
end

#spot_clearinghouse_state(user:) ⇒ Object



21
22
23
# File 'lib/honeymaker/clients/hyperliquid.rb', line 21

def spot_clearinghouse_state(user:)
  ({ type: "spotClearinghouseState", user: user })
end

#spot_metaObject



13
14
15
# File 'lib/honeymaker/clients/hyperliquid.rb', line 13

def spot_meta
  ({ type: "spotMeta" })
end

#spot_meta_and_asset_ctxsObject



17
18
19
# File 'lib/honeymaker/clients/hyperliquid.rb', line 17

def spot_meta_and_asset_ctxs
  ({ type: "spotMetaAndAssetCtxs" })
end

#user_fills(user:, start_time: nil, end_time: nil) ⇒ Object



93
94
95
96
97
98
# File 'lib/honeymaker/clients/hyperliquid.rb', line 93

def user_fills(user:, start_time: nil, end_time: nil)
  body = { type: "userFills", user: user }
  body[:startTime] = start_time if start_time
  body[:endTime] = end_time if end_time
  (body)
end

#user_fills_by_time(user:, start_time:, end_time: nil) ⇒ Object



100
101
102
103
104
# File 'lib/honeymaker/clients/hyperliquid.rb', line 100

def user_fills_by_time(user:, start_time:, end_time: nil)
  body = { type: "userFillsByTime", user: user, startTime: start_time }
  body[:endTime] = end_time if end_time
  (body)
end

#user_funding(user:, start_time:, end_time: nil) ⇒ Object

— Futures —



122
123
124
125
126
# File 'lib/honeymaker/clients/hyperliquid.rb', line 122

def user_funding(user:, start_time:, end_time: nil)
  body = { type: "userFunding", user: user, startTime: start_time }
  body[:endTime] = end_time if end_time
  (body)
end

#user_non_funding_ledger_updates(user:, start_time:, end_time: nil) ⇒ Object



128
129
130
131
132
# File 'lib/honeymaker/clients/hyperliquid.rb', line 128

def user_non_funding_ledger_updates(user:, start_time:, end_time: nil)
  body = { type: "userNonFundingLedgerUpdates", user: user, startTime: start_time }
  body[:endTime] = end_time if end_time
  (body)
end