perp-cli 0.14.2 → 0.15.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.
Files changed (313) hide show
  1. package/README.md +152 -13
  2. package/dist/agent-wallet/store.d.ts +3 -2
  3. package/dist/agent-wallet/store.js +2 -2
  4. package/dist/api/public/hyperliquid.js +4 -0
  5. package/dist/api/public/pacifica.js +83 -13
  6. package/dist/api/public/urls.d.ts +2 -0
  7. package/dist/api/public/urls.js +3 -0
  8. package/dist/arb/utils.d.ts +1 -2
  9. package/dist/arb/utils.js +1 -2
  10. package/dist/bot/apex/pulse.js +3 -0
  11. package/dist/bot/apex/radar.js +2 -1
  12. package/dist/bot/engine.d.ts +10 -1
  13. package/dist/bot/engine.js +14 -6
  14. package/dist/bot/indicators.d.ts +7 -0
  15. package/dist/bot/indicators.js +16 -0
  16. package/dist/bot/perp-order.d.ts +4 -4
  17. package/dist/bot/perp-order.js +5 -5
  18. package/dist/bot/quarantine.d.ts +1 -1
  19. package/dist/bot/quarantine.js +1 -1
  20. package/dist/bot/strategies/apex-strategy.js +3 -2
  21. package/dist/bot/strategies/engine-mm.js +6 -5
  22. package/dist/bot/strategies/funding-arb-strategy.js +9 -9
  23. package/dist/bot/strategies/funding-arb-utils.d.ts +15 -2
  24. package/dist/bot/strategies/funding-arb-utils.js +43 -24
  25. package/dist/bot/strategies/funding-auto.js +2 -2
  26. package/dist/bot/strategies/liquidation-mm.d.ts +1 -0
  27. package/dist/bot/strategies/liquidation-mm.js +8 -2
  28. package/dist/bot/strategies/momentum-breakout.d.ts +1 -0
  29. package/dist/bot/strategies/momentum-breakout.js +11 -3
  30. package/dist/bot/strategies/spot-perp-arb-strategy.js +23 -12
  31. package/dist/bot/strategies/spot-perp-executor.d.ts +1 -1
  32. package/dist/bot/strategies/spot-perp-executor.js +1 -1
  33. package/dist/bot/strategy-types.d.ts +2 -1
  34. package/dist/bot/tui/BotDashboard.d.ts +1 -1
  35. package/dist/bot/tui/BotDashboard.js +1 -1
  36. package/dist/cache.js +12 -6
  37. package/dist/cli-program.d.ts +15 -0
  38. package/dist/cli-program.js +125 -5
  39. package/dist/commands/agent-import.d.ts +7 -0
  40. package/dist/commands/agent-import.js +30 -1
  41. package/dist/commands/agent.d.ts +6 -3
  42. package/dist/commands/agent.js +160 -12
  43. package/dist/commands/arb/index.js +4 -4
  44. package/dist/commands/arb-auto.js +21 -17
  45. package/dist/commands/arb.d.ts +12 -0
  46. package/dist/commands/arb.js +61 -143
  47. package/dist/commands/bot.js +1 -1
  48. package/dist/commands/builder.js +1 -1
  49. package/dist/commands/funds.js +113 -3
  50. package/dist/commands/init.d.ts +1 -1
  51. package/dist/commands/init.js +27 -7
  52. package/dist/commands/manage.js +23 -21
  53. package/dist/commands/market.js +168 -36
  54. package/dist/commands/options.d.ts +9 -0
  55. package/dist/commands/options.js +134 -0
  56. package/dist/commands/pacifica-earn.d.ts +5 -0
  57. package/dist/commands/pacifica-earn.js +468 -0
  58. package/dist/commands/pacifica-orders.d.ts +14 -0
  59. package/dist/commands/pacifica-orders.js +142 -0
  60. package/dist/commands/portfolio.js +32 -47
  61. package/dist/commands/rebalance.d.ts +1 -0
  62. package/dist/commands/rebalance.js +15 -0
  63. package/dist/commands/risk.d.ts +11 -2
  64. package/dist/commands/risk.js +39 -44
  65. package/dist/commands/trade.d.ts +1 -0
  66. package/dist/commands/trade.js +63 -58
  67. package/dist/commands/wallet.js +1 -1
  68. package/dist/config.d.ts +2 -2
  69. package/dist/config.js +15 -4
  70. package/dist/constants.js +6 -0
  71. package/dist/dashboard/server.js +1 -1
  72. package/dist/dashboard/ui.js +1 -1
  73. package/dist/errors.d.ts +24 -1
  74. package/dist/errors.js +25 -3
  75. package/dist/exchanges/arcus/adapter.d.ts +7 -7
  76. package/dist/exchanges/arcus/adapter.js +12 -12
  77. package/dist/exchanges/arcus/agent.d.ts +1 -1
  78. package/dist/exchanges/arcus/agent.js +1 -1
  79. package/dist/exchanges/arcus/client.js +1 -1
  80. package/dist/exchanges/arcus/signing.d.ts +2 -3
  81. package/dist/exchanges/arcus/signing.js +1 -1
  82. package/dist/exchanges/arcus/spot-chain.d.ts +1 -1
  83. package/dist/exchanges/arcus/spot-chain.js +1 -1
  84. package/dist/exchanges/arcus/spot-router.d.ts +1 -1
  85. package/dist/exchanges/arcus/spot-router.js +2 -2
  86. package/dist/exchanges/arcus/spot.d.ts +2 -3
  87. package/dist/exchanges/arcus/spot.js +2 -3
  88. package/dist/exchanges/aster-spot.d.ts +3 -3
  89. package/dist/exchanges/aster-spot.js +6 -9
  90. package/dist/exchanges/aster-typed-data.d.ts +1 -1
  91. package/dist/exchanges/aster-typed-data.js +1 -1
  92. package/dist/exchanges/aster.d.ts +9 -4
  93. package/dist/exchanges/aster.js +125 -55
  94. package/dist/exchanges/builder-fee.d.ts +1 -1
  95. package/dist/exchanges/builder-fee.js +13 -2
  96. package/dist/exchanges/canonical-symbols.d.ts +1 -2
  97. package/dist/exchanges/canonical-symbols.js +26 -2
  98. package/dist/exchanges/derive/client.d.ts +37 -0
  99. package/dist/exchanges/derive/client.js +135 -0
  100. package/dist/exchanges/derive/options.d.ts +68 -0
  101. package/dist/exchanges/derive/options.js +360 -0
  102. package/dist/exchanges/extended/adapter.d.ts +82 -0
  103. package/dist/exchanges/extended/adapter.js +179 -0
  104. package/dist/exchanges/extended/client.d.ts +38 -0
  105. package/dist/exchanges/extended/client.js +88 -0
  106. package/dist/exchanges/extended/public.d.ts +130 -0
  107. package/dist/exchanges/extended/public.js +429 -0
  108. package/dist/exchanges/grvt/adapter.d.ts +86 -0
  109. package/dist/exchanges/grvt/adapter.js +206 -0
  110. package/dist/exchanges/grvt/client.d.ts +25 -0
  111. package/dist/exchanges/grvt/client.js +86 -0
  112. package/dist/exchanges/grvt/public.d.ts +151 -0
  113. package/dist/exchanges/grvt/public.js +438 -0
  114. package/dist/exchanges/hyperliquid-spot.d.ts +1 -1
  115. package/dist/exchanges/hyperliquid-spot.js +5 -5
  116. package/dist/exchanges/hyperliquid.d.ts +22 -16
  117. package/dist/exchanges/hyperliquid.js +80 -55
  118. package/dist/exchanges/index.d.ts +1 -1
  119. package/dist/exchanges/index.js +1 -1
  120. package/dist/exchanges/interface.d.ts +97 -8
  121. package/dist/exchanges/interface.js +19 -2
  122. package/dist/exchanges/ioc-outcome.d.ts +1 -1
  123. package/dist/exchanges/ioc-outcome.js +1 -1
  124. package/dist/exchanges/legacy-trading-v2.d.ts +2 -2
  125. package/dist/exchanges/legacy-trading-v2.js +7 -2
  126. package/dist/exchanges/lighter-public.d.ts +2 -2
  127. package/dist/exchanges/lighter-public.js +2 -2
  128. package/dist/exchanges/lighter-signer.d.ts +1 -1
  129. package/dist/exchanges/lighter-signer.js +1 -1
  130. package/dist/exchanges/lighter-spot.d.ts +3 -4
  131. package/dist/exchanges/lighter-spot.js +6 -7
  132. package/dist/exchanges/lighter.d.ts +11 -11
  133. package/dist/exchanges/lighter.js +28 -14
  134. package/dist/exchanges/ondo/adapter.d.ts +5 -6
  135. package/dist/exchanges/ondo/adapter.js +16 -14
  136. package/dist/exchanges/ondo/agent.d.ts +1 -1
  137. package/dist/exchanges/ondo/agent.js +1 -1
  138. package/dist/exchanges/ondo/client.d.ts +1 -1
  139. package/dist/exchanges/ondo/client.js +2 -2
  140. package/dist/exchanges/ondo/public.d.ts +8 -1
  141. package/dist/exchanges/ondo/public.js +13 -2
  142. package/dist/exchanges/ondo/spot.d.ts +2 -2
  143. package/dist/exchanges/ondo/spot.js +3 -3
  144. package/dist/exchanges/options-interface.d.ts +158 -0
  145. package/dist/exchanges/options-interface.js +17 -0
  146. package/dist/exchanges/options-venues.d.ts +12 -0
  147. package/dist/exchanges/options-venues.js +35 -0
  148. package/dist/exchanges/pacifica-atomic.d.ts +211 -0
  149. package/dist/exchanges/pacifica-atomic.js +440 -0
  150. package/dist/exchanges/pacifica-decimal.d.ts +10 -0
  151. package/dist/exchanges/pacifica-decimal.js +51 -0
  152. package/dist/exchanges/pacifica-presigned.d.ts +53 -0
  153. package/dist/exchanges/pacifica-presigned.js +141 -0
  154. package/dist/exchanges/pacifica-print.d.ts +200 -0
  155. package/dist/exchanges/pacifica-print.js +417 -0
  156. package/dist/exchanges/pacifica-spot.d.ts +2 -2
  157. package/dist/exchanges/pacifica-spot.js +3 -3
  158. package/dist/exchanges/pacifica-typed-data.d.ts +1 -1
  159. package/dist/exchanges/pacifica-typed-data.js +1 -1
  160. package/dist/exchanges/pacifica-vaults.d.ts +121 -0
  161. package/dist/exchanges/pacifica-vaults.js +264 -0
  162. package/dist/exchanges/pacifica.d.ts +32 -5
  163. package/dist/exchanges/pacifica.js +114 -48
  164. package/dist/exchanges/precision.d.ts +3 -1
  165. package/dist/exchanges/precision.js +9 -2
  166. package/dist/exchanges/qfex/adapter.d.ts +18 -5
  167. package/dist/exchanges/qfex/adapter.js +32 -12
  168. package/dist/exchanges/qfex/agent.d.ts +1 -1
  169. package/dist/exchanges/qfex/agent.js +1 -1
  170. package/dist/exchanges/qfex/client.d.ts +1 -1
  171. package/dist/exchanges/qfex/client.js +1 -1
  172. package/dist/exchanges/qfex/errors.d.ts +1 -1
  173. package/dist/exchanges/qfex/errors.js +2 -2
  174. package/dist/exchanges/qfex/public.d.ts +3 -3
  175. package/dist/exchanges/qfex/public.js +3 -3
  176. package/dist/exchanges/qfex/signing.d.ts +2 -2
  177. package/dist/exchanges/qfex/signing.js +4 -5
  178. package/dist/exchanges/qfex/ws-transport.d.ts +2 -2
  179. package/dist/exchanges/qfex/ws-transport.js +3 -3
  180. package/dist/exchanges/rate-limiter.d.ts +1 -1
  181. package/dist/exchanges/rate-limiter.js +5 -2
  182. package/dist/exchanges/registry.d.ts +1 -1
  183. package/dist/exchanges/registry.js +1 -1
  184. package/dist/exchanges/risex/adapter.d.ts +148 -0
  185. package/dist/exchanges/risex/adapter.js +796 -0
  186. package/dist/exchanges/risex/agent.d.ts +154 -0
  187. package/dist/exchanges/risex/agent.js +384 -0
  188. package/dist/exchanges/risex/client.d.ts +47 -0
  189. package/dist/exchanges/risex/client.js +174 -0
  190. package/dist/exchanges/risex/nonce.d.ts +43 -0
  191. package/dist/exchanges/risex/nonce.js +212 -0
  192. package/dist/exchanges/risex/public.d.ts +64 -0
  193. package/dist/exchanges/risex/public.js +150 -0
  194. package/dist/exchanges/risex/session.d.ts +71 -0
  195. package/dist/exchanges/risex/session.js +171 -0
  196. package/dist/exchanges/risex/typed-data.d.ts +173 -0
  197. package/dist/exchanges/risex/typed-data.js +240 -0
  198. package/dist/exchanges/risex/units.d.ts +29 -0
  199. package/dist/exchanges/risex/units.js +104 -0
  200. package/dist/exchanges/slippage.d.ts +1 -1
  201. package/dist/exchanges/slippage.js +1 -1
  202. package/dist/exchanges/spot-factory.d.ts +3 -3
  203. package/dist/exchanges/spot-factory.js +7 -7
  204. package/dist/exchanges/spot-interface.d.ts +5 -5
  205. package/dist/exchanges/spot-interface.js +2 -2
  206. package/dist/exchanges/spot-result.d.ts +3 -3
  207. package/dist/exchanges/spot-result.js +3 -3
  208. package/dist/exchanges/trading-v2.d.ts +3 -3
  209. package/dist/exchanges/trading-v2.js +9 -6
  210. package/dist/exchanges/txflow/adapter.d.ts +54 -0
  211. package/dist/exchanges/txflow/adapter.js +118 -0
  212. package/dist/exchanges/txflow/client.d.ts +47 -0
  213. package/dist/exchanges/txflow/client.js +153 -0
  214. package/dist/exchanges/txflow/public.d.ts +76 -0
  215. package/dist/exchanges/txflow/public.js +284 -0
  216. package/dist/exchanges/unknown-symbol.d.ts +29 -0
  217. package/dist/exchanges/unknown-symbol.js +51 -0
  218. package/dist/exchanges/variational/adapter.d.ts +71 -0
  219. package/dist/exchanges/variational/adapter.js +137 -0
  220. package/dist/exchanges/variational/client.d.ts +21 -0
  221. package/dist/exchanges/variational/client.js +66 -0
  222. package/dist/exchanges/variational/public.d.ts +126 -0
  223. package/dist/exchanges/variational/public.js +430 -0
  224. package/dist/exchanges/venue-types.d.ts +6 -7
  225. package/dist/exchanges/venue-types.js +2 -2
  226. package/dist/exchanges/venue.d.ts +51 -8
  227. package/dist/exchanges/venue.js +54 -4
  228. package/dist/exchanges/venues/arcus.d.ts +1 -2
  229. package/dist/exchanges/venues/arcus.js +5 -4
  230. package/dist/exchanges/venues/aster.d.ts +2 -2
  231. package/dist/exchanges/venues/aster.js +6 -4
  232. package/dist/exchanges/venues/create-helpers.d.ts +1 -1
  233. package/dist/exchanges/venues/create-helpers.js +3 -3
  234. package/dist/exchanges/venues/extended.d.ts +21 -0
  235. package/dist/exchanges/venues/extended.js +96 -0
  236. package/dist/exchanges/venues/grvt.d.ts +30 -0
  237. package/dist/exchanges/venues/grvt.js +98 -0
  238. package/dist/exchanges/venues/hyperliquid.d.ts +2 -2
  239. package/dist/exchanges/venues/hyperliquid.js +10 -8
  240. package/dist/exchanges/venues/index.d.ts +7 -2
  241. package/dist/exchanges/venues/index.js +8 -2
  242. package/dist/exchanges/venues/lighter-family.d.ts +7 -9
  243. package/dist/exchanges/venues/lighter-family.js +9 -11
  244. package/dist/exchanges/venues/lighter-rh.d.ts +2 -2
  245. package/dist/exchanges/venues/lighter-rh.js +7 -5
  246. package/dist/exchanges/venues/lighter.d.ts +1 -1
  247. package/dist/exchanges/venues/lighter.js +5 -3
  248. package/dist/exchanges/venues/ondo.d.ts +1 -1
  249. package/dist/exchanges/venues/ondo.js +5 -3
  250. package/dist/exchanges/venues/pacifica.d.ts +2 -2
  251. package/dist/exchanges/venues/pacifica.js +6 -4
  252. package/dist/exchanges/venues/qfex.d.ts +1 -1
  253. package/dist/exchanges/venues/qfex.js +4 -2
  254. package/dist/exchanges/venues/risex-release.d.ts +14 -0
  255. package/dist/exchanges/venues/risex-release.js +14 -0
  256. package/dist/exchanges/venues/risex.d.ts +31 -0
  257. package/dist/exchanges/venues/risex.js +116 -0
  258. package/dist/exchanges/venues/txflow.d.ts +18 -0
  259. package/dist/exchanges/venues/txflow.js +77 -0
  260. package/dist/exchanges/venues/variational.d.ts +21 -0
  261. package/dist/exchanges/venues/variational.js +85 -0
  262. package/dist/execution-log.d.ts +1 -1
  263. package/dist/funding/legacy-public.d.ts +1 -1
  264. package/dist/funding/legacy-public.js +9 -4
  265. package/dist/funding/normalize.d.ts +1 -1
  266. package/dist/funding/normalize.js +1 -1
  267. package/dist/funding/rates.d.ts +44 -4
  268. package/dist/funding/rates.js +56 -12
  269. package/dist/index.js +7 -6
  270. package/dist/jobs.d.ts +1 -0
  271. package/dist/jobs.js +25 -1
  272. package/dist/landing.d.ts +2 -0
  273. package/dist/landing.js +1 -1
  274. package/dist/mcp-pacifica-earn.d.ts +9 -0
  275. package/dist/mcp-pacifica-earn.js +58 -0
  276. package/dist/mcp-server.js +113 -59
  277. package/dist/pacifica/client.d.ts +67 -4
  278. package/dist/pacifica/client.js +170 -8
  279. package/dist/pacifica/rate-limit.d.ts +144 -0
  280. package/dist/pacifica/rate-limit.js +267 -0
  281. package/dist/pacifica/types/order.d.ts +2 -1
  282. package/dist/plan-executor.js +7 -2
  283. package/dist/rebalance.js +1 -1
  284. package/dist/risk.d.ts +2 -1
  285. package/dist/risk.js +2 -4
  286. package/dist/settings.d.ts +32 -3
  287. package/dist/signer/ows-evm.d.ts +1 -1
  288. package/dist/signer/ows-evm.js +1 -1
  289. package/dist/smart-order.d.ts +1 -1
  290. package/dist/smart-order.js +1 -1
  291. package/dist/strategies/funding-arb.d.ts +1 -1
  292. package/dist/strategies/funding-arb.js +1 -1
  293. package/dist/trade-validator.d.ts +1 -1
  294. package/dist/trade-validator.js +9 -4
  295. package/dist/utils.d.ts +12 -3
  296. package/dist/utils.js +11 -3
  297. package/dist/venue-health.d.ts +40 -0
  298. package/dist/venue-health.js +75 -0
  299. package/dist/withdraw-gate.d.ts +1 -1
  300. package/dist/withdraw-gate.js +1 -1
  301. package/dist/ws/index.d.ts +959 -0
  302. package/dist/ws/index.js +4295 -0
  303. package/dist/ws/node.d.ts +975 -0
  304. package/dist/ws/node.js +4366 -0
  305. package/dist/ws/pacifica-instrument.d.ts +8 -0
  306. package/dist/ws/pacifica-instrument.js +8 -0
  307. package/dist/ws-cli/credentials.d.ts +62 -0
  308. package/dist/ws-cli/credentials.js +126 -0
  309. package/package.json +58 -10
  310. package/skills/perp-cli/SKILL.md +62 -9
  311. package/skills/perp-cli/references/agent-operations.md +7 -0
  312. package/skills/perp-cli/references/commands.md +76 -5
  313. package/skills/perp-cli/references/ws-library.md +492 -0
