@continuumdao/ctm-mpc-defi 0.2.8 → 0.2.10
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.
- package/dist/agent/catalog.cjs +1133 -2
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +1268 -9
- package/dist/agent/catalog.js +1091 -3
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/hyperliquid/SKILL.md +205 -0
- package/dist/agent/skills/morpho/SKILL.md +48 -0
- package/dist/core/index.cjs +9 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.js +8 -1
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +9 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/aave-v4/index.js.map +1 -1
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/dist/protocols/evm/hyperliquid/index.cjs +1550 -0
- package/dist/protocols/evm/hyperliquid/index.cjs.map +1 -0
- package/dist/protocols/evm/hyperliquid/index.d.ts +668 -0
- package/dist/protocols/evm/hyperliquid/index.js +1464 -0
- package/dist/protocols/evm/hyperliquid/index.js.map +1 -0
- package/dist/protocols/evm/maple/index.cjs.map +1 -1
- package/dist/protocols/evm/maple/index.js.map +1 -1
- package/dist/protocols/evm/morpho/index.cjs +1971 -0
- package/dist/protocols/evm/morpho/index.cjs.map +1 -0
- package/dist/protocols/evm/morpho/index.d.ts +522 -0
- package/dist/protocols/evm/morpho/index.js +1918 -0
- package/dist/protocols/evm/morpho/index.js.map +1 -0
- package/dist/protocols/evm/sky/index.cjs.map +1 -1
- package/dist/protocols/evm/sky/index.js.map +1 -1
- package/package.json +11 -1
|
@@ -0,0 +1,1464 @@
|
|
|
1
|
+
import { parseAbi, encodeAbiParameters, getAddress, encodeFunctionData, defineChain, createPublicClient, http, parseGwei, serializeTransaction, keccak256 } from 'viem';
|
|
2
|
+
import { fetchChainFeeParams, gasLimitFromEstimateAndChainConfig, gweiToDecimalString, proposalTxParamsToFeeSnapshot, alignEip1559FeesWithLatestBase, getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk';
|
|
3
|
+
|
|
4
|
+
// src/core/registry.ts
|
|
5
|
+
var modules = [];
|
|
6
|
+
function registerProtocolModule(mod) {
|
|
7
|
+
const existing = modules.findIndex((m) => m.id === mod.id);
|
|
8
|
+
if (existing >= 0) {
|
|
9
|
+
modules[existing] = mod;
|
|
10
|
+
} else {
|
|
11
|
+
modules.push(mod);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/protocols/evm/hyperliquid/support.ts
|
|
16
|
+
var HYPERLIQUID_SUPPORTED_CHAIN_IDS = [999, 998];
|
|
17
|
+
function isHyperliquidChainSupported(chainId) {
|
|
18
|
+
return HYPERLIQUID_SUPPORTED_CHAIN_IDS.includes(chainId);
|
|
19
|
+
}
|
|
20
|
+
function hyperliquidApiBaseUrl(chainId) {
|
|
21
|
+
return chainId === 998 ? "https://api.hyperliquid-testnet.xyz" : "https://api.hyperliquid.xyz";
|
|
22
|
+
}
|
|
23
|
+
function hyperliquidVaultStatsUrl(chainId) {
|
|
24
|
+
return chainId === 998 ? null : "https://stats-data.hyperliquid.xyz/Mainnet/vaults";
|
|
25
|
+
}
|
|
26
|
+
var HYPERLIQUID_HLP_VAULT_ADDRESS = "0xdfc24b077bc1425ad1dea75bcb6f8158e10df303";
|
|
27
|
+
function hyperliquidInferDexFromCoin(coin) {
|
|
28
|
+
const trimmed = coin.trim();
|
|
29
|
+
const sep = trimmed.indexOf(":");
|
|
30
|
+
if (sep <= 0) return void 0;
|
|
31
|
+
return trimmed.slice(0, sep);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/protocols/evm/hyperliquid/constants.ts
|
|
35
|
+
var HYPERLIQUID_CORE_WRITER_ADDRESS = "0x3333333333333333333333333333333333333333";
|
|
36
|
+
var HYPERLIQUID_SPOT_ASSET_OFFSET = 1e4;
|
|
37
|
+
var HYPERLIQUID_CORE_WRITER_GAS_FALLBACK = 120000n;
|
|
38
|
+
var HYPERLIQUID_TIF = {
|
|
39
|
+
alo: 1,
|
|
40
|
+
gtc: 2,
|
|
41
|
+
ioc: 3
|
|
42
|
+
};
|
|
43
|
+
var HYPERLIQUID_INTERVAL_MS = {
|
|
44
|
+
"1m": 6e4,
|
|
45
|
+
"3m": 18e4,
|
|
46
|
+
"5m": 3e5,
|
|
47
|
+
"15m": 9e5,
|
|
48
|
+
"30m": 18e5,
|
|
49
|
+
"1h": 36e5,
|
|
50
|
+
"2h": 72e5,
|
|
51
|
+
"4h": 144e5,
|
|
52
|
+
"8h": 288e5,
|
|
53
|
+
"12h": 432e5,
|
|
54
|
+
"1d": 864e5,
|
|
55
|
+
"3d": 2592e5,
|
|
56
|
+
"1w": 6048e5,
|
|
57
|
+
"1M": 2592e6
|
|
58
|
+
};
|
|
59
|
+
var HYPERLIQUID_DEFAULT_OHLCV_INTERVAL = "15m";
|
|
60
|
+
var HYPERLIQUID_DEFAULT_CANDLE_LIMIT = 48;
|
|
61
|
+
var HYPERLIQUID_MAX_CANDLE_LIMIT = 200;
|
|
62
|
+
var HYPERLIQUID_MAX_OHLCV_BARS = 2e3;
|
|
63
|
+
var HYPERLIQUID_DEFAULT_LOOKBACK_DAYS = 1;
|
|
64
|
+
var HYPERLIQUID_MAX_LOOKBACK_DAYS = 90;
|
|
65
|
+
|
|
66
|
+
// src/protocols/evm/hyperliquid/api.ts
|
|
67
|
+
async function hyperliquidInfoPost(chainId, body) {
|
|
68
|
+
const base = hyperliquidApiBaseUrl(chainId);
|
|
69
|
+
const res = await fetch(`${base}/info`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: { "Content-Type": "application/json" },
|
|
72
|
+
body: JSON.stringify(body),
|
|
73
|
+
cache: "no-store"
|
|
74
|
+
});
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
const text = await res.text().catch(() => "");
|
|
77
|
+
throw new Error(`Hyperliquid info API failed (${res.status}): ${text.slice(0, 200)}`);
|
|
78
|
+
}
|
|
79
|
+
return await res.json();
|
|
80
|
+
}
|
|
81
|
+
async function hyperliquidFetchPerpMeta(args) {
|
|
82
|
+
const req = { type: "meta" };
|
|
83
|
+
if (args.dex?.trim()) req.dex = args.dex.trim();
|
|
84
|
+
const meta = await hyperliquidInfoPost(args.chainId, req);
|
|
85
|
+
const markets = (meta.universe ?? []).map((u, i) => ({
|
|
86
|
+
name: u.name,
|
|
87
|
+
asset: i,
|
|
88
|
+
szDecimals: u.szDecimals,
|
|
89
|
+
maxLeverage: u.maxLeverage,
|
|
90
|
+
onlyIsolated: u.onlyIsolated
|
|
91
|
+
}));
|
|
92
|
+
return { markets };
|
|
93
|
+
}
|
|
94
|
+
async function hyperliquidFetchSpotMeta(args) {
|
|
95
|
+
const meta = await hyperliquidInfoPost(args.chainId, { type: "spotMeta" });
|
|
96
|
+
const tokenByIndex = new Map((meta.tokens ?? []).map((t) => [t.index, t]));
|
|
97
|
+
const markets = (meta.universe ?? []).map((u, i) => {
|
|
98
|
+
const baseTokenIdx = u.tokens[0];
|
|
99
|
+
const token = baseTokenIdx != null ? tokenByIndex.get(baseTokenIdx) : void 0;
|
|
100
|
+
return {
|
|
101
|
+
name: u.name,
|
|
102
|
+
asset: 1e4 + i,
|
|
103
|
+
tokenIndex: i,
|
|
104
|
+
szDecimals: token?.szDecimals ?? 8
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
return { markets };
|
|
108
|
+
}
|
|
109
|
+
async function hyperliquidFetchAllMids(args) {
|
|
110
|
+
const req = { type: "allMids" };
|
|
111
|
+
if (args.dex?.trim()) req.dex = args.dex.trim();
|
|
112
|
+
const mids = await hyperliquidInfoPost(args.chainId, req);
|
|
113
|
+
return { mids };
|
|
114
|
+
}
|
|
115
|
+
function hyperliquidMapCandles(raw) {
|
|
116
|
+
return (raw ?? []).map((c) => ({
|
|
117
|
+
timestampMs: c.t,
|
|
118
|
+
open: c.o,
|
|
119
|
+
high: c.h,
|
|
120
|
+
low: c.l,
|
|
121
|
+
close: c.c,
|
|
122
|
+
volume: c.v
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
async function hyperliquidFetchCandlesRaw(args) {
|
|
126
|
+
const raw = await hyperliquidInfoPost(args.chainId, {
|
|
127
|
+
type: "candleSnapshot",
|
|
128
|
+
req: {
|
|
129
|
+
coin: args.coin,
|
|
130
|
+
interval: args.interval,
|
|
131
|
+
startTime: args.startTimeMs,
|
|
132
|
+
endTime: args.endTimeMs
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return hyperliquidMapCandles(raw);
|
|
136
|
+
}
|
|
137
|
+
function hyperliquidResolveOhlcvWindow(args) {
|
|
138
|
+
const endTimeMs = args.endTimeMs ?? Date.now();
|
|
139
|
+
const intervalMs = HYPERLIQUID_INTERVAL_MS[args.interval] ?? HYPERLIQUID_INTERVAL_MS["15m"];
|
|
140
|
+
let startTimeMs;
|
|
141
|
+
if (args.startTimeMs != null) {
|
|
142
|
+
startTimeMs = args.startTimeMs;
|
|
143
|
+
} else if (args.lookbackDays != null) {
|
|
144
|
+
if (args.lookbackDays <= 0 || args.lookbackDays > HYPERLIQUID_MAX_LOOKBACK_DAYS) {
|
|
145
|
+
throw new Error(`lookbackDays must be between 1 and ${HYPERLIQUID_MAX_LOOKBACK_DAYS}`);
|
|
146
|
+
}
|
|
147
|
+
startTimeMs = endTimeMs - args.lookbackDays * 864e5;
|
|
148
|
+
} else if (args.lookbackHours != null) {
|
|
149
|
+
if (args.lookbackHours <= 0 || args.lookbackHours > HYPERLIQUID_MAX_LOOKBACK_DAYS * 24) {
|
|
150
|
+
throw new Error(`lookbackHours must be between 1 and ${HYPERLIQUID_MAX_LOOKBACK_DAYS * 24}`);
|
|
151
|
+
}
|
|
152
|
+
startTimeMs = endTimeMs - args.lookbackHours * 36e5;
|
|
153
|
+
} else {
|
|
154
|
+
startTimeMs = endTimeMs - HYPERLIQUID_DEFAULT_LOOKBACK_DAYS * 864e5;
|
|
155
|
+
}
|
|
156
|
+
if (!Number.isFinite(startTimeMs) || !Number.isFinite(endTimeMs) || startTimeMs >= endTimeMs) {
|
|
157
|
+
throw new Error("Invalid OHLCV time range: startTimeMs must be before endTimeMs");
|
|
158
|
+
}
|
|
159
|
+
const expectedBars = Math.ceil((endTimeMs - startTimeMs) / intervalMs);
|
|
160
|
+
if (expectedBars > HYPERLIQUID_MAX_OHLCV_BARS) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`OHLCV range needs ~${expectedBars} bars at ${args.interval} (max ${HYPERLIQUID_MAX_OHLCV_BARS}). Use a coarser interval or shorter lookback.`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
return { startTimeMs, endTimeMs, expectedBars };
|
|
166
|
+
}
|
|
167
|
+
async function hyperliquidFetchCandles(args) {
|
|
168
|
+
const endTime = args.endTimeMs ?? Date.now();
|
|
169
|
+
const intervalMs = HYPERLIQUID_INTERVAL_MS[args.interval] ?? HYPERLIQUID_INTERVAL_MS["15m"];
|
|
170
|
+
const limit = Math.min(Math.max(args.limit ?? HYPERLIQUID_DEFAULT_CANDLE_LIMIT, 1), HYPERLIQUID_MAX_CANDLE_LIMIT);
|
|
171
|
+
const startTime = args.startTimeMs ?? endTime - intervalMs * (limit + 4);
|
|
172
|
+
const candles = await hyperliquidFetchCandlesRaw({
|
|
173
|
+
chainId: args.chainId,
|
|
174
|
+
coin: args.coin,
|
|
175
|
+
interval: args.interval,
|
|
176
|
+
startTimeMs: startTime,
|
|
177
|
+
endTimeMs: endTime
|
|
178
|
+
});
|
|
179
|
+
return { candles: candles.slice(-limit) };
|
|
180
|
+
}
|
|
181
|
+
async function hyperliquidFetchOhlcvRange(args) {
|
|
182
|
+
const coin = args.coin.trim();
|
|
183
|
+
const interval = args.interval ?? HYPERLIQUID_DEFAULT_OHLCV_INTERVAL;
|
|
184
|
+
const dex = args.dex?.trim() || hyperliquidInferDexFromCoin(coin) || null;
|
|
185
|
+
const { startTimeMs, endTimeMs, expectedBars } = hyperliquidResolveOhlcvWindow({
|
|
186
|
+
interval,
|
|
187
|
+
lookbackDays: args.lookbackDays,
|
|
188
|
+
lookbackHours: args.lookbackHours,
|
|
189
|
+
startTimeMs: args.startTimeMs,
|
|
190
|
+
endTimeMs: args.endTimeMs
|
|
191
|
+
});
|
|
192
|
+
const candles = await hyperliquidFetchCandlesRaw({
|
|
193
|
+
chainId: args.chainId,
|
|
194
|
+
coin,
|
|
195
|
+
interval,
|
|
196
|
+
startTimeMs,
|
|
197
|
+
endTimeMs
|
|
198
|
+
});
|
|
199
|
+
if (candles.length === 0) {
|
|
200
|
+
throw new Error(
|
|
201
|
+
`No OHLCV data for ${coin} between ${startTimeMs} and ${endTimeMs} at ${interval}. Check coin/dex.`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
const latestCandle = candles.length > 0 ? candles[candles.length - 1] : null;
|
|
205
|
+
return {
|
|
206
|
+
coin,
|
|
207
|
+
dex,
|
|
208
|
+
interval,
|
|
209
|
+
startTimeMs,
|
|
210
|
+
endTimeMs,
|
|
211
|
+
expectedBars,
|
|
212
|
+
candleCount: candles.length,
|
|
213
|
+
latestCandle,
|
|
214
|
+
candles,
|
|
215
|
+
fetchedAtMs: Date.now()
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
async function hyperliquidFetchPerpAssetContext(args) {
|
|
219
|
+
const coin = args.coin.trim();
|
|
220
|
+
const dex = args.dex?.trim() || hyperliquidInferDexFromCoin(coin) || "";
|
|
221
|
+
const req = { type: "metaAndAssetCtxs" };
|
|
222
|
+
if (dex) req.dex = dex;
|
|
223
|
+
const raw = await hyperliquidInfoPost(args.chainId, req);
|
|
224
|
+
const universe = raw?.[0]?.universe ?? [];
|
|
225
|
+
const contexts = raw?.[1] ?? [];
|
|
226
|
+
const idx = universe.findIndex((u) => u.name === coin);
|
|
227
|
+
if (idx < 0) {
|
|
228
|
+
throw new Error(`Hyperliquid asset context not found for ${coin}${dex ? ` on dex ${dex}` : ""}`);
|
|
229
|
+
}
|
|
230
|
+
const ctx = contexts[idx] ?? {};
|
|
231
|
+
const str = (v) => {
|
|
232
|
+
const s = String(v ?? "").trim();
|
|
233
|
+
return s || null;
|
|
234
|
+
};
|
|
235
|
+
return {
|
|
236
|
+
markPx: str(ctx.markPx),
|
|
237
|
+
midPx: str(ctx.midPx),
|
|
238
|
+
oraclePx: str(ctx.oraclePx),
|
|
239
|
+
prevDayPx: str(ctx.prevDayPx),
|
|
240
|
+
funding: str(ctx.funding),
|
|
241
|
+
openInterest: str(ctx.openInterest)
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function hyperliquidPickLivePrice(args) {
|
|
245
|
+
const midUsd = args.midPx ?? args.markPx ?? args.midFromAllMids;
|
|
246
|
+
if (!midUsd) {
|
|
247
|
+
throw new Error("Could not fetch live Hyperliquid price (mark, mid, and allMids all empty)");
|
|
248
|
+
}
|
|
249
|
+
const source = args.midPx ? "midPx" : args.markPx ? "markPx" : "allMids";
|
|
250
|
+
return {
|
|
251
|
+
markPx: args.markPx,
|
|
252
|
+
midPx: args.midPx,
|
|
253
|
+
oraclePx: null,
|
|
254
|
+
prevDayPx: null,
|
|
255
|
+
midUsd,
|
|
256
|
+
source
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
async function hyperliquidFetchMarketSnapshot(args) {
|
|
260
|
+
const coin = args.coin.trim();
|
|
261
|
+
const interval = args.interval ?? HYPERLIQUID_DEFAULT_OHLCV_INTERVAL;
|
|
262
|
+
const dex = args.dex?.trim() || hyperliquidInferDexFromCoin(coin) || null;
|
|
263
|
+
const candleLimit = Math.min(
|
|
264
|
+
Math.max(args.candleLimit ?? HYPERLIQUID_DEFAULT_CANDLE_LIMIT, 1),
|
|
265
|
+
HYPERLIQUID_MAX_CANDLE_LIMIT
|
|
266
|
+
);
|
|
267
|
+
const [{ mids }, assetCtx, { candles }] = await Promise.all([
|
|
268
|
+
hyperliquidFetchAllMids({ chainId: args.chainId, dex: dex ?? void 0 }),
|
|
269
|
+
hyperliquidFetchPerpAssetContext({ chainId: args.chainId, coin, dex: dex ?? void 0 }),
|
|
270
|
+
hyperliquidFetchCandles({
|
|
271
|
+
chainId: args.chainId,
|
|
272
|
+
coin,
|
|
273
|
+
interval,
|
|
274
|
+
limit: candleLimit
|
|
275
|
+
})
|
|
276
|
+
]);
|
|
277
|
+
const midFromAllMids = mids[coin] ?? null;
|
|
278
|
+
const livePrice = {
|
|
279
|
+
...hyperliquidPickLivePrice({
|
|
280
|
+
markPx: assetCtx.markPx,
|
|
281
|
+
midPx: assetCtx.midPx,
|
|
282
|
+
midFromAllMids
|
|
283
|
+
}),
|
|
284
|
+
oraclePx: assetCtx.oraclePx,
|
|
285
|
+
prevDayPx: assetCtx.prevDayPx
|
|
286
|
+
};
|
|
287
|
+
const latestCandle = candles.length > 0 ? candles[candles.length - 1] : null;
|
|
288
|
+
return {
|
|
289
|
+
coin,
|
|
290
|
+
dex,
|
|
291
|
+
livePrice,
|
|
292
|
+
midUsd: livePrice.midUsd,
|
|
293
|
+
fetchedAtMs: Date.now(),
|
|
294
|
+
interval,
|
|
295
|
+
latestCandle,
|
|
296
|
+
candles,
|
|
297
|
+
candleCount: candles.length
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
async function hyperliquidFetchClearinghouseState(args) {
|
|
301
|
+
const req = { type: "clearinghouseState", user: args.user };
|
|
302
|
+
if (args.dex?.trim()) req.dex = args.dex.trim();
|
|
303
|
+
const state = await hyperliquidInfoPost(args.chainId, req);
|
|
304
|
+
return { state };
|
|
305
|
+
}
|
|
306
|
+
async function hyperliquidFetchSpotClearinghouseState(args) {
|
|
307
|
+
const state = await hyperliquidInfoPost(args.chainId, {
|
|
308
|
+
type: "spotClearinghouseState",
|
|
309
|
+
user: args.user
|
|
310
|
+
});
|
|
311
|
+
return { state };
|
|
312
|
+
}
|
|
313
|
+
function hyperliquidFmtLeverage(leverage) {
|
|
314
|
+
if (leverage?.value == null) return null;
|
|
315
|
+
const t = leverage.type === "isolated" ? "iso" : "cross";
|
|
316
|
+
return `${leverage.value}x ${t}`;
|
|
317
|
+
}
|
|
318
|
+
function hyperliquidPositiveSizeString(value) {
|
|
319
|
+
const n = Number.parseFloat(String(value ?? "0"));
|
|
320
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
321
|
+
return String(n);
|
|
322
|
+
}
|
|
323
|
+
async function hyperliquidFetchActiveAssetData(args) {
|
|
324
|
+
const raw = await hyperliquidInfoPost(args.chainId, {
|
|
325
|
+
type: "activeAssetData",
|
|
326
|
+
user: args.user,
|
|
327
|
+
coin: args.coin.trim()
|
|
328
|
+
});
|
|
329
|
+
const avail = raw.availableToTrade;
|
|
330
|
+
return {
|
|
331
|
+
activeAsset: {
|
|
332
|
+
markPx: raw.markPx?.trim() || null,
|
|
333
|
+
leverageLabel: hyperliquidFmtLeverage(raw.leverage),
|
|
334
|
+
availableToBuy: avail?.[0] != null ? hyperliquidPositiveSizeString(avail[0]) : null,
|
|
335
|
+
availableToSell: avail?.[1] != null ? hyperliquidPositiveSizeString(avail[1]) : null
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
async function hyperliquidFetchOpenOrders(args) {
|
|
340
|
+
const req = { type: "openOrders", user: args.user };
|
|
341
|
+
if (args.dex?.trim()) req.dex = args.dex.trim();
|
|
342
|
+
const orders = await hyperliquidInfoPost(args.chainId, req);
|
|
343
|
+
return { orders: orders ?? [] };
|
|
344
|
+
}
|
|
345
|
+
async function hyperliquidFetchUserVaultEquities(args) {
|
|
346
|
+
const rows = await hyperliquidInfoPost(args.chainId, {
|
|
347
|
+
type: "userVaultEquities",
|
|
348
|
+
user: args.user
|
|
349
|
+
});
|
|
350
|
+
return { rows: rows ?? [] };
|
|
351
|
+
}
|
|
352
|
+
var VAULT_CATALOG_MAX = 40;
|
|
353
|
+
var VAULT_MIN_TVL_USD = 1e3;
|
|
354
|
+
function vaultSummaryFromStatsRow(row) {
|
|
355
|
+
const summary = row.summary;
|
|
356
|
+
if (!summary?.vaultAddress?.trim() || !summary.name?.trim() || summary.isClosed) return null;
|
|
357
|
+
const tvl = Number.parseFloat(summary.tvl ?? "");
|
|
358
|
+
if (!Number.isFinite(tvl) || tvl < VAULT_MIN_TVL_USD) return null;
|
|
359
|
+
return {
|
|
360
|
+
vaultAddress: summary.vaultAddress,
|
|
361
|
+
name: summary.name.trim(),
|
|
362
|
+
apr: typeof row.apr === "number" && Number.isFinite(row.apr) ? row.apr : null,
|
|
363
|
+
tvlUsd: summary.tvl ?? null
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function sortVaultCatalog(vaults) {
|
|
367
|
+
const hlp = HYPERLIQUID_HLP_VAULT_ADDRESS.toLowerCase();
|
|
368
|
+
return [...vaults].sort((a, b) => {
|
|
369
|
+
const aHlp = a.vaultAddress.toLowerCase() === hlp;
|
|
370
|
+
const bHlp = b.vaultAddress.toLowerCase() === hlp;
|
|
371
|
+
if (aHlp && !bHlp) return -1;
|
|
372
|
+
if (bHlp && !aHlp) return 1;
|
|
373
|
+
return Number.parseFloat(b.tvlUsd ?? "0") - Number.parseFloat(a.tvlUsd ?? "0");
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
async function hyperliquidFetchVaultCatalogFromStats(chainId) {
|
|
377
|
+
const statsUrl = hyperliquidVaultStatsUrl(chainId);
|
|
378
|
+
if (!statsUrl) return [];
|
|
379
|
+
const res = await fetch(statsUrl, { cache: "no-store" });
|
|
380
|
+
if (!res.ok) {
|
|
381
|
+
const text = await res.text().catch(() => "");
|
|
382
|
+
throw new Error(`Hyperliquid vault stats failed (${res.status}): ${text.slice(0, 200)}`);
|
|
383
|
+
}
|
|
384
|
+
const raw = await res.json();
|
|
385
|
+
const byAddr = /* @__PURE__ */ new Map();
|
|
386
|
+
for (const row of raw ?? []) {
|
|
387
|
+
const vault = vaultSummaryFromStatsRow(row);
|
|
388
|
+
if (!vault) continue;
|
|
389
|
+
byAddr.set(vault.vaultAddress.toLowerCase(), vault);
|
|
390
|
+
}
|
|
391
|
+
return sortVaultCatalog([...byAddr.values()]).slice(0, VAULT_CATALOG_MAX);
|
|
392
|
+
}
|
|
393
|
+
async function hyperliquidFetchVaultDetails(args) {
|
|
394
|
+
const raw = await hyperliquidInfoPost(args.chainId, {
|
|
395
|
+
type: "vaultDetails",
|
|
396
|
+
vaultAddress: args.vaultAddress
|
|
397
|
+
});
|
|
398
|
+
if (!raw?.vaultAddress?.trim() || !raw.name?.trim() || raw.isClosed) return null;
|
|
399
|
+
return {
|
|
400
|
+
vaultAddress: raw.vaultAddress,
|
|
401
|
+
name: raw.name.trim(),
|
|
402
|
+
apr: typeof raw.apr === "number" && Number.isFinite(raw.apr) ? raw.apr : null,
|
|
403
|
+
tvlUsd: null
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
async function hyperliquidFetchVaultSummaries(args) {
|
|
407
|
+
const catalog = await hyperliquidFetchVaultCatalogFromStats(args.chainId);
|
|
408
|
+
const byAddr = new Map(catalog.map((v) => [v.vaultAddress.toLowerCase(), v]));
|
|
409
|
+
const executor = args.executorAddress?.trim().toLowerCase();
|
|
410
|
+
if (executor) {
|
|
411
|
+
const { rows } = await hyperliquidFetchUserVaultEquities({ chainId: args.chainId, user: executor });
|
|
412
|
+
const missing = rows.filter((r) => r.vaultAddress && !byAddr.has(r.vaultAddress.toLowerCase()));
|
|
413
|
+
const extras = await Promise.all(
|
|
414
|
+
missing.map(async (r) => hyperliquidFetchVaultDetails({ chainId: args.chainId, vaultAddress: r.vaultAddress }))
|
|
415
|
+
);
|
|
416
|
+
for (const vault of extras) {
|
|
417
|
+
if (vault) byAddr.set(vault.vaultAddress.toLowerCase(), vault);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return { vaults: sortVaultCatalog([...byAddr.values()]) };
|
|
421
|
+
}
|
|
422
|
+
async function hyperliquidFetchDexList(args) {
|
|
423
|
+
const raw = await hyperliquidInfoPost(args.chainId, {
|
|
424
|
+
type: "perpDexs"
|
|
425
|
+
});
|
|
426
|
+
if (!Array.isArray(raw)) return { dexes: [] };
|
|
427
|
+
const dexes = [];
|
|
428
|
+
for (const entry of raw) {
|
|
429
|
+
if (entry == null) continue;
|
|
430
|
+
if (typeof entry === "string") {
|
|
431
|
+
const name2 = entry.trim();
|
|
432
|
+
if (name2) dexes.push({ name: name2, fullName: name2 });
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
const name = entry.name?.trim();
|
|
436
|
+
if (!name) continue;
|
|
437
|
+
const fullName = entry.fullName?.trim() || name;
|
|
438
|
+
dexes.push({ name, fullName });
|
|
439
|
+
}
|
|
440
|
+
return { dexes };
|
|
441
|
+
}
|
|
442
|
+
async function hyperliquidFetchPerpConciseAnnotations(args) {
|
|
443
|
+
const raw = await hyperliquidInfoPost(args.chainId, {
|
|
444
|
+
type: "perpConciseAnnotations"
|
|
445
|
+
});
|
|
446
|
+
const map = /* @__PURE__ */ new Map();
|
|
447
|
+
if (!Array.isArray(raw)) return map;
|
|
448
|
+
for (const entry of raw) {
|
|
449
|
+
if (!Array.isArray(entry) || entry.length < 2) continue;
|
|
450
|
+
const coin = String(entry[0] ?? "").trim();
|
|
451
|
+
const meta = entry[1];
|
|
452
|
+
if (!coin || !meta || typeof meta !== "object") continue;
|
|
453
|
+
map.set(coin, meta);
|
|
454
|
+
}
|
|
455
|
+
return map;
|
|
456
|
+
}
|
|
457
|
+
async function hyperliquidFetchDelegations(args) {
|
|
458
|
+
const raw = await hyperliquidInfoPost(args.chainId, {
|
|
459
|
+
type: "delegations",
|
|
460
|
+
user: args.user
|
|
461
|
+
});
|
|
462
|
+
return { delegations: raw ?? [] };
|
|
463
|
+
}
|
|
464
|
+
async function hyperliquidFetchStakingSummary(args) {
|
|
465
|
+
const raw = await hyperliquidInfoPost(args.chainId, {
|
|
466
|
+
type: "delegatorSummary",
|
|
467
|
+
user: args.user
|
|
468
|
+
});
|
|
469
|
+
return { delegated: raw?.delegated ?? "0", undelegated: raw?.undelegated ?? "0" };
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// src/protocols/evm/hyperliquid/marketSearch.ts
|
|
473
|
+
function normalizeQuery(value) {
|
|
474
|
+
return value.trim().toLowerCase();
|
|
475
|
+
}
|
|
476
|
+
function compactCoin(value) {
|
|
477
|
+
return normalizeQuery(value).replace(/[^a-z0-9]/g, "");
|
|
478
|
+
}
|
|
479
|
+
function hyperliquidMarketSymbol(coin) {
|
|
480
|
+
const sep = coin.indexOf(":");
|
|
481
|
+
return sep >= 0 ? coin.slice(sep + 1) : coin;
|
|
482
|
+
}
|
|
483
|
+
function scoreMarketMatch(query, market, annotation) {
|
|
484
|
+
const q = normalizeQuery(query);
|
|
485
|
+
if (!q) return null;
|
|
486
|
+
const coin = market.name;
|
|
487
|
+
const symbol = hyperliquidMarketSymbol(coin);
|
|
488
|
+
const coinLower = normalizeQuery(coin);
|
|
489
|
+
const symbolLower = normalizeQuery(symbol);
|
|
490
|
+
if (coinLower === q) return { score: 100, reason: "exact coin name" };
|
|
491
|
+
if (symbolLower === q) return { score: 95, reason: "exact ticker symbol" };
|
|
492
|
+
if (compactCoin(coin) === compactCoin(q)) return { score: 92, reason: "coin name without separators" };
|
|
493
|
+
if (annotation?.displayName) {
|
|
494
|
+
const display = normalizeQuery(annotation.displayName);
|
|
495
|
+
if (display === q) return { score: 94, reason: "exact display name" };
|
|
496
|
+
if (display.includes(q) || q.includes(display)) return { score: 72, reason: "display name partial match" };
|
|
497
|
+
}
|
|
498
|
+
for (const keyword of annotation?.keywords ?? []) {
|
|
499
|
+
const kw = normalizeQuery(keyword);
|
|
500
|
+
if (!kw) continue;
|
|
501
|
+
if (kw === q) return { score: 88, reason: `keyword "${keyword}"` };
|
|
502
|
+
if (kw.includes(q) || q.includes(kw)) return { score: 68, reason: `keyword partial "${keyword}"` };
|
|
503
|
+
}
|
|
504
|
+
if (symbolLower.includes(q) || q.includes(symbolLower)) {
|
|
505
|
+
return { score: 78, reason: "ticker partial match" };
|
|
506
|
+
}
|
|
507
|
+
if (!coin.includes(":") && coinLower.includes(q)) {
|
|
508
|
+
return { score: 65, reason: "native coin partial match" };
|
|
509
|
+
}
|
|
510
|
+
if (market.dex && normalizeQuery(market.dex) === q) {
|
|
511
|
+
return { score: 40, reason: "dex name match" };
|
|
512
|
+
}
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
515
|
+
async function hyperliquidCollectAllPerpMarkets(args) {
|
|
516
|
+
const dexFilter = args.dex?.trim();
|
|
517
|
+
const { dexes } = await hyperliquidFetchDexList({ chainId: args.chainId });
|
|
518
|
+
if (dexFilter) {
|
|
519
|
+
const { markets: markets2 } = await hyperliquidFetchPerpMeta({ chainId: args.chainId, dex: dexFilter });
|
|
520
|
+
return { markets: markets2.map((m) => ({ ...m, dex: dexFilter })), dexes };
|
|
521
|
+
}
|
|
522
|
+
const { markets: nativeMarkets } = await hyperliquidFetchPerpMeta({ chainId: args.chainId });
|
|
523
|
+
const markets = [...nativeMarkets];
|
|
524
|
+
const hip3Batches = await Promise.all(
|
|
525
|
+
dexes.map(async (d) => {
|
|
526
|
+
const { markets: dexMarkets } = await hyperliquidFetchPerpMeta({ chainId: args.chainId, dex: d.name });
|
|
527
|
+
return dexMarkets.map((m) => ({ ...m, dex: d.name }));
|
|
528
|
+
})
|
|
529
|
+
);
|
|
530
|
+
for (const batch of hip3Batches) markets.push(...batch);
|
|
531
|
+
return { markets, dexes };
|
|
532
|
+
}
|
|
533
|
+
async function hyperliquidSearchMarkets(args) {
|
|
534
|
+
const query = args.query.trim();
|
|
535
|
+
if (!query) return { matches: [] };
|
|
536
|
+
const limit = Math.max(1, Math.min(args.limit ?? 20, 50));
|
|
537
|
+
const [{ markets }, annotationMap] = await Promise.all([
|
|
538
|
+
hyperliquidCollectAllPerpMarkets({ chainId: args.chainId, dex: args.dex?.trim() }),
|
|
539
|
+
hyperliquidFetchPerpConciseAnnotations({ chainId: args.chainId })
|
|
540
|
+
]);
|
|
541
|
+
const hits = [];
|
|
542
|
+
for (const market of markets) {
|
|
543
|
+
const annotation = annotationMap.get(market.name);
|
|
544
|
+
const scored = scoreMarketMatch(query, market, annotation);
|
|
545
|
+
if (!scored || scored.score < 40) continue;
|
|
546
|
+
hits.push({
|
|
547
|
+
coin: market.name,
|
|
548
|
+
symbol: hyperliquidMarketSymbol(market.name),
|
|
549
|
+
dex: market.dex,
|
|
550
|
+
asset: market.asset,
|
|
551
|
+
szDecimals: market.szDecimals,
|
|
552
|
+
maxLeverage: market.maxLeverage,
|
|
553
|
+
onlyIsolated: market.onlyIsolated,
|
|
554
|
+
displayName: annotation?.displayName,
|
|
555
|
+
category: annotation?.category,
|
|
556
|
+
keywords: annotation?.keywords,
|
|
557
|
+
matchScore: scored.score,
|
|
558
|
+
matchReason: scored.reason
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
hits.sort((a, b) => b.matchScore - a.matchScore || a.coin.localeCompare(b.coin));
|
|
562
|
+
return { matches: hits.slice(0, limit) };
|
|
563
|
+
}
|
|
564
|
+
async function hyperliquidResolvePerpMarket(args) {
|
|
565
|
+
const coin = args.coin.trim();
|
|
566
|
+
if (!coin) throw new Error("coin is required");
|
|
567
|
+
const dex = args.dex?.trim() || hyperliquidInferDexFromCoin(coin);
|
|
568
|
+
if (dex || !coin.includes(":")) {
|
|
569
|
+
const { markets } = await hyperliquidFetchPerpMeta({ chainId: args.chainId, dex });
|
|
570
|
+
const direct = markets.find((m) => m.name.toLowerCase() === coin.toLowerCase());
|
|
571
|
+
if (direct) {
|
|
572
|
+
return {
|
|
573
|
+
...direct,
|
|
574
|
+
dex: dex || direct.dex,
|
|
575
|
+
symbol: hyperliquidMarketSymbol(direct.name)
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
const { matches } = await hyperliquidSearchMarkets({ chainId: args.chainId, query: coin, dex: args.dex, limit: 10 });
|
|
580
|
+
const bestScore = matches[0]?.matchScore ?? 0;
|
|
581
|
+
if (bestScore < 60) throw new Error(`Unknown Hyperliquid perp market: ${coin}`);
|
|
582
|
+
const top = matches.filter((m) => m.matchScore === bestScore);
|
|
583
|
+
if (top.length === 1) {
|
|
584
|
+
const m = top[0];
|
|
585
|
+
return {
|
|
586
|
+
name: m.coin,
|
|
587
|
+
asset: m.asset,
|
|
588
|
+
szDecimals: m.szDecimals,
|
|
589
|
+
maxLeverage: m.maxLeverage,
|
|
590
|
+
onlyIsolated: m.onlyIsolated,
|
|
591
|
+
dex: m.dex,
|
|
592
|
+
symbol: m.symbol
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
throw new Error(
|
|
596
|
+
`Ambiguous Hyperliquid market for "${coin}": ${top.map((m) => m.coin).join(", ")}. Pass dex or full coin name (e.g. xyz:AAPL).`
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// src/protocols/evm/hyperliquid/assets.ts
|
|
601
|
+
async function hyperliquidResolvePerpAsset(args) {
|
|
602
|
+
const resolved = await hyperliquidResolvePerpMarket(args);
|
|
603
|
+
return { asset: resolved.asset, szDecimals: resolved.szDecimals, maxLeverage: resolved.maxLeverage };
|
|
604
|
+
}
|
|
605
|
+
async function hyperliquidResolveSpotAsset(args) {
|
|
606
|
+
const coin = args.coin.trim();
|
|
607
|
+
const { markets } = await hyperliquidFetchSpotMeta({ chainId: args.chainId });
|
|
608
|
+
const hit = markets.find((m) => m.name.toLowerCase() === coin.toLowerCase());
|
|
609
|
+
if (!hit) throw new Error(`Unknown Hyperliquid spot market: ${coin}`);
|
|
610
|
+
return { asset: hit.asset, szDecimals: hit.szDecimals };
|
|
611
|
+
}
|
|
612
|
+
async function hyperliquidResolveAsset(args) {
|
|
613
|
+
if (args.marketKind === "spot") {
|
|
614
|
+
const r = await hyperliquidResolveSpotAsset({ chainId: args.chainId, coin: args.coin });
|
|
615
|
+
return r;
|
|
616
|
+
}
|
|
617
|
+
return hyperliquidResolvePerpAsset({ chainId: args.chainId, coin: args.coin, dex: args.dex });
|
|
618
|
+
}
|
|
619
|
+
function hyperliquidIsSpotAssetId(asset) {
|
|
620
|
+
return asset >= HYPERLIQUID_SPOT_ASSET_OFFSET;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// src/protocols/evm/hyperliquid/reads.ts
|
|
624
|
+
function hyperliquidUsdAmountString(value) {
|
|
625
|
+
const n = Number.parseFloat(String(value ?? "0"));
|
|
626
|
+
if (!Number.isFinite(n) || n <= 0) return "0";
|
|
627
|
+
return n.toFixed(6).replace(/\.?0+$/, "") || "0";
|
|
628
|
+
}
|
|
629
|
+
function hyperliquidSpotUsdcAvailable(balances) {
|
|
630
|
+
const usdc = balances.find((b) => b.coin === "USDC");
|
|
631
|
+
if (!usdc) return "0";
|
|
632
|
+
const total = Number.parseFloat(String(usdc.total ?? "0"));
|
|
633
|
+
const hold = Number.parseFloat(String(usdc.hold ?? "0"));
|
|
634
|
+
if (!Number.isFinite(total)) return "0";
|
|
635
|
+
const avail = Math.max(0, total - (Number.isFinite(hold) ? hold : 0));
|
|
636
|
+
return hyperliquidUsdAmountString(String(avail));
|
|
637
|
+
}
|
|
638
|
+
async function hyperliquidFetchUsdClassBalances(args) {
|
|
639
|
+
const user = args.executorAddress.trim().toLowerCase();
|
|
640
|
+
const [{ state: spotState }, { state: perpState }] = await Promise.all([
|
|
641
|
+
hyperliquidFetchSpotClearinghouseState({ chainId: args.chainId, user }),
|
|
642
|
+
hyperliquidFetchClearinghouseState({ chainId: args.chainId, user })
|
|
643
|
+
]);
|
|
644
|
+
return {
|
|
645
|
+
balances: {
|
|
646
|
+
spotUsdcAvailable: hyperliquidSpotUsdcAvailable(spotState.balances ?? []),
|
|
647
|
+
perpWithdrawable: hyperliquidUsdAmountString(perpState.withdrawable)
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
function fmtLeverage(leverage) {
|
|
652
|
+
if (leverage?.value == null) return null;
|
|
653
|
+
const t = leverage.type === "isolated" ? "iso" : "cross";
|
|
654
|
+
return `${leverage.value}x ${t}`;
|
|
655
|
+
}
|
|
656
|
+
function mapPositionRow(p) {
|
|
657
|
+
if (!p.coin) return null;
|
|
658
|
+
const szi = Number.parseFloat(String(p.szi ?? "0"));
|
|
659
|
+
if (!Number.isFinite(szi) || szi === 0) return null;
|
|
660
|
+
return {
|
|
661
|
+
key: `${p.coin}:${szi > 0 ? "long" : "short"}`,
|
|
662
|
+
coin: p.coin,
|
|
663
|
+
isLong: szi > 0,
|
|
664
|
+
size: String(Math.abs(szi)),
|
|
665
|
+
entryPx: p.entryPx ?? null,
|
|
666
|
+
positionValueUsd: p.positionValue ?? null,
|
|
667
|
+
unrealizedPnlUsd: p.unrealizedPnl ?? null,
|
|
668
|
+
liquidationPx: p.liquidationPx ?? null,
|
|
669
|
+
leverageLabel: fmtLeverage(p.leverage),
|
|
670
|
+
maxLeverage: typeof p.maxLeverage === "number" && Number.isFinite(p.maxLeverage) ? p.maxLeverage : null,
|
|
671
|
+
marginUsedUsd: p.marginUsed ?? null,
|
|
672
|
+
returnOnEquity: p.returnOnEquity ?? null
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
async function hyperliquidFetchOpenMarketContext(args) {
|
|
676
|
+
const user = args.executorAddress.trim().toLowerCase();
|
|
677
|
+
const resolved = await hyperliquidResolvePerpMarket({
|
|
678
|
+
chainId: args.chainId,
|
|
679
|
+
coin: args.coin,
|
|
680
|
+
dex: args.dex
|
|
681
|
+
});
|
|
682
|
+
const coin = resolved.name;
|
|
683
|
+
const dex = args.dex?.trim() || resolved.dex;
|
|
684
|
+
const [{ activeAsset }, { state }] = await Promise.all([
|
|
685
|
+
hyperliquidFetchActiveAssetData({ chainId: args.chainId, user, coin }),
|
|
686
|
+
hyperliquidFetchClearinghouseState({ chainId: args.chainId, user, dex })
|
|
687
|
+
]);
|
|
688
|
+
return {
|
|
689
|
+
context: {
|
|
690
|
+
activeAsset,
|
|
691
|
+
account: {
|
|
692
|
+
accountValueUsd: state.marginSummary?.accountValue ?? null,
|
|
693
|
+
totalMarginUsedUsd: state.marginSummary?.totalMarginUsed ?? null,
|
|
694
|
+
withdrawableUsd: state.withdrawable ?? null
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
async function hyperliquidFetchPositionDisplayRows(args) {
|
|
700
|
+
const user = args.executorAddress.trim().toLowerCase();
|
|
701
|
+
const { state } = await hyperliquidFetchClearinghouseState({
|
|
702
|
+
chainId: args.chainId,
|
|
703
|
+
user,
|
|
704
|
+
dex: args.dex
|
|
705
|
+
});
|
|
706
|
+
const rows = [];
|
|
707
|
+
for (const ap of state.assetPositions ?? []) {
|
|
708
|
+
const row = mapPositionRow(ap.position ?? {});
|
|
709
|
+
if (row) rows.push(row);
|
|
710
|
+
}
|
|
711
|
+
return { rows };
|
|
712
|
+
}
|
|
713
|
+
async function hyperliquidFetchOrdersForExecutor(args) {
|
|
714
|
+
return hyperliquidFetchOpenOrders({
|
|
715
|
+
chainId: args.chainId,
|
|
716
|
+
user: args.executorAddress.trim().toLowerCase(),
|
|
717
|
+
dex: args.dex
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
async function hyperliquidFetchMarketsSummary(args) {
|
|
721
|
+
const { markets, dexes } = await hyperliquidCollectAllPerpMarkets({
|
|
722
|
+
chainId: args.chainId,
|
|
723
|
+
dex: args.dex?.trim()
|
|
724
|
+
});
|
|
725
|
+
return { markets, dexes };
|
|
726
|
+
}
|
|
727
|
+
async function hyperliquidSearchMarketsSummary(args) {
|
|
728
|
+
return hyperliquidSearchMarkets(args);
|
|
729
|
+
}
|
|
730
|
+
async function hyperliquidFetchPositionsForExecutor(args) {
|
|
731
|
+
const { rows } = await hyperliquidFetchPositionDisplayRows(args);
|
|
732
|
+
return { positions: rows };
|
|
733
|
+
}
|
|
734
|
+
async function hyperliquidFetchOpenOrdersSummary(args) {
|
|
735
|
+
const { orders } = await hyperliquidFetchOrdersForExecutor(args);
|
|
736
|
+
return { orders };
|
|
737
|
+
}
|
|
738
|
+
async function hyperliquidFetchOpenContextSummary(args) {
|
|
739
|
+
const { context } = await hyperliquidFetchOpenMarketContext(args);
|
|
740
|
+
return { context };
|
|
741
|
+
}
|
|
742
|
+
async function hyperliquidFetchUsdClassBalancesSummary(args) {
|
|
743
|
+
const { balances } = await hyperliquidFetchUsdClassBalances(args);
|
|
744
|
+
return { balances };
|
|
745
|
+
}
|
|
746
|
+
async function hyperliquidFetchVaultCatalogSummary(args) {
|
|
747
|
+
const { vaults } = await hyperliquidFetchVaultSummaries({
|
|
748
|
+
chainId: args.chainId,
|
|
749
|
+
executorAddress: args.executorAddress
|
|
750
|
+
});
|
|
751
|
+
return { vaults };
|
|
752
|
+
}
|
|
753
|
+
async function hyperliquidFetchUserVaultEquitiesSummary(args) {
|
|
754
|
+
const { rows } = await hyperliquidFetchUserVaultEquities({
|
|
755
|
+
chainId: args.chainId,
|
|
756
|
+
user: args.executorAddress.trim().toLowerCase()
|
|
757
|
+
});
|
|
758
|
+
return { rows };
|
|
759
|
+
}
|
|
760
|
+
async function hyperliquidFetchStakingSummaryForExecutor(args) {
|
|
761
|
+
const summary = await hyperliquidFetchStakingSummary({
|
|
762
|
+
chainId: args.chainId,
|
|
763
|
+
user: args.executorAddress.trim().toLowerCase()
|
|
764
|
+
});
|
|
765
|
+
return { summary };
|
|
766
|
+
}
|
|
767
|
+
async function hyperliquidFetchDelegationsForExecutor(args) {
|
|
768
|
+
const { delegations } = await hyperliquidFetchDelegations({
|
|
769
|
+
chainId: args.chainId,
|
|
770
|
+
user: args.executorAddress.trim().toLowerCase()
|
|
771
|
+
});
|
|
772
|
+
return { delegations };
|
|
773
|
+
}
|
|
774
|
+
async function hyperliquidFetchMarketSnapshotSummary(args) {
|
|
775
|
+
const resolved = await hyperliquidResolvePerpMarket({
|
|
776
|
+
chainId: args.chainId,
|
|
777
|
+
coin: args.coin,
|
|
778
|
+
dex: args.dex
|
|
779
|
+
});
|
|
780
|
+
const snapshot = await hyperliquidFetchMarketSnapshot({
|
|
781
|
+
chainId: args.chainId,
|
|
782
|
+
coin: resolved.name,
|
|
783
|
+
interval: args.interval,
|
|
784
|
+
dex: args.dex?.trim() || resolved.dex,
|
|
785
|
+
candleLimit: args.candleLimit
|
|
786
|
+
});
|
|
787
|
+
return { snapshot, resolvedCoin: resolved.name, dex: resolved.dex ?? null };
|
|
788
|
+
}
|
|
789
|
+
async function hyperliquidFetchOhlcvSummary(args) {
|
|
790
|
+
const resolved = await hyperliquidResolvePerpMarket({
|
|
791
|
+
chainId: args.chainId,
|
|
792
|
+
coin: args.coin,
|
|
793
|
+
dex: args.dex
|
|
794
|
+
});
|
|
795
|
+
const ohlcv = await hyperliquidFetchOhlcvRange({
|
|
796
|
+
chainId: args.chainId,
|
|
797
|
+
coin: resolved.name,
|
|
798
|
+
interval: args.interval,
|
|
799
|
+
dex: args.dex?.trim() || resolved.dex,
|
|
800
|
+
lookbackDays: args.lookbackDays,
|
|
801
|
+
lookbackHours: args.lookbackHours,
|
|
802
|
+
startTimeMs: args.startTimeMs,
|
|
803
|
+
endTimeMs: args.endTimeMs
|
|
804
|
+
});
|
|
805
|
+
return { ohlcv, resolvedCoin: resolved.name, dex: resolved.dex ?? null };
|
|
806
|
+
}
|
|
807
|
+
var coreWriterAbi = parseAbi(["function sendRawAction(bytes data) external"]);
|
|
808
|
+
var ACTION_LIMIT_ORDER = 1;
|
|
809
|
+
var ACTION_VAULT_TRANSFER = 2;
|
|
810
|
+
var ACTION_TOKEN_DELEGATE = 3;
|
|
811
|
+
var ACTION_STAKING_DEPOSIT = 4;
|
|
812
|
+
var ACTION_STAKING_WITHDRAW = 5;
|
|
813
|
+
var ACTION_USD_CLASS_TRANSFER = 7;
|
|
814
|
+
var ACTION_CANCEL_BY_OID = 10;
|
|
815
|
+
var ACTION_CANCEL_BY_CLOID = 11;
|
|
816
|
+
function encodeActionHeader(actionId) {
|
|
817
|
+
const idHex = actionId.toString(16).padStart(6, "0");
|
|
818
|
+
return `0x01${idHex}`;
|
|
819
|
+
}
|
|
820
|
+
function encodeCoreWriterCalldata(actionId, paramsEncoded) {
|
|
821
|
+
const header = encodeActionHeader(actionId).slice(2);
|
|
822
|
+
const params = paramsEncoded.startsWith("0x") ? paramsEncoded.slice(2) : paramsEncoded;
|
|
823
|
+
const actionBytes = `0x${header}${params}`;
|
|
824
|
+
return encodeFunctionData({
|
|
825
|
+
abi: coreWriterAbi,
|
|
826
|
+
functionName: "sendRawAction",
|
|
827
|
+
args: [actionBytes]
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
function hyperliquidEncodePx8(human) {
|
|
831
|
+
const n = typeof human === "number" ? human : Number.parseFloat(String(human).trim());
|
|
832
|
+
if (!Number.isFinite(n) || n < 0) throw new Error("Invalid price or size for Hyperliquid encoding.");
|
|
833
|
+
return BigInt(Math.round(n * 1e8));
|
|
834
|
+
}
|
|
835
|
+
function hyperliquidEncodeUsd6(human) {
|
|
836
|
+
const n = typeof human === "number" ? human : Number.parseFloat(String(human).trim());
|
|
837
|
+
if (!Number.isFinite(n) || n < 0) throw new Error("Invalid USD amount for Hyperliquid encoding.");
|
|
838
|
+
return BigInt(Math.round(n * 1e6));
|
|
839
|
+
}
|
|
840
|
+
function hyperliquidEncodeWei8(human) {
|
|
841
|
+
return hyperliquidEncodePx8(human);
|
|
842
|
+
}
|
|
843
|
+
function hyperliquidResolveTif(tif) {
|
|
844
|
+
const key = String(tif).trim().toLowerCase();
|
|
845
|
+
const v = HYPERLIQUID_TIF[key];
|
|
846
|
+
if (v == null) throw new Error(`Unknown time-in-force: ${tif}. Use alo, gtc, or ioc.`);
|
|
847
|
+
return v;
|
|
848
|
+
}
|
|
849
|
+
function buildCoreWriterLimitOrderCalldata(args) {
|
|
850
|
+
const params = encodeAbiParameters(
|
|
851
|
+
[
|
|
852
|
+
{ type: "uint32" },
|
|
853
|
+
{ type: "bool" },
|
|
854
|
+
{ type: "uint64" },
|
|
855
|
+
{ type: "uint64" },
|
|
856
|
+
{ type: "bool" },
|
|
857
|
+
{ type: "uint8" },
|
|
858
|
+
{ type: "uint128" }
|
|
859
|
+
],
|
|
860
|
+
[
|
|
861
|
+
args.asset,
|
|
862
|
+
args.isBuy,
|
|
863
|
+
hyperliquidEncodePx8(args.limitPxHuman),
|
|
864
|
+
hyperliquidEncodePx8(args.szHuman),
|
|
865
|
+
Boolean(args.reduceOnly),
|
|
866
|
+
hyperliquidResolveTif(args.tif ?? "gtc"),
|
|
867
|
+
args.cloid ?? 0n
|
|
868
|
+
]
|
|
869
|
+
);
|
|
870
|
+
return encodeCoreWriterCalldata(ACTION_LIMIT_ORDER, params);
|
|
871
|
+
}
|
|
872
|
+
function buildCoreWriterCancelByOidCalldata(args) {
|
|
873
|
+
const params = encodeAbiParameters(
|
|
874
|
+
[{ type: "uint32" }, { type: "uint64" }],
|
|
875
|
+
[args.asset, BigInt(args.oid)]
|
|
876
|
+
);
|
|
877
|
+
return encodeCoreWriterCalldata(ACTION_CANCEL_BY_OID, params);
|
|
878
|
+
}
|
|
879
|
+
function buildCoreWriterCancelByCloidCalldata(args) {
|
|
880
|
+
const params = encodeAbiParameters(
|
|
881
|
+
[{ type: "uint32" }, { type: "uint128" }],
|
|
882
|
+
[args.asset, args.cloid]
|
|
883
|
+
);
|
|
884
|
+
return encodeCoreWriterCalldata(ACTION_CANCEL_BY_CLOID, params);
|
|
885
|
+
}
|
|
886
|
+
function buildCoreWriterUsdClassTransferCalldata(args) {
|
|
887
|
+
const params = encodeAbiParameters(
|
|
888
|
+
[{ type: "uint64" }, { type: "bool" }],
|
|
889
|
+
[hyperliquidEncodeUsd6(args.usdHuman), args.toPerp]
|
|
890
|
+
);
|
|
891
|
+
return encodeCoreWriterCalldata(ACTION_USD_CLASS_TRANSFER, params);
|
|
892
|
+
}
|
|
893
|
+
function buildCoreWriterVaultTransferCalldata(args) {
|
|
894
|
+
const params = encodeAbiParameters(
|
|
895
|
+
[{ type: "address" }, { type: "bool" }, { type: "uint64" }],
|
|
896
|
+
[args.vault, args.isDeposit, hyperliquidEncodeUsd6(args.usdHuman)]
|
|
897
|
+
);
|
|
898
|
+
return encodeCoreWriterCalldata(ACTION_VAULT_TRANSFER, params);
|
|
899
|
+
}
|
|
900
|
+
function buildCoreWriterStakingDepositCalldata(args) {
|
|
901
|
+
const params = encodeAbiParameters([{ type: "uint64" }], [hyperliquidEncodeWei8(args.hypeHuman)]);
|
|
902
|
+
return encodeCoreWriterCalldata(ACTION_STAKING_DEPOSIT, params);
|
|
903
|
+
}
|
|
904
|
+
function buildCoreWriterStakingWithdrawCalldata(args) {
|
|
905
|
+
const params = encodeAbiParameters([{ type: "uint64" }], [hyperliquidEncodeWei8(args.hypeHuman)]);
|
|
906
|
+
return encodeCoreWriterCalldata(ACTION_STAKING_WITHDRAW, params);
|
|
907
|
+
}
|
|
908
|
+
function buildCoreWriterTokenDelegateCalldata(args) {
|
|
909
|
+
const params = encodeAbiParameters(
|
|
910
|
+
[{ type: "address" }, { type: "uint64" }, { type: "bool" }],
|
|
911
|
+
[args.validator, hyperliquidEncodeWei8(args.hypeHuman), args.isUndelegate]
|
|
912
|
+
);
|
|
913
|
+
return encodeCoreWriterCalldata(ACTION_TOKEN_DELEGATE, params);
|
|
914
|
+
}
|
|
915
|
+
function coreWriterStep(data) {
|
|
916
|
+
return {
|
|
917
|
+
to: HYPERLIQUID_CORE_WRITER_ADDRESS,
|
|
918
|
+
data,
|
|
919
|
+
value: 0n
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// src/core/purpose.ts
|
|
924
|
+
function mergePurposeText(purposeText, purposeSuffix) {
|
|
925
|
+
const t = purposeText.trim();
|
|
926
|
+
const suffix = (purposeSuffix ?? "").trim();
|
|
927
|
+
if (!suffix) return t;
|
|
928
|
+
return t ? `${t}
|
|
929
|
+
|
|
930
|
+
${suffix}` : suffix;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
// src/core/envelope.ts
|
|
934
|
+
function finalizeMultisign(input) {
|
|
935
|
+
const { keyGen, destinationChainID, legs } = input;
|
|
936
|
+
if (legs.length === 0) {
|
|
937
|
+
throw new Error("finalizeMultisign requires at least one leg");
|
|
938
|
+
}
|
|
939
|
+
const ph = (keyGen.pubkeyhex ?? "").trim();
|
|
940
|
+
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
941
|
+
const keyList = keyGen.keylist ?? [];
|
|
942
|
+
const clientId = getClientIdFromKeyGenResult(keyGen);
|
|
943
|
+
const first = legs[0];
|
|
944
|
+
const messageHashes = legs.map((l) => l.msgHash);
|
|
945
|
+
const messageRawBatch = legs.map((l) => l.msgRaw);
|
|
946
|
+
const batchMeta = legs.map((l) => ({
|
|
947
|
+
destinationAddress: l.destinationAddress,
|
|
948
|
+
signatureText: l.signatureText,
|
|
949
|
+
...l.audit
|
|
950
|
+
}));
|
|
951
|
+
const proposalTxParams = legs.map((l) => l.proposalTxParams).filter((p) => p != null && typeof p === "object");
|
|
952
|
+
const extraPayload = {
|
|
953
|
+
batchMeta,
|
|
954
|
+
...input.extraJSON ?? {}
|
|
955
|
+
};
|
|
956
|
+
const extraJSON = JSON.stringify(extraPayload);
|
|
957
|
+
const bodyForSign = {
|
|
958
|
+
keyList,
|
|
959
|
+
pubKey: ph,
|
|
960
|
+
msgHash: messageHashes[0],
|
|
961
|
+
msgRaw: first.msgRaw,
|
|
962
|
+
destinationChainID,
|
|
963
|
+
destinationAddress: input.destinationAddress ?? first.destinationAddress,
|
|
964
|
+
extraJSON,
|
|
965
|
+
signatureText: first.signatureText,
|
|
966
|
+
purpose: mergePurposeText(input.purposeText, input.purposeSuffix),
|
|
967
|
+
...first.feeSnapshot
|
|
968
|
+
};
|
|
969
|
+
if (legs.length > 1) {
|
|
970
|
+
bodyForSign.messageHashes = messageHashes;
|
|
971
|
+
bodyForSign.messageRawBatch = messageRawBatch;
|
|
972
|
+
}
|
|
973
|
+
if (proposalTxParams.length > 0) {
|
|
974
|
+
bodyForSign.proposalTxParams = proposalTxParams;
|
|
975
|
+
}
|
|
976
|
+
const valueWei = first.valueWei;
|
|
977
|
+
if (valueWei != null && valueWei > 0n) {
|
|
978
|
+
bodyForSign.value = valueWei.toString();
|
|
979
|
+
}
|
|
980
|
+
if (clientId) bodyForSign.clientId = clientId;
|
|
981
|
+
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
982
|
+
}
|
|
983
|
+
function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
|
|
984
|
+
if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {
|
|
985
|
+
return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit);
|
|
986
|
+
}
|
|
987
|
+
return (estimatedGas * 12n + 9n) / 10n;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// src/chains/evm/buildBatch.ts
|
|
991
|
+
async function buildEvmMultisignBatch(args) {
|
|
992
|
+
const { context, steps } = args;
|
|
993
|
+
const {
|
|
994
|
+
chainId,
|
|
995
|
+
rpcUrl,
|
|
996
|
+
executorAddress,
|
|
997
|
+
chainDetail,
|
|
998
|
+
useCustomGas,
|
|
999
|
+
customGasChainDetails,
|
|
1000
|
+
keyGen,
|
|
1001
|
+
purposeText
|
|
1002
|
+
} = context;
|
|
1003
|
+
if (steps.length === 0) throw new Error("buildEvmMultisignBatch requires at least one step");
|
|
1004
|
+
const ch = defineChain({
|
|
1005
|
+
id: chainId,
|
|
1006
|
+
name: "Destination",
|
|
1007
|
+
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
1008
|
+
rpcUrls: { default: { http: [rpcUrl] } }
|
|
1009
|
+
});
|
|
1010
|
+
const publicClient = createPublicClient({ chain: ch, transport: http(rpcUrl) });
|
|
1011
|
+
const feeParams = await fetchChainFeeParams(rpcUrl, chainId);
|
|
1012
|
+
const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559;
|
|
1013
|
+
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
1014
|
+
const gasLimitConfig = useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : void 0;
|
|
1015
|
+
const chainGasLimitRouter = chainDetail?.gasLimit != null && Number.isFinite(Number(chainDetail.gasLimit)) && Number(chainDetail.gasLimit) > 0 ? Number(chainDetail.gasLimit) : void 0;
|
|
1016
|
+
const gasFeeMultiplier = useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : void 0;
|
|
1017
|
+
const executor = getAddress(executorAddress);
|
|
1018
|
+
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
1019
|
+
const legs = [];
|
|
1020
|
+
for (let i = 0; i < steps.length; i++) {
|
|
1021
|
+
const step = steps[i];
|
|
1022
|
+
const currentNonce = baseNonce + i;
|
|
1023
|
+
let estimatedGas;
|
|
1024
|
+
if (args.estimateGasForStep) {
|
|
1025
|
+
estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor });
|
|
1026
|
+
} else {
|
|
1027
|
+
try {
|
|
1028
|
+
estimatedGas = await publicClient.estimateGas({
|
|
1029
|
+
to: step.to,
|
|
1030
|
+
data: step.data,
|
|
1031
|
+
value: step.value,
|
|
1032
|
+
account: executor
|
|
1033
|
+
});
|
|
1034
|
+
} catch {
|
|
1035
|
+
estimatedGas = step.fallbackGas ?? 100000n;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
let gasLimitI;
|
|
1039
|
+
if (args.resolveGasLimit) {
|
|
1040
|
+
gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient });
|
|
1041
|
+
} else if (step.routerSwap) {
|
|
1042
|
+
gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter);
|
|
1043
|
+
} else {
|
|
1044
|
+
gasLimitI = useCustomGas ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
1045
|
+
}
|
|
1046
|
+
let proposalTxParams;
|
|
1047
|
+
let feeSnapshot;
|
|
1048
|
+
let serialized;
|
|
1049
|
+
if (legacy) {
|
|
1050
|
+
let gasPriceWei = await publicClient.getGasPrice();
|
|
1051
|
+
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1052
|
+
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1053
|
+
}
|
|
1054
|
+
if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {
|
|
1055
|
+
const configured = parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)));
|
|
1056
|
+
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
1057
|
+
}
|
|
1058
|
+
serialized = serializeTransaction({
|
|
1059
|
+
type: "legacy",
|
|
1060
|
+
to: step.to,
|
|
1061
|
+
data: step.data,
|
|
1062
|
+
value: step.value,
|
|
1063
|
+
gas: gasLimitI,
|
|
1064
|
+
gasPrice: gasPriceWei,
|
|
1065
|
+
nonce: currentNonce,
|
|
1066
|
+
chainId
|
|
1067
|
+
});
|
|
1068
|
+
proposalTxParams = {
|
|
1069
|
+
nonce: currentNonce,
|
|
1070
|
+
gasLimit: gasLimitI.toString(),
|
|
1071
|
+
txType: "legacy",
|
|
1072
|
+
gasPrice: gasPriceWei.toString()
|
|
1073
|
+
};
|
|
1074
|
+
feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams);
|
|
1075
|
+
} else {
|
|
1076
|
+
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
1077
|
+
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
1078
|
+
const configuredBase = useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0;
|
|
1079
|
+
const configuredPriority = useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0;
|
|
1080
|
+
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
1081
|
+
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
1082
|
+
const baseFeeMultiplierPct = useCustomGas && chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(chainDetail.baseFeeMultiplier)) : 100;
|
|
1083
|
+
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
1084
|
+
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
1085
|
+
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? parseGwei(gweiToDecimalString(effectivePriorityFeeGwei)) : parseGwei("1");
|
|
1086
|
+
let maxFeePerGas = parseGwei(gweiToDecimalString(maxFeePerGasGwei));
|
|
1087
|
+
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1088
|
+
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1089
|
+
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1090
|
+
}
|
|
1091
|
+
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
1092
|
+
maxFeePerGas,
|
|
1093
|
+
maxPriorityFeePerGas,
|
|
1094
|
+
latestBaseFeeWei
|
|
1095
|
+
));
|
|
1096
|
+
serialized = serializeTransaction({
|
|
1097
|
+
type: "eip1559",
|
|
1098
|
+
to: step.to,
|
|
1099
|
+
data: step.data,
|
|
1100
|
+
value: step.value,
|
|
1101
|
+
gas: gasLimitI,
|
|
1102
|
+
maxFeePerGas,
|
|
1103
|
+
maxPriorityFeePerGas,
|
|
1104
|
+
nonce: currentNonce,
|
|
1105
|
+
chainId
|
|
1106
|
+
});
|
|
1107
|
+
proposalTxParams = {
|
|
1108
|
+
nonce: currentNonce,
|
|
1109
|
+
gasLimit: gasLimitI.toString(),
|
|
1110
|
+
txType: "eip1559",
|
|
1111
|
+
maxFeePerGas: maxFeePerGas.toString(),
|
|
1112
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1113
|
+
};
|
|
1114
|
+
feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {};
|
|
1115
|
+
}
|
|
1116
|
+
const h = keccak256(serialized);
|
|
1117
|
+
const msgHash = h.startsWith("0x") ? h.slice(2) : h;
|
|
1118
|
+
const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI });
|
|
1119
|
+
legs.push({
|
|
1120
|
+
msgHash,
|
|
1121
|
+
msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,
|
|
1122
|
+
destinationAddress: step.to,
|
|
1123
|
+
signatureText: typeof batchMetaExtra.signatureText === "string" ? batchMetaExtra.signatureText : JSON.stringify(batchMetaExtra.signatureText ?? {}),
|
|
1124
|
+
audit: batchMetaExtra,
|
|
1125
|
+
feeSnapshot: i === 0 ? feeSnapshot : {},
|
|
1126
|
+
proposalTxParams,
|
|
1127
|
+
valueWei: i === 0 ? step.value : void 0
|
|
1128
|
+
});
|
|
1129
|
+
if (i === 0 && args.firstMsgRawNo0x != null) {
|
|
1130
|
+
legs[0].msgRaw = args.firstMsgRawNo0x;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
const extraJSON = {};
|
|
1134
|
+
if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {
|
|
1135
|
+
extraJSON.customGasChainDetails = customGasChainDetails;
|
|
1136
|
+
}
|
|
1137
|
+
const result = finalizeMultisign({
|
|
1138
|
+
keyGen,
|
|
1139
|
+
purposeText,
|
|
1140
|
+
purposeSuffix: args.purposeSuffix,
|
|
1141
|
+
destinationChainID: String(chainId),
|
|
1142
|
+
destinationAddress: args.destinationAddress ?? steps[0].to,
|
|
1143
|
+
legs,
|
|
1144
|
+
extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
|
|
1145
|
+
});
|
|
1146
|
+
const pv = args.payableValueWei;
|
|
1147
|
+
if (pv != null && pv > 0n) {
|
|
1148
|
+
result.bodyForSign.value = pv.toString();
|
|
1149
|
+
}
|
|
1150
|
+
return result;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
// src/protocols/evm/hyperliquid/multisign.ts
|
|
1154
|
+
async function buildCoreWriterMultisign(common, data, signatureMeta) {
|
|
1155
|
+
const step = coreWriterStep(data);
|
|
1156
|
+
return buildEvmMultisignBatch({
|
|
1157
|
+
context: {
|
|
1158
|
+
keyGen: common.keyGen,
|
|
1159
|
+
chainCategory: "evm",
|
|
1160
|
+
chainId: common.chainId,
|
|
1161
|
+
rpcUrl: common.rpcUrl,
|
|
1162
|
+
chainDetail: common.chainDetail,
|
|
1163
|
+
useCustomGas: common.useCustomGas,
|
|
1164
|
+
customGasChainDetails: common.customGasChainDetails ?? null,
|
|
1165
|
+
executorAddress: getAddress(common.executorAddress),
|
|
1166
|
+
purposeText: common.purposeText
|
|
1167
|
+
},
|
|
1168
|
+
steps: [{ ...step, fallbackGas: HYPERLIQUID_CORE_WRITER_GAS_FALLBACK }],
|
|
1169
|
+
destinationAddress: step.to,
|
|
1170
|
+
buildBatchMeta: () => ({
|
|
1171
|
+
kind: "Hyperliquid",
|
|
1172
|
+
...signatureMeta,
|
|
1173
|
+
evm: { type: "hyperliquid_core_writer", version: 1, chainId: String(common.chainId) }
|
|
1174
|
+
})
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
async function buildEvmMultisignBodyHyperliquidLimitOrderBatch(args) {
|
|
1178
|
+
const marketKind = args.marketKind ?? "perp";
|
|
1179
|
+
const { asset } = await hyperliquidResolveAsset({
|
|
1180
|
+
chainId: args.chainId,
|
|
1181
|
+
coin: args.coin,
|
|
1182
|
+
marketKind,
|
|
1183
|
+
dex: args.dex
|
|
1184
|
+
});
|
|
1185
|
+
const data = buildCoreWriterLimitOrderCalldata({
|
|
1186
|
+
asset,
|
|
1187
|
+
isBuy: args.isBuy,
|
|
1188
|
+
limitPxHuman: args.limitPxHuman,
|
|
1189
|
+
szHuman: args.szHuman,
|
|
1190
|
+
reduceOnly: args.reduceOnly,
|
|
1191
|
+
tif: args.tif
|
|
1192
|
+
});
|
|
1193
|
+
return buildCoreWriterMultisign(args, data, {
|
|
1194
|
+
action: "limitOrder",
|
|
1195
|
+
coin: args.coin,
|
|
1196
|
+
marketKind,
|
|
1197
|
+
isBuy: args.isBuy,
|
|
1198
|
+
limitPxHuman: args.limitPxHuman,
|
|
1199
|
+
szHuman: args.szHuman,
|
|
1200
|
+
reduceOnly: Boolean(args.reduceOnly),
|
|
1201
|
+
tif: args.tif ?? "gtc",
|
|
1202
|
+
asset
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
async function buildEvmMultisignBodyHyperliquidCloseBatch(args) {
|
|
1206
|
+
return buildEvmMultisignBodyHyperliquidLimitOrderBatch({
|
|
1207
|
+
...args,
|
|
1208
|
+
marketKind: "perp",
|
|
1209
|
+
isBuy: !args.isLong,
|
|
1210
|
+
reduceOnly: true,
|
|
1211
|
+
tif: args.tif ?? "ioc"
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
async function buildEvmMultisignBodyHyperliquidCancelBatch(args) {
|
|
1215
|
+
const marketKind = args.marketKind ?? "perp";
|
|
1216
|
+
const { asset } = await hyperliquidResolveAsset({
|
|
1217
|
+
chainId: args.chainId,
|
|
1218
|
+
coin: args.coin,
|
|
1219
|
+
marketKind,
|
|
1220
|
+
dex: args.dex
|
|
1221
|
+
});
|
|
1222
|
+
const data = buildCoreWriterCancelByOidCalldata({ asset, oid: args.oid });
|
|
1223
|
+
return buildCoreWriterMultisign(args, data, {
|
|
1224
|
+
action: "cancelOrder",
|
|
1225
|
+
coin: args.coin,
|
|
1226
|
+
marketKind,
|
|
1227
|
+
oid: args.oid,
|
|
1228
|
+
asset
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
async function buildEvmMultisignBodyHyperliquidUsdClassTransferBatch(args) {
|
|
1232
|
+
const data = buildCoreWriterUsdClassTransferCalldata({
|
|
1233
|
+
usdHuman: args.usdHuman,
|
|
1234
|
+
toPerp: args.toPerp
|
|
1235
|
+
});
|
|
1236
|
+
return buildCoreWriterMultisign(args, data, {
|
|
1237
|
+
action: "usdClassTransfer",
|
|
1238
|
+
usdHuman: args.usdHuman,
|
|
1239
|
+
toPerp: args.toPerp
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
1242
|
+
async function buildVaultMultisign(common, isDeposit) {
|
|
1243
|
+
const vault = getAddress(common.vaultAddress);
|
|
1244
|
+
const data = buildCoreWriterVaultTransferCalldata({
|
|
1245
|
+
vault,
|
|
1246
|
+
isDeposit,
|
|
1247
|
+
usdHuman: common.usdHuman
|
|
1248
|
+
});
|
|
1249
|
+
const step = coreWriterStep(data);
|
|
1250
|
+
return buildEvmMultisignBatch({
|
|
1251
|
+
context: {
|
|
1252
|
+
keyGen: common.keyGen,
|
|
1253
|
+
chainCategory: "evm",
|
|
1254
|
+
chainId: common.chainId,
|
|
1255
|
+
rpcUrl: common.rpcUrl,
|
|
1256
|
+
chainDetail: common.chainDetail,
|
|
1257
|
+
useCustomGas: common.useCustomGas,
|
|
1258
|
+
customGasChainDetails: common.customGasChainDetails ?? null,
|
|
1259
|
+
executorAddress: getAddress(common.executorAddress),
|
|
1260
|
+
purposeText: common.purposeText
|
|
1261
|
+
},
|
|
1262
|
+
steps: [{ ...step, fallbackGas: HYPERLIQUID_CORE_WRITER_GAS_FALLBACK }],
|
|
1263
|
+
destinationAddress: step.to,
|
|
1264
|
+
buildBatchMeta: () => ({
|
|
1265
|
+
kind: "Hyperliquid",
|
|
1266
|
+
action: isDeposit ? "vaultDeposit" : "vaultWithdraw",
|
|
1267
|
+
vault,
|
|
1268
|
+
usdHuman: common.usdHuman,
|
|
1269
|
+
evm: { type: "hyperliquid_vault", version: 1, chainId: String(common.chainId) }
|
|
1270
|
+
})
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
async function buildEvmMultisignBodyHyperliquidVaultDepositBatch(args) {
|
|
1274
|
+
return buildVaultMultisign(args, true);
|
|
1275
|
+
}
|
|
1276
|
+
async function buildEvmMultisignBodyHyperliquidVaultWithdrawBatch(args) {
|
|
1277
|
+
return buildVaultMultisign(args, false);
|
|
1278
|
+
}
|
|
1279
|
+
async function buildStakingMultisign(common, data, action, extra = {}) {
|
|
1280
|
+
const step = coreWriterStep(data);
|
|
1281
|
+
return buildEvmMultisignBatch({
|
|
1282
|
+
context: {
|
|
1283
|
+
keyGen: common.keyGen,
|
|
1284
|
+
chainCategory: "evm",
|
|
1285
|
+
chainId: common.chainId,
|
|
1286
|
+
rpcUrl: common.rpcUrl,
|
|
1287
|
+
chainDetail: common.chainDetail,
|
|
1288
|
+
useCustomGas: common.useCustomGas,
|
|
1289
|
+
customGasChainDetails: common.customGasChainDetails ?? null,
|
|
1290
|
+
executorAddress: getAddress(common.executorAddress),
|
|
1291
|
+
purposeText: common.purposeText
|
|
1292
|
+
},
|
|
1293
|
+
steps: [{ ...step, fallbackGas: HYPERLIQUID_CORE_WRITER_GAS_FALLBACK }],
|
|
1294
|
+
destinationAddress: step.to,
|
|
1295
|
+
buildBatchMeta: () => ({
|
|
1296
|
+
kind: "Hyperliquid",
|
|
1297
|
+
action,
|
|
1298
|
+
hypeHuman: common.hypeHuman,
|
|
1299
|
+
...extra,
|
|
1300
|
+
evm: { type: "hyperliquid_staking", version: 1, chainId: String(common.chainId) }
|
|
1301
|
+
})
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
async function buildEvmMultisignBodyHyperliquidStakeDepositBatch(args) {
|
|
1305
|
+
const data = buildCoreWriterStakingDepositCalldata({ hypeHuman: args.hypeHuman });
|
|
1306
|
+
return buildStakingMultisign(args, data, "stakingDeposit");
|
|
1307
|
+
}
|
|
1308
|
+
async function buildEvmMultisignBodyHyperliquidStakeWithdrawBatch(args) {
|
|
1309
|
+
const data = buildCoreWriterStakingWithdrawCalldata({ hypeHuman: args.hypeHuman });
|
|
1310
|
+
return buildStakingMultisign(args, data, "stakingWithdraw");
|
|
1311
|
+
}
|
|
1312
|
+
async function buildEvmMultisignBodyHyperliquidDelegateBatch(args) {
|
|
1313
|
+
const validator = getAddress(args.validator);
|
|
1314
|
+
const data = buildCoreWriterTokenDelegateCalldata({
|
|
1315
|
+
validator,
|
|
1316
|
+
hypeHuman: args.hypeHuman,
|
|
1317
|
+
isUndelegate: args.isUndelegate
|
|
1318
|
+
});
|
|
1319
|
+
return buildStakingMultisign(args, data, args.isUndelegate ? "undelegate" : "delegate", { validator });
|
|
1320
|
+
}
|
|
1321
|
+
async function buildEvmMultisignBodyHyperliquidDelegateOnlyBatch(args) {
|
|
1322
|
+
return buildEvmMultisignBodyHyperliquidDelegateBatch({ ...args, isUndelegate: false });
|
|
1323
|
+
}
|
|
1324
|
+
async function buildEvmMultisignBodyHyperliquidUndelegateBatch(args) {
|
|
1325
|
+
return buildEvmMultisignBodyHyperliquidDelegateBatch({ ...args, isUndelegate: true });
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
// src/protocols/evm/hyperliquid/index.ts
|
|
1329
|
+
var HYPERLIQUID_PROTOCOL_ID = "hyperliquid";
|
|
1330
|
+
var hyperliquidProtocolModule = {
|
|
1331
|
+
id: HYPERLIQUID_PROTOCOL_ID,
|
|
1332
|
+
chainCategory: "evm",
|
|
1333
|
+
isChainSupported(ctx) {
|
|
1334
|
+
if (ctx.chainCategory !== "evm") return false;
|
|
1335
|
+
const chainId = typeof ctx.chainId === "number" ? ctx.chainId : Number(ctx.chainId);
|
|
1336
|
+
return Number.isFinite(chainId) && isHyperliquidChainSupported(chainId);
|
|
1337
|
+
},
|
|
1338
|
+
isTokenSupported(token) {
|
|
1339
|
+
if (token.category !== "evm") return false;
|
|
1340
|
+
return token.kind === "erc20" || token.kind === "native";
|
|
1341
|
+
},
|
|
1342
|
+
actions: [
|
|
1343
|
+
{
|
|
1344
|
+
id: "hyperliquid.limitOrder",
|
|
1345
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1346
|
+
chainCategory: "evm",
|
|
1347
|
+
description: "Place a Hyperliquid limit/IoC order via HyperEVM CoreWriter",
|
|
1348
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1349
|
+
params: {
|
|
1350
|
+
coin: { type: "string", required: true, description: "Market coin e.g. BTC" },
|
|
1351
|
+
isBuy: { type: "boolean", required: true, description: "true for buy/long, false for sell/short" },
|
|
1352
|
+
limitPxHuman: { type: "string", required: true, description: "Limit price" },
|
|
1353
|
+
szHuman: { type: "string", required: true, description: "Order size in coin units" },
|
|
1354
|
+
marketKind: { type: "string", required: false, description: "perp (default) or spot" },
|
|
1355
|
+
tif: { type: "string", required: false, description: "gtc, ioc, or alo" },
|
|
1356
|
+
dex: { type: "string", required: false, description: "HIP-3 dex name when applicable" }
|
|
1357
|
+
}
|
|
1358
|
+
},
|
|
1359
|
+
{
|
|
1360
|
+
id: "hyperliquid.close",
|
|
1361
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1362
|
+
chainCategory: "evm",
|
|
1363
|
+
description: "Close or reduce a perp via IoC reduce-only limit order (CoreWriter)",
|
|
1364
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1365
|
+
params: {
|
|
1366
|
+
coin: { type: "string", required: true, description: "Market coin" },
|
|
1367
|
+
isLong: { type: "boolean", required: true, description: "true if closing a long position" },
|
|
1368
|
+
limitPxHuman: { type: "string", required: true, description: "Limit price" },
|
|
1369
|
+
szHuman: { type: "string", required: true, description: "Size to close in coin units" }
|
|
1370
|
+
}
|
|
1371
|
+
},
|
|
1372
|
+
{
|
|
1373
|
+
id: "hyperliquid.cancel",
|
|
1374
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1375
|
+
chainCategory: "evm",
|
|
1376
|
+
description: "Cancel a Hyperliquid open order via CoreWriter",
|
|
1377
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1378
|
+
params: {
|
|
1379
|
+
coin: { type: "string", required: true, description: "Market coin" },
|
|
1380
|
+
oid: { type: "number", required: true, description: "Order id from openOrders" }
|
|
1381
|
+
}
|
|
1382
|
+
},
|
|
1383
|
+
{
|
|
1384
|
+
id: "hyperliquid.usdTransfer",
|
|
1385
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1386
|
+
chainCategory: "evm",
|
|
1387
|
+
description: "Move USDC between Hyperliquid spot and perp margin accounts",
|
|
1388
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1389
|
+
params: {
|
|
1390
|
+
usdHuman: { type: "string", required: true, description: "USD amount" },
|
|
1391
|
+
toPerp: { type: "boolean", required: true, description: "true spot\u2192perp, false perp\u2192spot" }
|
|
1392
|
+
}
|
|
1393
|
+
},
|
|
1394
|
+
{
|
|
1395
|
+
id: "hyperliquid.vaultDeposit",
|
|
1396
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1397
|
+
chainCategory: "evm",
|
|
1398
|
+
description: "Deposit USD into a Hyperliquid vault",
|
|
1399
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1400
|
+
params: {
|
|
1401
|
+
vaultAddress: { type: "string", required: true, description: "Vault address" },
|
|
1402
|
+
usdHuman: { type: "string", required: true, description: "USD amount" }
|
|
1403
|
+
}
|
|
1404
|
+
},
|
|
1405
|
+
{
|
|
1406
|
+
id: "hyperliquid.vaultWithdraw",
|
|
1407
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1408
|
+
chainCategory: "evm",
|
|
1409
|
+
description: "Withdraw USD from a Hyperliquid vault (includes accrued PnL)",
|
|
1410
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1411
|
+
params: {
|
|
1412
|
+
vaultAddress: { type: "string", required: true, description: "Vault address" },
|
|
1413
|
+
usdHuman: { type: "string", required: true, description: "USD amount" }
|
|
1414
|
+
}
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
id: "hyperliquid.stake",
|
|
1418
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1419
|
+
chainCategory: "evm",
|
|
1420
|
+
description: "Stake HYPE via CoreWriter",
|
|
1421
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1422
|
+
params: {
|
|
1423
|
+
hypeHuman: { type: "string", required: true, description: "HYPE amount" }
|
|
1424
|
+
}
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
id: "hyperliquid.unstake",
|
|
1428
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1429
|
+
chainCategory: "evm",
|
|
1430
|
+
description: "Unstake HYPE via CoreWriter",
|
|
1431
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1432
|
+
params: {
|
|
1433
|
+
hypeHuman: { type: "string", required: true, description: "HYPE amount" }
|
|
1434
|
+
}
|
|
1435
|
+
},
|
|
1436
|
+
{
|
|
1437
|
+
id: "hyperliquid.delegate",
|
|
1438
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1439
|
+
chainCategory: "evm",
|
|
1440
|
+
description: "Delegate staked HYPE to a validator",
|
|
1441
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1442
|
+
params: {
|
|
1443
|
+
hypeHuman: { type: "string", required: true, description: "HYPE amount" },
|
|
1444
|
+
validator: { type: "string", required: true, description: "Validator address" }
|
|
1445
|
+
}
|
|
1446
|
+
},
|
|
1447
|
+
{
|
|
1448
|
+
id: "hyperliquid.undelegate",
|
|
1449
|
+
protocolId: HYPERLIQUID_PROTOCOL_ID,
|
|
1450
|
+
chainCategory: "evm",
|
|
1451
|
+
description: "Undelegate HYPE from a validator",
|
|
1452
|
+
commonParams: ["keyGen", "purposeText", "useCustomGas"],
|
|
1453
|
+
params: {
|
|
1454
|
+
hypeHuman: { type: "string", required: true, description: "HYPE amount" },
|
|
1455
|
+
validator: { type: "string", required: true, description: "Validator address" }
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
]
|
|
1459
|
+
};
|
|
1460
|
+
registerProtocolModule(hyperliquidProtocolModule);
|
|
1461
|
+
|
|
1462
|
+
export { HYPERLIQUID_CORE_WRITER_ADDRESS, HYPERLIQUID_CORE_WRITER_GAS_FALLBACK, HYPERLIQUID_DEFAULT_CANDLE_LIMIT, HYPERLIQUID_DEFAULT_LOOKBACK_DAYS, HYPERLIQUID_DEFAULT_OHLCV_INTERVAL, HYPERLIQUID_HLP_VAULT_ADDRESS, HYPERLIQUID_INTERVAL_MS, HYPERLIQUID_MAX_CANDLE_LIMIT, HYPERLIQUID_MAX_LOOKBACK_DAYS, HYPERLIQUID_MAX_OHLCV_BARS, HYPERLIQUID_PROTOCOL_ID, HYPERLIQUID_SPOT_ASSET_OFFSET, HYPERLIQUID_SUPPORTED_CHAIN_IDS, HYPERLIQUID_TIF, buildCoreWriterCancelByCloidCalldata, buildCoreWriterCancelByOidCalldata, buildCoreWriterLimitOrderCalldata, buildCoreWriterStakingDepositCalldata, buildCoreWriterStakingWithdrawCalldata, buildCoreWriterTokenDelegateCalldata, buildCoreWriterUsdClassTransferCalldata, buildCoreWriterVaultTransferCalldata, buildEvmMultisignBodyHyperliquidCancelBatch, buildEvmMultisignBodyHyperliquidCloseBatch, buildEvmMultisignBodyHyperliquidDelegateBatch, buildEvmMultisignBodyHyperliquidDelegateOnlyBatch, buildEvmMultisignBodyHyperliquidLimitOrderBatch, buildEvmMultisignBodyHyperliquidStakeDepositBatch, buildEvmMultisignBodyHyperliquidStakeWithdrawBatch, buildEvmMultisignBodyHyperliquidUndelegateBatch, buildEvmMultisignBodyHyperliquidUsdClassTransferBatch, buildEvmMultisignBodyHyperliquidVaultDepositBatch, buildEvmMultisignBodyHyperliquidVaultWithdrawBatch, coreWriterStep, hyperliquidApiBaseUrl, hyperliquidCollectAllPerpMarkets, hyperliquidEncodePx8, hyperliquidEncodeUsd6, hyperliquidEncodeWei8, hyperliquidFetchActiveAssetData, hyperliquidFetchAllMids, hyperliquidFetchCandles, hyperliquidFetchClearinghouseState, hyperliquidFetchDelegations, hyperliquidFetchDelegationsForExecutor, hyperliquidFetchDexList, hyperliquidFetchMarketSnapshot, hyperliquidFetchMarketSnapshotSummary, hyperliquidFetchMarketsSummary, hyperliquidFetchOhlcvRange, hyperliquidFetchOhlcvSummary, hyperliquidFetchOpenContextSummary, hyperliquidFetchOpenMarketContext, hyperliquidFetchOpenOrders, hyperliquidFetchOpenOrdersSummary, hyperliquidFetchOrdersForExecutor, hyperliquidFetchPerpAssetContext, hyperliquidFetchPerpConciseAnnotations, hyperliquidFetchPerpMeta, hyperliquidFetchPositionDisplayRows, hyperliquidFetchPositionsForExecutor, hyperliquidFetchSpotClearinghouseState, hyperliquidFetchSpotMeta, hyperliquidFetchStakingSummary, hyperliquidFetchStakingSummaryForExecutor, hyperliquidFetchUsdClassBalances, hyperliquidFetchUsdClassBalancesSummary, hyperliquidFetchUserVaultEquities, hyperliquidFetchUserVaultEquitiesSummary, hyperliquidFetchVaultCatalogSummary, hyperliquidFetchVaultSummaries, hyperliquidInferDexFromCoin, hyperliquidIsSpotAssetId, hyperliquidMarketSymbol, hyperliquidProtocolModule, hyperliquidResolveAsset, hyperliquidResolveOhlcvWindow, hyperliquidResolvePerpAsset, hyperliquidResolvePerpMarket, hyperliquidResolveSpotAsset, hyperliquidResolveTif, hyperliquidSearchMarkets, hyperliquidSearchMarketsSummary, hyperliquidVaultStatsUrl, isHyperliquidChainSupported };
|
|
1463
|
+
//# sourceMappingURL=index.js.map
|
|
1464
|
+
//# sourceMappingURL=index.js.map
|