hyperliquid-prime 0.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.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +426 -0
  3. package/dist/cli/context.d.ts +12 -0
  4. package/dist/cli/context.d.ts.map +1 -0
  5. package/dist/cli/context.js +27 -0
  6. package/dist/cli/context.js.map +1 -0
  7. package/dist/cli/index.d.ts +3 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +5 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/output.d.ts +7 -0
  12. package/dist/cli/output.d.ts.map +1 -0
  13. package/dist/cli/output.js +29 -0
  14. package/dist/cli/output.js.map +1 -0
  15. package/dist/cli/program.d.ts +3 -0
  16. package/dist/cli/program.d.ts.map +1 -0
  17. package/dist/cli/program.js +232 -0
  18. package/dist/cli/program.js.map +1 -0
  19. package/dist/collateral/manager.d.ts +45 -0
  20. package/dist/collateral/manager.d.ts.map +1 -0
  21. package/dist/collateral/manager.js +252 -0
  22. package/dist/collateral/manager.js.map +1 -0
  23. package/dist/collateral/types.d.ts +26 -0
  24. package/dist/collateral/types.d.ts.map +1 -0
  25. package/dist/collateral/types.js +2 -0
  26. package/dist/collateral/types.js.map +1 -0
  27. package/dist/config.d.ts +31 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +6 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/execution/executor.d.ts +30 -0
  32. package/dist/execution/executor.d.ts.map +1 -0
  33. package/dist/execution/executor.js +291 -0
  34. package/dist/execution/executor.js.map +1 -0
  35. package/dist/execution/monitor.d.ts +26 -0
  36. package/dist/execution/monitor.d.ts.map +1 -0
  37. package/dist/execution/monitor.js +50 -0
  38. package/dist/execution/monitor.js.map +1 -0
  39. package/dist/execution/types.d.ts +26 -0
  40. package/dist/execution/types.d.ts.map +1 -0
  41. package/dist/execution/types.js +2 -0
  42. package/dist/execution/types.js.map +1 -0
  43. package/dist/index.d.ts +87 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +249 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/logging/logger.d.ts +7 -0
  48. package/dist/logging/logger.d.ts.map +1 -0
  49. package/dist/logging/logger.js +10 -0
  50. package/dist/logging/logger.js.map +1 -0
  51. package/dist/market/aggregator.d.ts +28 -0
  52. package/dist/market/aggregator.d.ts.map +1 -0
  53. package/dist/market/aggregator.js +166 -0
  54. package/dist/market/aggregator.js.map +1 -0
  55. package/dist/market/book.d.ts +22 -0
  56. package/dist/market/book.d.ts.map +1 -0
  57. package/dist/market/book.js +34 -0
  58. package/dist/market/book.js.map +1 -0
  59. package/dist/market/registry.d.ts +19 -0
  60. package/dist/market/registry.d.ts.map +1 -0
  61. package/dist/market/registry.js +127 -0
  62. package/dist/market/registry.js.map +1 -0
  63. package/dist/market/types.d.ts +53 -0
  64. package/dist/market/types.d.ts.map +1 -0
  65. package/dist/market/types.js +2 -0
  66. package/dist/market/types.js.map +1 -0
  67. package/dist/position/manager.d.ts +21 -0
  68. package/dist/position/manager.d.ts.map +1 -0
  69. package/dist/position/manager.js +63 -0
  70. package/dist/position/manager.js.map +1 -0
  71. package/dist/position/risk.d.ts +7 -0
  72. package/dist/position/risk.d.ts.map +1 -0
  73. package/dist/position/risk.js +23 -0
  74. package/dist/position/risk.js.map +1 -0
  75. package/dist/position/types.d.ts +28 -0
  76. package/dist/position/types.d.ts.map +1 -0
  77. package/dist/position/types.js +2 -0
  78. package/dist/position/types.js.map +1 -0
  79. package/dist/provider/nktkas.d.ts +63 -0
  80. package/dist/provider/nktkas.d.ts.map +1 -0
  81. package/dist/provider/nktkas.js +277 -0
  82. package/dist/provider/nktkas.js.map +1 -0
  83. package/dist/provider/provider.d.ts +42 -0
  84. package/dist/provider/provider.d.ts.map +1 -0
  85. package/dist/provider/provider.js +2 -0
  86. package/dist/provider/provider.js.map +1 -0
  87. package/dist/provider/types.d.ts +214 -0
  88. package/dist/provider/types.d.ts.map +1 -0
  89. package/dist/provider/types.js +4 -0
  90. package/dist/provider/types.js.map +1 -0
  91. package/dist/router/router.d.ts +30 -0
  92. package/dist/router/router.d.ts.map +1 -0
  93. package/dist/router/router.js +256 -0
  94. package/dist/router/router.js.map +1 -0
  95. package/dist/router/scorer.d.ts +18 -0
  96. package/dist/router/scorer.d.ts.map +1 -0
  97. package/dist/router/scorer.js +43 -0
  98. package/dist/router/scorer.js.map +1 -0
  99. package/dist/router/simulator.d.ts +11 -0
  100. package/dist/router/simulator.d.ts.map +1 -0
  101. package/dist/router/simulator.js +44 -0
  102. package/dist/router/simulator.js.map +1 -0
  103. package/dist/router/splitter.d.ts +26 -0
  104. package/dist/router/splitter.d.ts.map +1 -0
  105. package/dist/router/splitter.js +119 -0
  106. package/dist/router/splitter.js.map +1 -0
  107. package/dist/router/types.d.ts +69 -0
  108. package/dist/router/types.d.ts.map +1 -0
  109. package/dist/router/types.js +4 -0
  110. package/dist/router/types.js.map +1 -0
  111. package/dist/utils/errors.d.ts +28 -0
  112. package/dist/utils/errors.d.ts.map +1 -0
  113. package/dist/utils/errors.js +55 -0
  114. package/dist/utils/errors.js.map +1 -0
  115. package/dist/utils/math.d.ts +24 -0
  116. package/dist/utils/math.d.ts.map +1 -0
  117. package/dist/utils/math.js +43 -0
  118. package/dist/utils/math.js.map +1 -0
  119. package/package.json +59 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mehran Hydary
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,426 @@
1
+ # Hyperliquid Prime
2
+
3
+ A TypeScript SDK that acts as a **prime broker layer** on top of Hyperliquid's perp markets — both native (ETH, BTC) and HIP-3 deployer markets (xyz's TSLA, Hyena's ETH). When multiple venues list the same asset with different collateral types (USDC, USDH, USDT0), Hyperliquid Prime automatically discovers all markets, compares liquidity/funding/cost, and routes to the best execution — presenting a single unified trading interface.
4
+
5
+ ## The Problem
6
+
7
+ Hyperliquid has native perpetual markets (ETH, BTC, SOL) and HIP-3, which allows anyone to deploy additional perp markets. This means ETH can be traded on both the native HL market *and* third-party deployers like Hyena — each with different liquidity depth and funding rates. Similarly, TSLA exists across multiple HIP-3 venues (xyz, flx, km, cash) with different collateral types. Traders are left manually comparing across fragmented markets.
8
+
9
+ ## What Hyperliquid Prime Does
10
+
11
+ - **Discovers** all perp markets per asset (native + HIP-3) and groups them
12
+ - **Aggregates** orderbooks across collateral types into a unified view
13
+ - **Routes** orders to the single best market based on price impact, funding rate, and collateral match
14
+ - **Splits** large orders across multiple markets for better fills when a single venue lacks depth
15
+ - **Swaps collateral** automatically (e.g., USDC → USDH) when the best liquidity lives on a non-USDC market
16
+ - **Executes** via an explicit quote-then-execute flow
17
+ - **Tracks** positions across all markets in a unified view
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install hyperliquid-prime
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ### SDK Usage (TypeScript)
28
+
29
+ ```typescript
30
+ import { HyperliquidPrime } from 'hyperliquid-prime'
31
+
32
+ // --- Read-only (no wallet needed) ---
33
+ const hp = new HyperliquidPrime({ testnet: true })
34
+ await hp.connect()
35
+
36
+ // What markets exist for ETH? (native HL + HIP-3 deployers)
37
+ const ethMarkets = hp.getMarkets('ETH')
38
+ // [
39
+ // { coin: "ETH", dexName: "__native__", collateral: "USDC", isNative: true },
40
+ // { coin: "hyena:ETH", dexName: "hyena", collateral: "USDC", isNative: false },
41
+ // ]
42
+
43
+ // HIP-3-only assets also work
44
+ const tslaMarkets = hp.getMarkets('TSLA')
45
+ // [
46
+ // { coin: "xyz:TSLA", dexName: "xyz", collateral: "USDC", isNative: false },
47
+ // { coin: "flx:TSLA", dexName: "flx", collateral: "USDH", isNative: false },
48
+ // { coin: "km:TSLA", dexName: "km", collateral: "USDH", isNative: false },
49
+ // { coin: "cash:TSLA", dexName: "cash", collateral: "USDT0", isNative: false },
50
+ // ]
51
+
52
+ // Where's the best execution for a 50 TSLA long?
53
+ const quote = await hp.quote('TSLA', 'buy', 50)
54
+ console.log(quote.selectedMarket.coin) // "xyz:TSLA"
55
+ console.log(quote.estimatedAvgPrice) // 431.56
56
+ console.log(quote.estimatedPriceImpact) // 0.8 (bps)
57
+ console.log(quote.alternativesConsidered) // All markets with scores
58
+
59
+ // Aggregated orderbook across all TSLA markets
60
+ const book = await hp.getAggregatedBook('TSLA')
61
+
62
+ // Funding rate comparison
63
+ const funding = await hp.getFundingComparison('TSLA')
64
+
65
+ await hp.disconnect()
66
+ ```
67
+
68
+ ### Trading
69
+
70
+ ```typescript
71
+ const hp = new HyperliquidPrime({
72
+ privateKey: '0x...',
73
+ testnet: true,
74
+ })
75
+ await hp.connect()
76
+
77
+ // Two-step: quote then execute (recommended)
78
+ const quote = await hp.quote('TSLA', 'buy', 50)
79
+ // Review the quote...
80
+ const receipt = await hp.execute(quote.plan)
81
+ console.log(receipt.success) // true
82
+ console.log(receipt.filledSize) // "50"
83
+ console.log(receipt.avgPrice) // "431.50"
84
+ console.log(receipt.market.coin) // "xyz:TSLA"
85
+
86
+ // One-step convenience
87
+ const receipt2 = await hp.long('TSLA', 50)
88
+ const receipt3 = await hp.short('TSLA', 25)
89
+
90
+ // --- Split orders across multiple markets for better fills ---
91
+ const splitQuote = await hp.quoteSplit('TSLA', 'buy', 200)
92
+ console.log(splitQuote.allocations)
93
+ // [
94
+ // { market: xyz:TSLA, size: 120, proportion: 0.6 },
95
+ // { market: flx:TSLA, size: 50, proportion: 0.25 },
96
+ // { market: km:TSLA, size: 30, proportion: 0.15 },
97
+ // ]
98
+ console.log(splitQuote.collateralPlan.swapsNeeded) // false (resolved at executeSplit time)
99
+
100
+ const splitReceipt = await hp.executeSplit(splitQuote.splitPlan)
101
+ console.log(splitReceipt.totalFilledSize) // "200"
102
+ console.log(splitReceipt.aggregateAvgPrice) // "431.42"
103
+
104
+ // One-step split convenience
105
+ const splitReceipt2 = await hp.longSplit('TSLA', 200)
106
+ const splitReceipt3 = await hp.shortSplit('TSLA', 100)
107
+
108
+ // Unified position view across all perp markets
109
+ const positions = await hp.getGroupedPositions()
110
+ const tslaPositions = positions.get('TSLA')
111
+ // Shows all TSLA positions across all markets in one group
112
+
113
+ // Account balance
114
+ const balance = await hp.getBalance()
115
+
116
+ await hp.disconnect()
117
+ ```
118
+
119
+ ### CLI
120
+
121
+ The `hp` CLI provides the same functionality from the terminal:
122
+
123
+ ```bash
124
+ # Show all perp markets for an asset (native + HIP-3)
125
+ hp markets ETH
126
+ hp markets TSLA
127
+ hp markets TSLA --json
128
+
129
+ # Aggregated orderbook
130
+ hp book TSLA
131
+ hp book TSLA --depth 10
132
+
133
+ # Compare funding rates across markets
134
+ hp funding TSLA
135
+
136
+ # Get a routing quote (does not execute)
137
+ hp quote TSLA buy 50
138
+
139
+ # Execute trades via best market
140
+ HP_PRIVATE_KEY=0x... hp long TSLA 50
141
+ HP_PRIVATE_KEY=0x... hp short TSLA 25
142
+
143
+ # View positions and balance
144
+ HP_PRIVATE_KEY=0x... hp positions
145
+ HP_PRIVATE_KEY=0x... hp balance
146
+
147
+ # Use testnet
148
+ hp markets TSLA --testnet
149
+ ```
150
+
151
+ For CLI secrets, use `HP_PRIVATE_KEY` (or `--key-env <NAME>`) instead of `--key` whenever possible.
152
+
153
+ ## How Routing Works
154
+
155
+ ### Single-Market Routing
156
+
157
+ When you call `hp.quote("TSLA", "buy", 50)`, the router:
158
+
159
+ 1. **Fetches** the orderbook for every TSLA market (xyz, flx, km, cash)
160
+ 2. **Simulates** walking each book to estimate average fill price and price impact at the requested size
161
+ 3. **Scores** each market using three factors:
162
+ - **Price impact** (dominant) — cost in basis points to fill
163
+ - **Funding rate** (secondary) — prefers favorable funding direction
164
+ - **Collateral match** (penalty) — penalizes markets by the estimated cost to swap into their collateral (e.g., ~50 bps for USDC → USDH)
165
+ 4. **Selects** the lowest-score market and builds an execution plan with IOC limit order + slippage
166
+
167
+ The result is a `Quote` object containing the selected market, estimated cost, and a ready-to-execute `ExecutionPlan`. You review it, then call `execute(plan)` to place the order.
168
+
169
+ ### Split Routing (Multi-Market)
170
+
171
+ When you call `hp.quoteSplit("TSLA", "buy", 200)`, the router:
172
+
173
+ 1. **Aggregates** all orderbooks into a single merged book with source tracking
174
+ 2. **Walks** the merged book greedily — always consuming the cheapest liquidity first, regardless of venue
175
+ 3. **Distributes** fills proportionally across sources at each price level
176
+ 4. **Builds** a `SplitExecutionPlan` with one leg per market
177
+ 5. **Defers collateral estimation** to `executeSplit()` so balances and swap costs are resolved from live account state at execution time
178
+
179
+ On execution, the system automatically:
180
+ - Enables **DEX abstraction** (Hyperliquid's unified account mode)
181
+ - **Transfers** USDC from perp to spot if needed
182
+ - **Swaps** USDC → target tokens (e.g., USDH) via spot market
183
+ - **Places all leg orders** in a single atomic `batchOrders` call
184
+
185
+ If only one market has competitive liquidity, 100% routes there — equivalent to single-market behavior.
186
+
187
+ ## Configuration
188
+
189
+ ```typescript
190
+ interface HyperliquidPrimeConfig {
191
+ privateKey?: `0x${string}` // Required for trading, optional for read-only
192
+ walletAddress?: string // Derived from privateKey if not provided
193
+ testnet?: boolean // Default: false
194
+ defaultSlippage?: number // Default: 0.01 (1%)
195
+ logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent'
196
+ prettyLogs?: boolean // Default: false
197
+ builder?: BuilderConfig | null // Builder fee config (see below)
198
+ }
199
+ ```
200
+
201
+ ### Builder Fee
202
+
203
+ Hyperliquid Prime includes a small builder fee (1 basis point = 0.01%) on all orders placed through the SDK's execution methods. This uses Hyperliquid's native [builder fee](https://hyperliquid.gitbook.io/hyperliquid-docs) mechanism.
204
+
205
+ The fee is automatically approved on the trader's first order (one-time on-chain action per wallet).
206
+
207
+ ```typescript
208
+ // Default: 1 bps fee (no config needed)
209
+ const hp = new HyperliquidPrime({ privateKey: '0x...' })
210
+
211
+ // Custom builder address and fee
212
+ const hp = new HyperliquidPrime({
213
+ privateKey: '0x...',
214
+ builder: { address: '0xYourAddress', feeBps: 2 }, // 2 bps
215
+ })
216
+
217
+ // Disable builder fee entirely
218
+ const hp = new HyperliquidPrime({
219
+ privateKey: '0x...',
220
+ builder: null,
221
+ })
222
+ ```
223
+
224
+ The builder fee only applies to orders placed through `execute()`, `executeSplit()`, and their convenience wrappers (`long`, `short`, `longSplit`, `shortSplit`). Raw provider calls via `hp.api` are never affected.
225
+
226
+ CLI flag to disable:
227
+ ```bash
228
+ HP_PRIVATE_KEY=0x... hp long TSLA 50 --no-builder-fee
229
+ ```
230
+
231
+ ## API Reference
232
+
233
+ ### Read-Only Methods
234
+
235
+ | Method | Description |
236
+ | -------------------------------- | -------------------------------------------- |
237
+ | `getMarkets(asset)` | All perp markets for an asset (native + HIP-3) |
238
+ | `getAggregatedMarkets()` | Asset groups with multiple markets |
239
+ | `getAggregatedBook(asset)` | Merged orderbook across all markets |
240
+ | `getFundingComparison(asset)` | Funding rates compared across markets |
241
+ | `quote(asset, side, size)` | Routing quote for single best market |
242
+ | `quoteSplit(asset, side, size)` | Split quote across multiple markets |
243
+
244
+ ### Trading Methods (wallet required)
245
+
246
+ | Method | Description |
247
+ | ------------------------- | ------------------------------------------------- |
248
+ | `execute(plan)` | Execute a single-market quote |
249
+ | `executeSplit(plan)` | Execute a split quote (handles collateral swaps) |
250
+ | `long(asset, size)` | Quote + execute a long on best market |
251
+ | `short(asset, size)` | Quote + execute a short on best market |
252
+ | `longSplit(asset, size)` | Split quote + execute a long across markets |
253
+ | `shortSplit(asset, size)` | Split quote + execute a short across markets |
254
+ | `close(asset)` | Close all positions for an asset |
255
+
256
+ ### Position & Balance
257
+
258
+ | Method | Description |
259
+ | ----------------------- | ---------------------------------- |
260
+ | `getPositions()` | All positions with market metadata |
261
+ | `getGroupedPositions()` | Positions grouped by base asset |
262
+ | `getBalance()` | Account margin summary |
263
+
264
+ ### Escape Hatches
265
+
266
+ | Property | Description |
267
+ | ------------ | --------------------------------------------------- |
268
+ | `hp.api` | Direct access to the `HLProvider` for raw API calls |
269
+ | `hp.markets` | Direct access to the `MarketRegistry` |
270
+
271
+ ## Architecture
272
+
273
+ ```
274
+ hyperliquid-prime/
275
+ ├── src/
276
+ │ ├── index.ts # HyperliquidPrime class — public API surface
277
+ │ ├── config.ts # Configuration types
278
+ │ ├── provider/ # Wraps @nktkas/hyperliquid
279
+ │ │ ├── provider.ts # HLProvider interface
280
+ │ │ ├── nktkas.ts # Implementation
281
+ │ │ └── types.ts # Normalized types
282
+ │ ├── market/ # Perp market discovery (native + HIP-3)
283
+ │ │ ├── registry.ts # Discovers & indexes all perp markets per asset
284
+ │ │ ├── book.ts # Book normalization helpers
285
+ │ │ ├── aggregator.ts # Merges books across collateral types
286
+ │ │ └── types.ts # PerpMarket, MarketGroup, AggregatedBook
287
+ │ ├── router/ # Smart order routing
288
+ │ │ ├── router.ts # Scores markets, picks best one (or splits across many)
289
+ │ │ ├── simulator.ts # Walks books, estimates fill cost
290
+ │ │ ├── scorer.ts # Ranks by impact + funding + collateral swap cost
291
+ │ │ ├── splitter.ts # Optimizes order splits across aggregated book
292
+ │ │ └── types.ts # Quote, SplitQuote, ExecutionPlan, MarketScore
293
+ │ ├── execution/ # Order lifecycle
294
+ │ │ ├── executor.ts # Places orders via provider (single + batch)
295
+ │ │ ├── monitor.ts # Tracks order status via WebSocket
296
+ │ │ └── types.ts # ExecutionReceipt, SplitExecutionReceipt
297
+ │ ├── collateral/ # Collateral management for cross-market trading
298
+ │ │ ├── manager.ts # Estimates swap costs, executes USDC→token swaps
299
+ │ │ └── types.ts # CollateralPlan, CollateralRequirement
300
+ │ ├── position/ # Position tracking
301
+ │ │ ├── manager.ts # Read-only position tracking
302
+ │ │ ├── risk.ts # Per-position risk math
303
+ │ │ └── types.ts # LogicalPosition, RiskProfile
304
+ │ ├── cli/ # CLI commands
305
+ │ │ ├── index.ts # Entry point
306
+ │ │ ├── program.ts # Commander setup + all commands
307
+ │ │ ├── context.ts # Builds HyperliquidPrime from CLI flags
308
+ │ │ └── output.ts # JSON / table formatting
309
+ │ ├── logging/ # Structured logging (pino)
310
+ │ └── utils/ # Math helpers, error types
311
+ └── test/
312
+ ├── fixtures/ # Deterministic test data
313
+ ├── unit/ # Unit tests (mock provider)
314
+ └── integration/ # Testnet integration tests
315
+ ```
316
+
317
+ The provider interface (`HLProvider`) is the only module that imports `@nktkas/hyperliquid` directly. Swapping to a different SDK or going direct is a one-file change.
318
+
319
+ ## OpenClaw Skill (AI-Assisted Trading)
320
+
321
+ Hyperliquid Prime includes an [OpenClaw](https://openclaw.ai) skill for AI-assisted trading via natural language.
322
+
323
+ ### Installation
324
+
325
+ Install the skill via ClawHub:
326
+ ```bash
327
+ clawhub install mehranhydary/hl-prime
328
+ ```
329
+
330
+ Or manually clone to your OpenClaw skills directory:
331
+ ```bash
332
+ cd ~/.openclaw/skills
333
+ git clone https://github.com/mehranhydary/hl-prime.git hyperliquid-prime
334
+ ```
335
+
336
+ ### What You Can Ask
337
+
338
+ Once the skill is installed, you can trade via conversational commands:
339
+
340
+ ```
341
+ "What's the best market to buy 50 TSLA on Hyperliquid?"
342
+ "Show me all markets for GOLD"
343
+ "Compare funding rates across ETH markets"
344
+ "Get me a quote to short 100 NVDA"
345
+ "Execute that TSLA trade"
346
+ "Split 200 TSLA across all markets for better fills"
347
+ "Show my positions across all markets"
348
+ "Which market has the best price impact for buying 10 BTC?"
349
+ ```
350
+
351
+ ### How It Works
352
+
353
+ The OpenClaw skill provides:
354
+ - **Natural language market discovery** — "Find all markets for AAPL"
355
+ - **Intelligent routing guidance** — AI explains which market is best and why
356
+ - **Split order optimization** — "Split 200 TSLA across venues for lowest cost"
357
+ - **Quote explanations** — "The xyz:TSLA market has lowest price impact (0.8 bps) and favorable funding"
358
+ - **Automatic collateral handling** — Swaps USDC to USDH/USDT0 when needed for best execution
359
+ - **Aggregated data access** — View combined orderbooks and funding comparisons conversationally
360
+ - **Position summaries** — "Show my TSLA exposure across all collateral types"
361
+
362
+ ### Configuration
363
+
364
+ The skill works with your existing Hyperliquid Prime installation. No additional config needed — it uses the SDK directly.
365
+
366
+ For trading (not read-only), ensure your OpenClaw agent has access to your wallet or private key configuration.
367
+
368
+ ### Example Session
369
+
370
+ ```
371
+ You: Find the best market for buying 100 UNI
372
+ Agent: Found 4 markets for UNI. Analyzing...
373
+
374
+ Best route: xyz:UNI
375
+ - Price impact: 1.2 bps (lowest)
376
+ - Funding: -0.01% (you earn funding)
377
+ - Collateral: USDC (you hold USDC)
378
+
379
+ Alternative: cash:UNI
380
+ - Price impact: 2.8 bps
381
+ - Funding: +0.03%
382
+ - Collateral: USDT0
383
+
384
+ Recommendation: Route through xyz:UNI for lowest cost.
385
+
386
+ You: Execute it
387
+ Agent: Executed 100 UNI long on xyz:UNI
388
+ Filled: 100 UNI at avg price $12.34
389
+ Market: xyz:UNI
390
+ Status: success
391
+
392
+ You: Split 500 TSLA across all markets
393
+ Agent: Analyzing liquidity across 4 TSLA markets...
394
+
395
+ Split plan:
396
+ - xyz:TSLA → 300 (60%) — USDC, 0.9 bps impact
397
+ - flx:TSLA → 120 (24%) — USDH, 1.4 bps impact
398
+ - km:TSLA → 80 (16%) — USDH, 2.1 bps impact
399
+
400
+ Collateral: will be estimated at execution time from live balances (and swapped if needed)
401
+ Aggregate avg price: $431.42 (vs $432.10 single-market)
402
+
403
+ You: Execute the split
404
+ Agent: Executed 3-leg split order for 500 TSLA
405
+ Total filled: 500 TSLA at avg $431.42
406
+ Legs: xyz:TSLA (300), flx:TSLA (120), km:TSLA (80)
407
+ Collateral swaps: USDC → USDH completed
408
+ Status: success
409
+ ```
410
+
411
+ See [openclaw/SKILL.md](./openclaw/SKILL.md) for full skill documentation.
412
+
413
+ ## Development
414
+
415
+ ```bash
416
+ npm install
417
+ npm run build # Compile TypeScript
418
+ npm test # Run unit tests
419
+ npm run test:watch # Watch mode
420
+ npm run typecheck # Type check without emitting
421
+ npm run hp -- markets TSLA --testnet # Run CLI in dev mode
422
+ ```
423
+
424
+ ## License
425
+
426
+ MIT
@@ -0,0 +1,12 @@
1
+ import { HyperliquidPrime } from "../index.js";
2
+ /**
3
+ * Build a HyperliquidPrime client from CLI options.
4
+ */
5
+ export declare function createContext(opts: {
6
+ testnet?: boolean;
7
+ key?: string;
8
+ keyEnv?: string;
9
+ logLevel?: string;
10
+ builderFee?: boolean;
11
+ }): Promise<HyperliquidPrime>;
12
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6B5B"}
@@ -0,0 +1,27 @@
1
+ import { HyperliquidPrime } from "../index.js";
2
+ /**
3
+ * Build a HyperliquidPrime client from CLI options.
4
+ */
5
+ export async function createContext(opts) {
6
+ const keyEnv = opts.keyEnv ?? "HP_PRIVATE_KEY";
7
+ const keyFromCli = opts.key?.trim();
8
+ const keyFromEnv = process.env[keyEnv]?.trim();
9
+ const resolvedKey = keyFromCli || keyFromEnv;
10
+ if (keyFromCli) {
11
+ console.error("Warning: --key exposes secrets in shell history/process listings. Prefer environment variables.");
12
+ }
13
+ if (resolvedKey && !/^0x[0-9a-fA-F]{64}$/.test(resolvedKey)) {
14
+ throw new Error(`Invalid private key format. Expected a 0x-prefixed 64-hex string (source: ${keyFromCli ? "--key" : keyEnv})`);
15
+ }
16
+ const config = {
17
+ testnet: opts.testnet ?? false,
18
+ privateKey: resolvedKey,
19
+ logLevel: opts.logLevel ?? "warn",
20
+ prettyLogs: true,
21
+ builder: opts.builderFee === false ? null : undefined,
22
+ };
23
+ const hp = new HyperliquidPrime(config);
24
+ await hp.connect();
25
+ return hp;
26
+ }
27
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAMnC;IACC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC;IAC/C,MAAM,WAAW,GAAG,UAAU,IAAI,UAAU,CAAC;IAE7C,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,iGAAiG,CAClG,CAAC;IACJ,CAAC;IAED,IAAI,WAAW,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CACb,6EAA6E,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,CAC9G,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAA2B;QACrC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;QAC9B,UAAU,EAAE,WAAwC;QACpD,QAAQ,EAAG,IAAI,CAAC,QAA+C,IAAI,MAAM;QACzE,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;KACtD,CAAC;IAEF,MAAM,EAAE,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC;IACnB,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { createProgram } from "./program.js";
3
+ const program = createProgram();
4
+ program.parse();
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAChC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Output formatting for CLI commands.
3
+ */
4
+ export declare function formatJson(data: unknown): string;
5
+ export declare function formatTable(headers: string[], rows: string[][]): string;
6
+ export declare function output(data: unknown, json: boolean): void;
7
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,EAAE,MAAM,EAAE,EAAE,GACf,MAAM,CAgBR;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAQzD"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Output formatting for CLI commands.
3
+ */
4
+ export function formatJson(data) {
5
+ return JSON.stringify(data, null, 2);
6
+ }
7
+ export function formatTable(headers, rows) {
8
+ const colWidths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? "").length)));
9
+ const sep = colWidths.map((w) => "-".repeat(w)).join("-+-");
10
+ const headerLine = headers
11
+ .map((h, i) => h.padEnd(colWidths[i]))
12
+ .join(" | ");
13
+ const dataLines = rows
14
+ .map((r) => r.map((c, i) => (c ?? "").padEnd(colWidths[i])).join(" | "))
15
+ .join("\n");
16
+ return `${headerLine}\n${sep}\n${dataLines}`;
17
+ }
18
+ export function output(data, json) {
19
+ if (json) {
20
+ console.log(formatJson(data));
21
+ }
22
+ else if (typeof data === "string") {
23
+ console.log(data);
24
+ }
25
+ else {
26
+ console.log(formatJson(data));
27
+ }
28
+ }
29
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,OAAiB,EACjB,IAAgB;IAEhB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACrC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAC5D,CAAC;IAEF,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,OAAO;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;SACrC,IAAI,CAAC,KAAK,CAAC,CAAC;IACf,MAAM,SAAS,GAAG,IAAI;SACnB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAC5D;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO,GAAG,UAAU,KAAK,GAAG,KAAK,SAAS,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAa,EAAE,IAAa;IACjD,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAChC,CAAC;SAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAChC,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function createProgram(): Command;
3
+ //# sourceMappingURL=program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoDpC,wBAAgB,aAAa,IAAI,OAAO,CAiPvC"}