@@ -0,0 +1,438 @@
1
+ /**
2
+ * GRVT public market data — official Market Data REST API (api-docs.grvt.io/market_data_api/).
3
+ *
4
+ * Sources (all `POST https://market-data.grvt.io/full/v1/…`, no key):
5
+ * instruments {kind:["PERPETUAL"], is_active:true, limit} directory: instrument "BTC_USDT_Perp",
6
+ * base, quote, kind, settlement_period, tick_size, min_size, min_notional,
7
+ * funding_interval_hours (4 or 8, PER INSTRUMENT), asset_class (CRYPTO / EQUITY / COMMODITY),
8
+ * status. No leverage and no lot step (base_decimals is the signing multiplier, not a lot).
9
+ * ticker {instrument} one instrument per call (no bulk ticker exists): mark / index / last /
10
+ * best bid / best ask prices, open_interest (base), buy/sell_volume_24h_q (quote = USDT),
11
+ * funding_rate, next_funding_time (ns).
12
+ * margin_rules {instrument} risk_brackets → max_leverage of tier 1 (= maxLeverage) and the tiers.
13
+ *
14
+ * Mapping:
15
+ * - symbol = `base` ("BTC", "KPEPE"); venueSymbol = instrument ("BTC_USDT_Perp"); canonical via
16
+ * canonical-symbols.ts (crypto by ticker + denomination aliases, equity / etf by ticker,
17
+ * commodity explicit only). Pre-IPO markets (listed by GRVT as EQUITY) are preIpo → no canonical.
18
+ * - funding: `funding_rate` is the venue's INDICATIVE rate for the active interval (the interval
19
+ * ending at next_funding_time) — kind "predicted", a moving estimate. Its unit is PERCENT per the
20
+ * market's funding interval: settled history (/full/v1/funding, "percentage points") prints the
21
+ * same magnitude (BTC 0.01 = HL-style 0.01 %/8 h baseline; ticker 0.0063). The ticker schema says
22
+ * "centibeeps", which would make every rate 100× smaller than its own settled prints — not used.
23
+ * Converted to a fraction per interval by an exact × 0.01; basis perHours = funding_interval_hours.
24
+ * - volume24h = buy + sell 24 h quote volume (the docs' "24 hour volume"), exact decimal sum.
25
+ * - unknown / absent values are null; a ticker without a mark price, or whose read fails, drops
26
+ * that market (warned by name).
27
+ * - request budget: the registry path (fetchMarkets / fetchFundingRates) is price-only
28
+ * (instruments + one ticker per market, both reused in-process for 15 s); margin_rules (leverage)
29
+ * only for `market list` / `info`, file-cached 6 h per network.
30
+ */
31
+ import { getCached, invalidateCache, setCached } from "../../cache.js";
32
+ import { PerpError, extractErrorMessage } from "../../errors.js";
33
+ import { canonicalFor } from "../canonical-symbols.js";
34
+ import { addDecimal, mulDecimal } from "../precision.js";
35
+ import { symbolNotFound } from "../unknown-symbol.js";
36
+ import { networkConfig } from "../venue.js";
37
+ import { grvtVenue } from "../venues/grvt.js";
38
+ import { grvtShapeError, GrvtClient } from "./client.js";
39
+ /** Requests in flight at once for the per-instrument fan-out (ticker / margin_rules). */
40
+ export const GRVT_FANOUT_CONCURRENCY = 8;
41
+ /** In-process reuse of the directory and of each ticker (repeated MCP / dashboard reads). */
42
+ export const GRVT_SHORT_TTL_MS = 15_000;
43
+ /** margin_rules brackets change rarely: file cache (src/cache.ts), per network. */
44
+ export const GRVT_MARGIN_TTL_MS = 6 * 3_600_000;
45
+ /**
46
+ * GRVT EQUITY markets that may match other venues by ticker identity: exchange-listed shares and
47
+ * ETFs (or, for Korean / HK listings, the plain company name every venue uses). Reviewed against
48
+ * the live list 2026-10-19. Any other EQUITY market is explicit-only (canonical null) — a new
49
+ * pre-IPO or synthetic listing is never matched by a look-alike ticker.
50
+ */
51
+ const MATCHABLE_EQUITY = new Set([
52
+ "AAOI", "AAPL", "AMAT", "AMD", "AMZN", "ARM", "ASML", "ASTS", "AVGO", "AXTI", "BABA", "BE", "BMNR", "BX", "COHR", "COIN",
53
+ "CRCL", "CRDO", "CRM", "CRWD", "CRWV", "CSCO", "DELL", "DIS", "FLNC", "GLW", "GOOGL", "GS", "HANMI", "HD", "HOOD", "HYUNDAI",
54
+ "IBM", "INTC", "IREN", "JPM", "LGELECTRONICS", "LITE", "LLY", "META", "MINIMAX", "MRNA", "MRVL", "MSFT", "MSTR", "MU", "NAVER",
55
+ "NBIS", "NFLX", "NOK", "NOW", "NVDA", "NVO", "ONDS", "ORCL", "PLTR", "QCOM", "RKLB", "SAMSUNG", "SKHYNIX", "SMCI", "SNDK",
56
+ "STRC", "TSLA", "TSM", "UBER", "USAR", "V", "WDC", "WMT",
57
+ ]);
58
+ /** Exchange-traded funds among GRVT's EQUITY markets (matchable by ticker, labelled etf). */
59
+ const ETF = new Set([
60
+ "SPY", "QQQ", "IWM", "EWJ", "EWT", "EWY", "EWZ", "SOXL", "TQQQ", "SQQQ", "UVXY", "URNM", "XLE", "KORU", "KODEX200",
61
+ ]);
62
+ /** Pre-IPO private companies GRVT lists as EQUITY (a private valuation, not a listed share). */
63
+ const PRE_IPO = new Set(["ANTHROPIC", "OPENAI", "SPACEX"]);
64
+ /**
65
+ * Reviewed EQUITY markets that stay explicit-only without a warning: tickers that are not a plain
66
+ * exchange ticker or are ambiguous across venues (BRKB vs BRK.B, SKHY next to SKHYNIX, SAMSUNGEM,
67
+ * DRAM, …). Unreviewed tickers are explicit-only too, but warned once per process.
68
+ */
69
+ const EXPLICIT_ONLY_EQUITY = new Set([
70
+ "BBX", "BRKB", "CBRS", "DRAM", "KSTR", "PAYP", "QNTX", "SAMSUNGEM", "SKHY", "STXX",
71
+ ]);
72
+ const warnedUnreviewed = new Set();
73
+ const DEC = /^-?\d+(\.\d+)?$/;
74
+ function decOrNull(v) {
75
+ return typeof v === "string" && DEC.test(v) ? v : null;
76
+ }
77
+ function positiveDec(v, what) {
78
+ if (typeof v !== "string" || !/^\d+(\.\d+)?$/.test(v) || !(Number(v) > 0))
79
+ throw grvtShapeError(`${what} is not a positive decimal`);
80
+ return v;
81
+ }
82
+ function assetClassOf(symbol, raw) {
83
+ switch (raw) {
84
+ case "CRYPTO": return "crypto";
85
+ case "COMMODITY": return "commodity";
86
+ case "EQUITY": return PRE_IPO.has(symbol) ? "preIpo" : ETF.has(symbol) ? "etf" : "equity";
87
+ default: return null;
88
+ }
89
+ }
90
+ /**
91
+ * Cross-venue key: crypto / commodity / preIpo through canonical-symbols.ts; an equity / etf only
92
+ * when whitelisted (MATCHABLE_EQUITY / ETF), else null — warned once when not reviewed at all.
93
+ */
94
+ export function grvtCanonicalOf(symbol, assetClass, warn) {
95
+ if (assetClass !== "equity" && assetClass !== "etf")
96
+ return canonicalFor("grvt", symbol, assetClass);
97
+ if (MATCHABLE_EQUITY.has(symbol) || ETF.has(symbol))
98
+ return canonicalFor("grvt", symbol, assetClass);
99
+ if (!EXPLICIT_ONLY_EQUITY.has(symbol) && !warnedUnreviewed.has(symbol)) {
100
+ warnedUnreviewed.add(symbol);
101
+ warn(`[grvt] ${symbol}: equity market not yet reviewed for cross-venue matching — not matched (canonical null)`);
102
+ }
103
+ return null;
104
+ }
105
+ /**
106
+ * Parse one instruments row. Returns null for a row that is not a listed perpetual (another kind,
107
+ * an expiring settlement period); shape drift on a perpetual row is EXCHANGE_ERROR.
108
+ */
109
+ export function toGrvtMarketMeta(raw, warn) {
110
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw))
111
+ throw grvtShapeError("instruments row is not an object");
112
+ const r = raw;
113
+ if (r.kind !== "PERPETUAL" || r.settlement_period !== "PERPETUAL")
114
+ return null;
115
+ if (typeof r.instrument !== "string" || typeof r.base !== "string" || r.base === "" || typeof r.quote !== "string") {
116
+ throw grvtShapeError(`instrument row ${String(r.instrument)} has no instrument / base / quote`);
117
+ }
118
+ const symbol = r.base.toUpperCase();
119
+ const assetClass = assetClassOf(symbol, r.asset_class);
120
+ if (assetClass === null) {
121
+ warn(`[grvt] skipped ${r.instrument}: unknown asset_class "${String(r.asset_class)}"`);
122
+ return null;
123
+ }
124
+ const fi = r.funding_interval_hours;
125
+ if (typeof fi !== "number" || !Number.isInteger(fi) || fi <= 0)
126
+ throw grvtShapeError(`${r.instrument} funding_interval_hours ${String(fi)} is not a positive integer`);
127
+ return {
128
+ instrument: r.instrument,
129
+ symbol,
130
+ quote: r.quote,
131
+ tickSize: positiveDec(r.tick_size, `${r.instrument} tick_size`),
132
+ minSize: positiveDec(r.min_size, `${r.instrument} min_size`),
133
+ minNotional: decOrNull(r.min_notional),
134
+ fundingIntervalHours: fi,
135
+ assetClass,
136
+ canonical: grvtCanonicalOf(symbol, assetClass, warn),
137
+ tradable: r.status === "ACTIVE",
138
+ };
139
+ }
140
+ export async function fetchGrvtDirectory(client, warn) {
141
+ const rows = await client.result("instruments", { kind: ["PERPETUAL"], is_active: true, limit: 100000 });
142
+ if (!Array.isArray(rows))
143
+ throw grvtShapeError("instruments result is not an array");
144
+ const out = [];
145
+ const seen = new Set();
146
+ for (const row of rows) {
147
+ const m = toGrvtMarketMeta(row, warn);
148
+ if (m === null)
149
+ continue;
150
+ if (seen.has(m.symbol))
151
+ throw grvtShapeError(`instruments list ${m.symbol} twice`);
152
+ seen.add(m.symbol);
153
+ out.push(m);
154
+ }
155
+ return out;
156
+ }
157
+ /** Resolve a CLI symbol ("btc", "BTC-PERP", "BTC_USDT_Perp", "BTC-USDT") against the directory. */
158
+ export function resolveGrvtMarket(dir, input) {
159
+ const up = input.trim().toUpperCase().replace(/-PERP$/, "").replace(/_PERP$/, "").replace(/[-_/]USDT$/, "");
160
+ const hit = dir.find(m => m.symbol === up);
161
+ if (hit === undefined)
162
+ throw symbolNotFound("grvt", input);
163
+ return hit;
164
+ }
165
+ function nsToMsOrNull(v) {
166
+ if (typeof v !== "string" || !/^\d+$/.test(v))
167
+ return null;
168
+ const ms = Number(BigInt(v) / 1000000n);
169
+ return ms > 0 ? ms : null;
170
+ }
171
+ export function toGrvtTicker(raw) {
172
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw))
173
+ throw grvtShapeError("ticker result is not an object");
174
+ const r = raw;
175
+ const bv = decOrNull(r.buy_volume_24h_q);
176
+ const sv = decOrNull(r.sell_volume_24h_q);
177
+ return {
178
+ markPrice: decOrNull(r.mark_price),
179
+ indexPrice: decOrNull(r.index_price),
180
+ lastPrice: decOrNull(r.last_price),
181
+ bestBid: decOrNull(r.best_bid_price),
182
+ bestAsk: decOrNull(r.best_ask_price),
183
+ openInterest: decOrNull(r.open_interest),
184
+ volume24hQuote: bv !== null && sv !== null ? addDecimal(bv, sv) : null,
185
+ fundingPct: decOrNull(r.funding_rate),
186
+ nextFundingTime: nsToMsOrNull(r.next_funding_time),
187
+ };
188
+ }
189
+ /** Percent → fraction, exactly ("0.0063" → "0.000063"); null stays null (unknown, never 0). */
190
+ export function grvtPercentToFraction(pct) {
191
+ return pct === null ? null : mulDecimal(pct, "0.01");
192
+ }
193
+ export function grvtFundingBasis(m) {
194
+ return { kind: "perHours", hours: m.fundingIntervalHours };
195
+ }
196
+ /** risk_brackets → tier-1 max leverage and the notional tiers (ascending); null when unpublished. */
197
+ export function toGrvtLeverage(raw) {
198
+ const brackets = raw?.risk_brackets;
199
+ if (!Array.isArray(brackets) || brackets.length === 0)
200
+ return null;
201
+ const tiers = [];
202
+ for (const b of brackets) {
203
+ const x = b;
204
+ const floor = decOrNull(x.notional_floor);
205
+ if (floor === null || typeof x.max_leverage !== "number" || !Number.isInteger(x.max_leverage) || x.max_leverage <= 0)
206
+ return null;
207
+ tiers.push({ lowerBound: Number(floor), maxLeverage: x.max_leverage });
208
+ }
209
+ tiers.sort((a, b) => a.lowerBound - b.lowerBound);
210
+ return { maxLeverage: tiers[0].maxLeverage, tiers };
211
+ }
212
+ function isRateLimited(e) {
213
+ return e instanceof PerpError && e.structured.code === "RATE_LIMITED";
214
+ }
215
+ /**
216
+ * Run `fn` over `items` with `limit` in flight; each item settles on its own. RATE_LIMITED stops
217
+ * every worker (nothing new is sent) and is re-thrown — the venue told us to back off.
218
+ */
219
+ export async function settleEach(items, limit, fn) {
220
+ const out = new Array(items.length);
221
+ let next = 0;
222
+ let rateLimited = null;
223
+ const worker = async () => {
224
+ while (rateLimited === null && next < items.length) {
225
+ const i = next++;
226
+ try {
227
+ out[i] = { ok: true, value: await fn(items[i]) };
228
+ }
229
+ catch (e) {
230
+ if (isRateLimited(e)) {
231
+ rateLimited = e;
232
+ return;
233
+ }
234
+ out[i] = { ok: false, error: e };
235
+ }
236
+ }
237
+ };
238
+ await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
239
+ if (rateLimited !== null)
240
+ throw rateLimited;
241
+ return out;
242
+ }
243
+ function failureList(names, errors) {
244
+ return names.map((n, i) => `${n} (${extractErrorMessage(errors[i])})`).join(", ");
245
+ }
246
+ export function fetchGrvtTicker(client, instrument) {
247
+ return client.result("ticker", { instrument }).then(toGrvtTicker);
248
+ }
249
+ export function fetchGrvtLeverage(client, instrument) {
250
+ return client.post("margin_rules", { instrument }).then(toGrvtLeverage);
251
+ }
252
+ // ── Caches ──
253
+ const dirCache = new Map();
254
+ const tickerCache = new Map();
255
+ const marginCacheKey = (net) => `grvt-margin-rules-${net}`;
256
+ /** Drop every GRVT cache (in-process directory / tickers and the margin-rules file cache). */
257
+ export function clearGrvtCaches() {
258
+ dirCache.clear();
259
+ tickerCache.clear();
260
+ invalidateCache("grvt-");
261
+ }
262
+ /** The directory, reused for GRVT_SHORT_TTL_MS; a failed read is not kept. */
263
+ export function grvtDirectory(client, net, warn) {
264
+ const hit = dirCache.get(net);
265
+ if (hit !== undefined && Date.now() - hit.at < GRVT_SHORT_TTL_MS)
266
+ return hit.value;
267
+ const value = fetchGrvtDirectory(client, warn);
268
+ dirCache.set(net, { at: Date.now(), value });
269
+ value.catch(() => { if (dirCache.get(net)?.value === value)
270
+ dirCache.delete(net); });
271
+ return value;
272
+ }
273
+ /** One ticker, reused for GRVT_SHORT_TTL_MS. */
274
+ export async function grvtTicker(client, net, instrument) {
275
+ const key = `${net}|${instrument}`;
276
+ const hit = tickerCache.get(key);
277
+ if (hit !== undefined && Date.now() - hit.at < GRVT_SHORT_TTL_MS)
278
+ return hit.value;
279
+ const value = await fetchGrvtTicker(client, instrument);
280
+ tickerCache.set(key, { at: Date.now(), value });
281
+ return value;
282
+ }
283
+ function isEntry(v) {
284
+ if (v === null || typeof v !== "object")
285
+ return false;
286
+ const e = v;
287
+ return typeof e.fetchedAt === "number" && Number.isFinite(e.fetchedAt) && (e.leverage === null || (typeof e.leverage === "object" && e.leverage !== undefined));
288
+ }
289
+ /**
290
+ * Leverage per instrument from the margin-rules file cache (JSON: instrument → {fetchedAt, leverage}).
291
+ * Each entry expires on its own GRVT_MARGIN_TTL_MS after ITS read (rewriting the file never extends
292
+ * an old entry); expired, malformed and missing instruments are read again. A failed read leaves
293
+ * that market's leverage unknown (null entry, warned, not cached).
294
+ */
295
+ export async function grvtLeverageFor(client, net, instruments, warn) {
296
+ const now = Date.now();
297
+ const stored = getCached(marginCacheKey(net)) ?? {};
298
+ const cache = {};
299
+ for (const [inst, e] of Object.entries(stored)) {
300
+ if (isEntry(e) && e.fetchedAt <= now && now - e.fetchedAt < GRVT_MARGIN_TTL_MS)
301
+ cache[inst] = e;
302
+ }
303
+ const missing = instruments.filter(i => !(i in cache));
304
+ if (missing.length > 0) {
305
+ const settled = await settleEach(missing, GRVT_FANOUT_CONCURRENCY, i => fetchGrvtLeverage(client, i));
306
+ const failed = [];
307
+ const errors = [];
308
+ settled.forEach((r, k) => {
309
+ if (r.ok)
310
+ cache[missing[k]] = { fetchedAt: Date.now(), leverage: r.value };
311
+ else {
312
+ failed.push(missing[k]);
313
+ errors.push(r.error);
314
+ }
315
+ });
316
+ if (failed.length > 0)
317
+ warn(`[grvt] margin rules unreadable for ${failed.length} market(s) — max leverage unknown: ${failureList(failed, errors)}`);
318
+ // The file outlives every entry in it (each is younger than the TTL); entries expire by fetchedAt.
319
+ setCached(marginCacheKey(net), cache, GRVT_MARGIN_TTL_MS);
320
+ }
321
+ return Object.fromEntries(instruments.map(i => [i, i in cache ? cache[i] : null]));
322
+ }
323
+ export function toGrvtVenueMarket(m, t, entry) {
324
+ const lev = entry === null ? null : entry.leverage;
325
+ return {
326
+ venue: "grvt",
327
+ venueSymbol: m.instrument,
328
+ symbol: m.symbol,
329
+ canonical: m.canonical,
330
+ assetClass: m.assetClass,
331
+ settle: "USDT",
332
+ quoteAsset: m.quote,
333
+ markPrice: t.markPrice,
334
+ indexPrice: t.indexPrice,
335
+ fundingRate: grvtPercentToFraction(t.fundingPct),
336
+ fundingRateBasis: grvtFundingBasis(m),
337
+ settlementIntervalHours: m.fundingIntervalHours,
338
+ openInterest: t.openInterest,
339
+ volume24h: t.volume24hQuote,
340
+ tickSize: m.tickSize,
341
+ // No lot step is published (min_size is the minimum, base_decimals the signing multiplier).
342
+ stepSize: null,
343
+ minSize: m.minSize,
344
+ minNotional: m.minNotional,
345
+ maxLeverage: lev === null ? null : lev.maxLeverage,
346
+ marginTiers: lev === null ? null : lev.tiers,
347
+ leverageAsOf: entry === null ? null : new Date(entry.fetchedAt).toISOString(),
348
+ // Not mapped: the ticker's `session` ("REGULAR" on every market, 2026-10-19) is not in GRVT's
349
+ // documented schema and its other values / their meaning (open hours, price bands) are unknown.
350
+ session: null,
351
+ tradable: m.tradable,
352
+ lastPrice: t.lastPrice,
353
+ bestBid: t.bestBid,
354
+ bestAsk: t.bestAsk,
355
+ nextFundingTime: t.nextFundingTime,
356
+ };
357
+ }
358
+ const DEFAULT_DEPS = { warn: msg => process.stderr.write(`${msg}\n`) };
359
+ export function grvtClient(net) {
360
+ return new GrvtClient(networkConfig(grvtVenue, net).restUrl, net);
361
+ }
362
+ function priced(meta, t) {
363
+ return t.markPrice !== null && Number(t.markPrice) > 0 ? { meta, ticker: { ...t, markPrice: t.markPrice } } : null;
364
+ }
365
+ /**
366
+ * Directory + one ticker per market. A market whose ticker read fails, or has no mark price, is
367
+ * dropped with a warning naming it; the venue fails only when every ticker read fails (or on
368
+ * RATE_LIMITED).
369
+ */
370
+ async function fetchPriced(client, net, deps) {
371
+ const dir = await grvtDirectory(client, net, deps.warn);
372
+ const settled = await settleEach(dir, GRVT_FANOUT_CONCURRENCY, m => grvtTicker(client, net, m.instrument));
373
+ const out = [];
374
+ const unpriced = [];
375
+ const failed = [];
376
+ const errors = [];
377
+ dir.forEach((meta, i) => {
378
+ const r = settled[i];
379
+ if (!r.ok) {
380
+ failed.push(meta.symbol);
381
+ errors.push(r.error);
382
+ return;
383
+ }
384
+ const p = priced(meta, r.value);
385
+ if (p === null)
386
+ unpriced.push(meta.symbol);
387
+ else
388
+ out.push(p);
389
+ });
390
+ if (dir.length > 0 && failed.length === dir.length)
391
+ throw errors[0];
392
+ if (failed.length > 0)
393
+ deps.warn(`[grvt] ${failed.length} market(s) whose ticker could not be read are not shown: ${failureList(failed, errors)}`);
394
+ if (unpriced.length > 0)
395
+ deps.warn(`[grvt] ${unpriced.length} market(s) without a mark price are not shown: ${unpriced.join(", ")}`);
396
+ return out;
397
+ }
398
+ export async function fetchGrvtMarkets(net, opts, deps = DEFAULT_DEPS) {
399
+ const client = grvtClient(net);
400
+ const rows = await fetchPriced(client, net, deps);
401
+ const lev = opts.leverage ? await grvtLeverageFor(client, net, rows.map(p => p.meta.instrument), deps.warn) : null;
402
+ return rows.map(p => toGrvtVenueMarket(p.meta, p.ticker, lev === null ? null : lev[p.meta.instrument]));
403
+ }
404
+ /** One market: directory (cached) + its ticker + its margin rules — no fan-out. */
405
+ export async function fetchGrvtMarket(net, symbol, deps = DEFAULT_DEPS) {
406
+ const client = grvtClient(net);
407
+ const meta = resolveGrvtMarket(await grvtDirectory(client, net, deps.warn), symbol);
408
+ const p = priced(meta, await grvtTicker(client, net, meta.instrument));
409
+ if (p === null)
410
+ throw grvtShapeError(`${meta.instrument} ticker has no mark price`);
411
+ const lev = await grvtLeverageFor(client, net, [meta.instrument], deps.warn);
412
+ return toGrvtVenueMarket(p.meta, p.ticker, lev[meta.instrument]);
413
+ }
414
+ /** Funding rows (tickers only — no margin_rules): fraction per the market's own interval. */
415
+ export async function fetchGrvtFundingRates(net, deps = DEFAULT_DEPS) {
416
+ const out = [];
417
+ for (const { meta, ticker } of await fetchPriced(grvtClient(net), net, deps)) {
418
+ const rate = grvtPercentToFraction(ticker.fundingPct);
419
+ if (rate === null)
420
+ continue;
421
+ out.push({
422
+ venue: "grvt",
423
+ venueSymbol: meta.instrument,
424
+ symbol: meta.symbol,
425
+ canonical: meta.canonical,
426
+ rate,
427
+ basis: grvtFundingBasis(meta),
428
+ markPrice: ticker.markPrice,
429
+ nextFundingTime: ticker.nextFundingTime,
430
+ });
431
+ }
432
+ return out;
433
+ }
434
+ /** The registry's public data path (MCP get_prices / get_markets, market://prices, arb, dashboards): price-only. */
435
+ export const grvtPublicData = {
436
+ fetchMarkets: net => fetchGrvtMarkets(net, { leverage: false }),
437
+ fetchFundingRates: net => fetchGrvtFundingRates(net),
438
+ };
@@ -74,7 +74,7 @@ export declare class HyperliquidSpotAdapter implements SpotAdapter, SpotHoldingP
74
74
  * `usdClassTransfer`. No signer → NO_SIGNER_AVAILABLE from the adapter.
75
75
  */
76
76
  private _moveUsdc;
77
- /** SpotTransferCapable (§12.4 #4): USDC only; an `err` response is thrown, not returned. */
77
+ /** SpotTransferCapable: USDC only; an `err` response is thrown, not returned. */
78
78
  transferToSpot(amount: string, asset: string): Promise<unknown>;
79
79
  transferToPerp(amount: string, asset: string): Promise<unknown>;
80
80
  private _checkedTransfer;
@@ -182,7 +182,7 @@ export class HyperliquidSpotAdapter {
182
182
  // Reuse cached spot clearinghouse state (shared with getBalance() — saves 1 API call).
183
183
  const state = await this._hl._getSpotClearinghouseState({ fresh });
184
184
  const balances = (state?.balances ?? []);
185
- // Unified HL accounts: spot USDC IS the perp margin (§12.4 #8) — mark it shared.
185
+ // Unified HL accounts: spot USDC IS the perp margin — mark it shared.
186
186
  // HIP-3 dex-scoped adapters report dex equity, which never contains spot USDC.
187
187
  const unified = this._hl.isUnifiedAccount === true && this._hl.dex === "";
188
188
  return balances.map((b) => ({
@@ -204,7 +204,7 @@ export class HyperliquidSpotAdapter {
204
204
  await this.init();
205
205
  const resolved = this._resolveBase(symbol);
206
206
  base = resolved.base;
207
- // Reference = l2Book mid (the same single declared source as HL perps, §13.10 #5).
207
+ // Reference = l2Book mid (the same single declared source as HL perps).
208
208
  // Either side missing → PRICE_STALE (no one-sided "mid").
209
209
  const book = await this.getSpotOrderbook(symbol);
210
210
  const bestAsk = Number(book.asks[0]?.[0]);
@@ -213,7 +213,7 @@ export class HyperliquidSpotAdapter {
213
213
  throw new PerpError("PRICE_STALE", `Hyperliquid spot ${base}: no two-sided l2Book to derive the mid reference price`, { exchange: "hyperliquid" });
214
214
  }
215
215
  const midPrice = (bestAsk + bestBid) / 2;
216
- // Protection = mid ± the resolved slippage bound (design §13.2), aligned toward
216
+ // Protection = mid ± the resolved slippage bound, aligned toward
217
217
  // crossing on HL's spot grid (5 sig figs, max 8 − szDecimals decimals).
218
218
  const isBuy = side === "buy";
219
219
  const szDec = this.getSpotDecimals(base).size;
@@ -254,7 +254,7 @@ export class HyperliquidSpotAdapter {
254
254
  await this.init();
255
255
  const { base, spotIndex } = this._resolveBase(symbol);
256
256
  const assetIndex = 10000 + spotIndex;
257
- // TIF aliases (§13.3): GTC/IOC/ALO or native spellings; FOK → CAPABILITY_UNSUPPORTED.
257
+ // TIF aliases: GTC/IOC/ALO or native spellings; FOK → CAPABILITY_UNSUPPORTED.
258
258
  const tif = hlTif(opts?.tif ?? "GTC");
259
259
  const szDec = this.getSpotDecimals(base).size;
260
260
  const what = `spot limit ${side} ${size} ${base} @ ${price}`;
@@ -388,7 +388,7 @@ export class HyperliquidSpotAdapter {
388
388
  invalidateCache("acct"); // perp and spot balances both moved
389
389
  }
390
390
  }
391
- /** SpotTransferCapable (§12.4 #4): USDC only; an `err` response is thrown, not returned. */
391
+ /** SpotTransferCapable: USDC only; an `err` response is thrown, not returned. */
392
392
  async transferToSpot(amount, asset) {
393
393
  return this._checkedTransfer(amount, asset, false);
394
394
  }
@@ -1,4 +1,4 @@
1
- import type { ExchangeAdapter, ExchangeMarketInfo, ExchangePosition, ExchangeOrder, ExchangeBalance, ExchangeTrade, ExchangeFundingPayment, ExchangeKline } from "./interface.js";
1
+ import type { ExchangeAdapter, ExchangeMarketInfo, ExchangePosition, ExchangeOrder, ExchangeBalance, ExchangeTrade, ExchangePublicTrade, ExchangeFundingPayment, ExchangeKline } from "./interface.js";
2
2
  import type { ResolvedSlippage } from "./slippage.js";
3
3
  import type { EvmSigner } from "../signer/index.js";
4
4
  import type { AgentMeta } from "../settings.js";
@@ -6,15 +6,15 @@ import { type BuilderApproval, type BuilderDecision, type BuilderFeeGate, type B
6
6
  /** HL native time-in-force values. */
7
7
  export type HlTif = "Gtc" | "Ioc" | "Alo";
8
8
  /**
9
- * Map a TIF input to HL's native value (design §13.3). Accepts the common names
9
+ * Map a TIF input to HL's native value. Accepts the common names
10
10
  * GTC/IOC/ALO and the native spellings case-insensitively. FOK is not offered by
11
- * HL (no FOK emulation, §13.3) → CAPABILITY_UNSUPPORTED; anything else likewise.
11
+ * HL (no FOK emulation) → CAPABILITY_UNSUPPORTED; anything else likewise.
12
12
  */
13
13
  export declare function hlTif(raw: string): HlTif;
14
14
  /** HL lot step implied by szDecimals ("1" for 0, "0.001" for 3) — sizes are floored to it (floorSize). */
15
15
  export declare function hlSizeStep(szDecimals: number): string;
16
16
  /**
17
- * Slippage-bounded IOC protection price (design §13.2, §13.10 #5).
17
+ * Slippage-bounded IOC protection price.
18
18
  *
19
19
  * `reference` × (1 ± bps/10000), then aligned TOWARD CROSSING (buy → up, sell →
20
20
  * down) on HL's price grid: at most 5 significant figures and at most
@@ -29,8 +29,8 @@ export declare function hlProtectionPrice(reference: number, side: "buy" | "sell
29
29
  appliedBps: number;
30
30
  };
31
31
  /**
32
- * A USER-SUPPLIED limit / trigger / modify price checked against HL's price grid (design §10.10:
33
- * an off-grid limit price is refused, never rounded — rounding to nearest can move a buy price UP).
32
+ * A USER-SUPPLIED limit / trigger / modify price checked against HL's price grid:
33
+ * an off-grid limit price is refused, never rounded — rounding to nearest can move a buy price UP.
34
34
  * HL docs (trading/tick-and-lot-size): "Prices can have up to 5 significant figures, but no more
35
35
  * than MAX_DECIMALS - szDecimals decimal places where MAX_DECIMALS is 6 for perps and 8 for spot.
36
36
  * Integer prices are always allowed, regardless of the number of significant figures."
@@ -59,7 +59,7 @@ export declare function hlAlignPriceToGrid(price: string, szDecimals: number, ma
59
59
  export declare function assertHlAppliedBps(appliedBps: number, what: string): Promise<void>;
60
60
  /**
61
61
  * Definite IOC outcome of a raw HL `order` response (shared contract with the
62
- * perp-order lane, design §13.10 #4). Reads `response.data.statuses[0]`:
62
+ * perp-order lane). Reads `response.data.statuses[0]`:
63
63
  * - `{ filled: { totalSz } }` with a plain decimal totalSz → that size, final;
64
64
  * - `{ error }` that is HL's IOC no-match cancel ("could not immediately match")
65
65
  * → the venue explicitly cancelled the IOC with nothing filled → "0", final;
@@ -269,7 +269,17 @@ export declare class HyperliquidAdapter implements ExchangeAdapter {
269
269
  /** Lot step of a market from the loaded `meta` szDecimals (precision.lotStepOf) — no metaAndAssetCtxs / allMids read per order. */
270
270
  lotStepOf(symbol: string): string;
271
271
  getAssetIndex(symbol: string): Promise<number>;
272
+ /** SYMBOL_NOT_FOUND for a coin the venue does not list (on this adapter's dex), with the listing command. */
273
+ private _unknownSymbol;
272
274
  getMarkets(): Promise<ExchangeMarketInfo[]>;
275
+ /** Display names of the delisted assets seen by the last getMarkets() (meta isDelisted). */
276
+ private _delisted;
277
+ /**
278
+ * Why `symbol` is not in getMarkets(): it is delisted (message), or null when it is not a
279
+ * delisted asset. Read after getMarkets(). `market info` uses it to say "delisted" rather than
280
+ * "not found" — the asset map still resolves it for orders / positions / history.
281
+ */
282
+ delistedMessage(symbol: string): string | null;
273
283
  getOrderbook(symbol: string): Promise<{
274
284
  bids: [string, string][];
275
285
  asks: [string, string][];
@@ -367,11 +377,11 @@ export declare class HyperliquidAdapter implements ExchangeAdapter {
367
377
  */
368
378
  private _validateOrderFill;
369
379
  /**
370
- * Market order = slippage-bounded IOC limit (design §13.2, §13.10 #1/#5) for
380
+ * Market order = slippage-bounded IOC limit for
371
381
  * native perps and HIP-3 dexes alike. Replaces the SDK's marketOpen/marketClose
372
382
  * (hidden built-in slippage) and the former HIP-3 5% constant.
373
383
  *
374
- * Reference price (the single declared source, §13.10 #5): the l2Book mid
384
+ * Reference price (the single declared source): the l2Book mid
375
385
  * (best bid + best ask) / 2 of this coin — see referencePrice(). No runtime
376
386
  * substitute (mark, allMids, last trade): a missing side → PRICE_STALE before
377
387
  * anything is sent. Protection = reference ± opts.slippage.bps, aligned toward
@@ -483,7 +493,7 @@ export declare class HyperliquidAdapter implements ExchangeAdapter {
483
493
  cancelOrder(symbol: string, orderId: string): Promise<unknown>;
484
494
  cancelAllOrders(symbol?: string): Promise<unknown[]>;
485
495
  /**
486
- * Amend (design §13.4, §13.10 #10) via HL native batchModify. `size` = the NEW
496
+ * Amend via HL native batchModify. `size` = the NEW
487
497
  * open (unfilled) size — native-modify semantics, not the original total. The
488
498
  * order's own tif (Gtc/Alo) and reduceOnly are read from frontendOpenOrders
489
499
  * and preserved; nothing is hardcoded.
@@ -494,7 +504,7 @@ export declare class HyperliquidAdapter implements ExchangeAdapter {
494
504
  limitPrice?: string;
495
505
  reduceOnly?: boolean;
496
506
  }): Promise<unknown>;
497
- getRecentTrades(symbol: string, limit?: number): Promise<ExchangeTrade[]>;
507
+ getRecentTrades(symbol: string, limit?: number): Promise<ExchangePublicTrade[]>;
498
508
  getKlines(symbol: string, interval: string, startTime: number, endTime: number): Promise<ExchangeKline[]>;
499
509
  /**
500
510
  * Order history: POST /info {type:"historicalOrders"} ("Retrieve a user's historical orders",
@@ -538,7 +548,7 @@ export declare class HyperliquidAdapter implements ExchangeAdapter {
538
548
  * Place a trigger order (stop loss / take profit).
539
549
  * Python SDK: order() with trigger type {"trigger": {triggerPx, isMarket, tpsl: "tp"|"sl"}}
540
550
  *
541
- * Pricing (design §13.10 #3):
551
+ * Pricing:
542
552
  * - isMarket (default): HL native market trigger; `p` = trigger ± 10 % (the venue's documented
543
553
  * market TP/SL slippage tolerance, HL_MARKET_TPSL_SLIPPAGE_BPS), aligned toward crossing.
544
554
  * - limit trigger with an explicit `limitPrice`: that price, rounded to HL's grid.
@@ -665,10 +675,6 @@ export declare class HyperliquidAdapter implements ExchangeAdapter {
665
675
  * adapter creation. Throws on a venue rejection (SSOT Rule #2).
666
676
  */
667
677
  setReferrer(code: string): Promise<unknown>;
668
- /**
669
- * Get funding history for a symbol.
670
- */
671
- getFundingHistoryRaw(symbol: string, startTime: number, endTime?: number): Promise<any>;
672
678
  /**
673
679
  * Get user trade fills.
674
680
  */