@exagent/agent 0.3.5 → 0.3.7

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 (78) hide show
  1. package/dist/chunk-7UGLJO6W.js +6392 -0
  2. package/dist/chunk-EHAOPCTJ.js +6406 -0
  3. package/dist/chunk-FGMXTW5I.js +6540 -0
  4. package/dist/chunk-IVA2SCSN.js +6756 -0
  5. package/dist/chunk-JHXCSGPC.js +6352 -0
  6. package/dist/chunk-V6O4UXVN.js +6345 -0
  7. package/dist/chunk-ZRAOPQQW.js +6406 -0
  8. package/dist/cli.js +40 -98
  9. package/dist/index.d.ts +24 -2
  10. package/dist/index.js +1 -1
  11. package/package.json +17 -14
  12. package/.turbo/turbo-build.log +0 -17
  13. package/src/bridge/across.ts +0 -240
  14. package/src/bridge/bridge-manager.ts +0 -87
  15. package/src/bridge/index.ts +0 -9
  16. package/src/bridge/types.ts +0 -77
  17. package/src/chains.ts +0 -105
  18. package/src/cli.ts +0 -244
  19. package/src/config.ts +0 -499
  20. package/src/diagnostics.ts +0 -335
  21. package/src/index.ts +0 -98
  22. package/src/llm/anthropic.ts +0 -63
  23. package/src/llm/base.ts +0 -264
  24. package/src/llm/deepseek.ts +0 -48
  25. package/src/llm/google.ts +0 -63
  26. package/src/llm/groq.ts +0 -48
  27. package/src/llm/index.ts +0 -42
  28. package/src/llm/mistral.ts +0 -48
  29. package/src/llm/ollama.ts +0 -52
  30. package/src/llm/openai.ts +0 -51
  31. package/src/llm/together.ts +0 -48
  32. package/src/llm-providers.ts +0 -100
  33. package/src/logger.ts +0 -137
  34. package/src/paper/executor.ts +0 -201
  35. package/src/paper/index.ts +0 -1
  36. package/src/perp/client.ts +0 -200
  37. package/src/perp/index.ts +0 -12
  38. package/src/perp/msgpack.ts +0 -272
  39. package/src/perp/orders.ts +0 -234
  40. package/src/perp/positions.ts +0 -126
  41. package/src/perp/signer.ts +0 -277
  42. package/src/perp/types.ts +0 -192
  43. package/src/perp/websocket.ts +0 -274
  44. package/src/position-tracker.ts +0 -243
  45. package/src/prediction/client.ts +0 -281
  46. package/src/prediction/index.ts +0 -3
  47. package/src/prediction/order-manager.ts +0 -297
  48. package/src/prediction/types.ts +0 -151
  49. package/src/relay.ts +0 -254
  50. package/src/runtime.ts +0 -1755
  51. package/src/scrub-secrets.ts +0 -39
  52. package/src/setup.ts +0 -384
  53. package/src/signal.ts +0 -212
  54. package/src/spot/aerodrome.ts +0 -158
  55. package/src/spot/client.ts +0 -138
  56. package/src/spot/index.ts +0 -11
  57. package/src/spot/swap-manager.ts +0 -219
  58. package/src/spot/types.ts +0 -203
  59. package/src/spot/uniswap.ts +0 -150
  60. package/src/store.ts +0 -50
  61. package/src/strategy/index.ts +0 -2
  62. package/src/strategy/loader.ts +0 -191
  63. package/src/strategy/templates.ts +0 -125
  64. package/src/trading/index.ts +0 -2
  65. package/src/trading/market.ts +0 -120
  66. package/src/trading/risk.ts +0 -107
  67. package/src/ui.ts +0 -75
  68. package/test-bridge-arb-to-base.mjs +0 -223
  69. package/test-funded-check.mjs +0 -79
  70. package/test-funded-phase19.mjs +0 -933
  71. package/test-hl-deposit-recover.mjs +0 -281
  72. package/test-hl-withdraw.mjs +0 -372
  73. package/test-live-signing.mjs +0 -374
  74. package/test-phase7.mjs +0 -416
  75. package/test-recover-arb.mjs +0 -206
  76. package/test-spot-bridge.mjs +0 -248
  77. package/test-wallet-setup.mjs +0 -126
  78. package/tsconfig.json +0 -8
@@ -1,100 +0,0 @@
1
- /**
2
- * LLM provider and model registry.
3
- * Keep in sync with apps/web/src/lib/llm-providers.ts.
4
- */
5
-
6
- export interface LlmModel {
7
- id: string;
8
- label: string;
9
- }
10
-
11
- export interface LlmProvider {
12
- id: string;
13
- label: string;
14
- models: LlmModel[];
15
- }
16
-
17
- export const LLM_PROVIDERS: LlmProvider[] = [
18
- {
19
- id: 'openai',
20
- label: 'OpenAI',
21
- models: [
22
- { id: 'gpt-5.2', label: 'GPT-5.2' },
23
- { id: 'gpt-5.2-pro', label: 'GPT-5.2 Pro' },
24
- { id: 'gpt-5-mini', label: 'GPT-5 Mini' },
25
- { id: 'gpt-5-nano', label: 'GPT-5 Nano' },
26
- { id: 'gpt-4o', label: 'GPT-4o' },
27
- { id: 'gpt-4o-mini', label: 'GPT-4o Mini' },
28
- ],
29
- },
30
- {
31
- id: 'anthropic',
32
- label: 'Anthropic',
33
- models: [
34
- { id: 'claude-opus-4-6', label: 'Claude Opus 4.6' },
35
- { id: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6' },
36
- { id: 'claude-haiku-4-5', label: 'Claude Haiku 4.5' },
37
- ],
38
- },
39
- {
40
- id: 'google',
41
- label: 'Google',
42
- models: [
43
- { id: 'gemini-3-pro', label: 'Gemini 3 Pro' },
44
- { id: 'gemini-3-flash', label: 'Gemini 3 Flash' },
45
- { id: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro' },
46
- { id: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash' },
47
- { id: 'gemini-2.5-flash-lite', label: 'Gemini 2.5 Flash Lite' },
48
- ],
49
- },
50
- {
51
- id: 'deepseek',
52
- label: 'DeepSeek',
53
- models: [
54
- { id: 'deepseek-chat', label: 'DeepSeek Chat' },
55
- { id: 'deepseek-reasoner', label: 'DeepSeek Reasoner' },
56
- ],
57
- },
58
- {
59
- id: 'mistral',
60
- label: 'Mistral',
61
- models: [
62
- { id: 'mistral-large-latest', label: 'Mistral Large' },
63
- { id: 'mistral-small-latest', label: 'Mistral Small' },
64
- ],
65
- },
66
- {
67
- id: 'groq',
68
- label: 'Groq',
69
- models: [
70
- { id: 'llama-3.3-70b-versatile', label: 'Llama 3.3 70B' },
71
- { id: 'llama-3.1-8b-instant', label: 'Llama 3.1 8B' },
72
- { id: 'mixtral-8x7b-32768', label: 'Mixtral 8x7B' },
73
- ],
74
- },
75
- {
76
- id: 'together',
77
- label: 'Together',
78
- models: [
79
- { id: 'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo', label: 'Llama 3.1 70B' },
80
- { id: 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo', label: 'Llama 3.1 8B' },
81
- ],
82
- },
83
- {
84
- id: 'ollama',
85
- label: 'Ollama (local)',
86
- models: [
87
- { id: 'llama3.1', label: 'Llama 3.1' },
88
- { id: 'mistral', label: 'Mistral' },
89
- { id: 'custom', label: 'Custom (type model name)' },
90
- ],
91
- },
92
- ];
93
-
94
- export function getProvider(id: string): LlmProvider | undefined {
95
- return LLM_PROVIDERS.find((p) => p.id === id);
96
- }
97
-
98
- export function getProviderIds(): string[] {
99
- return LLM_PROVIDERS.map((p) => p.id);
100
- }
package/src/logger.ts DELETED
@@ -1,137 +0,0 @@
1
- /**
2
- * Structured JSON logger for the agent SDK.
3
- *
4
- * Outputs newline-delimited JSON (NDJSON) with consistent fields:
5
- * { ts, level, cat, msg, ...data }
6
- *
7
- * Categories map to agent subsystems: runtime, llm, strategy, signal,
8
- * relay, risk, venue, bridge, cycle, diagnostics.
9
- */
10
-
11
- export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
12
-
13
- export type LogCategory =
14
- | 'runtime'
15
- | 'llm'
16
- | 'strategy'
17
- | 'signal'
18
- | 'relay'
19
- | 'risk'
20
- | 'venue'
21
- | 'bridge'
22
- | 'cycle'
23
- | 'diagnostics';
24
-
25
- export interface LogEntry {
26
- ts: string;
27
- level: LogLevel;
28
- cat: LogCategory;
29
- msg: string;
30
- [key: string]: unknown;
31
- }
32
-
33
- const LEVEL_PRIORITY: Record<LogLevel, number> = {
34
- debug: 0,
35
- info: 1,
36
- warn: 2,
37
- error: 3,
38
- };
39
-
40
- export interface LoggerConfig {
41
- /** Minimum log level (default: 'info') */
42
- minLevel?: LogLevel;
43
- /** Output as JSON (true) or human-readable (false). Default: true */
44
- json?: boolean;
45
- /** Custom output function (default: console methods) */
46
- output?: (entry: LogEntry) => void;
47
- }
48
-
49
- export class Logger {
50
- private minLevel: number;
51
- private jsonMode: boolean;
52
- private output: ((entry: LogEntry) => void) | null;
53
-
54
- constructor(config?: LoggerConfig) {
55
- this.minLevel = LEVEL_PRIORITY[config?.minLevel ?? 'info'];
56
- this.jsonMode = config?.json ?? true;
57
- this.output = config?.output ?? null;
58
- }
59
-
60
- debug(cat: LogCategory, msg: string, data?: Record<string, unknown>): void {
61
- this.log('debug', cat, msg, data);
62
- }
63
-
64
- info(cat: LogCategory, msg: string, data?: Record<string, unknown>): void {
65
- this.log('info', cat, msg, data);
66
- }
67
-
68
- warn(cat: LogCategory, msg: string, data?: Record<string, unknown>): void {
69
- this.log('warn', cat, msg, data);
70
- }
71
-
72
- error(cat: LogCategory, msg: string, data?: Record<string, unknown>): void {
73
- this.log('error', cat, msg, data);
74
- }
75
-
76
- private log(level: LogLevel, cat: LogCategory, msg: string, data?: Record<string, unknown>): void {
77
- if (LEVEL_PRIORITY[level] < this.minLevel) return;
78
-
79
- const entry: LogEntry = {
80
- ts: new Date().toISOString(),
81
- level,
82
- cat,
83
- msg,
84
- ...data,
85
- };
86
-
87
- if (this.output) {
88
- this.output(entry);
89
- return;
90
- }
91
-
92
- if (this.jsonMode) {
93
- const line = JSON.stringify(entry);
94
- switch (level) {
95
- case 'error':
96
- console.error(line);
97
- break;
98
- case 'warn':
99
- console.warn(line);
100
- break;
101
- default:
102
- console.log(line);
103
- }
104
- } else {
105
- // Human-readable fallback: [cat] msg { data }
106
- const prefix = `[${cat}]`;
107
- const extra = data && Object.keys(data).length > 0
108
- ? ' ' + JSON.stringify(data)
109
- : '';
110
- switch (level) {
111
- case 'error':
112
- console.error(`${prefix} ${msg}${extra}`);
113
- break;
114
- case 'warn':
115
- console.warn(`${prefix} ${msg}${extra}`);
116
- break;
117
- default:
118
- console.log(`${prefix} ${msg}${extra}`);
119
- }
120
- }
121
- }
122
- }
123
-
124
- /**
125
- * Singleton logger instance.
126
- * Defaults to JSON mode at 'info' level.
127
- * Call `configureLogger()` before `start()` to customize.
128
- */
129
- let globalLogger = new Logger();
130
-
131
- export function getLogger(): Logger {
132
- return globalLogger;
133
- }
134
-
135
- export function configureLogger(config: LoggerConfig): void {
136
- globalLogger = new Logger(config);
137
- }
@@ -1,201 +0,0 @@
1
- import type { TradeSignal, PaperTrade, PaperMetrics, MarketData } from '@exagent/sdk';
2
- import { randomUUID } from 'node:crypto';
3
-
4
- interface PaperPosition {
5
- quantity: number;
6
- avgPrice: number;
7
- }
8
-
9
- export class PaperExecutor {
10
- private cash: number;
11
- private positions: Map<string, PaperPosition> = new Map();
12
- private trades: PaperTrade[] = [];
13
- private equityCurve: { timestamp: number; equity: number }[] = [];
14
- private currentPrices: Record<string, number> = {};
15
- private slippageBps: number;
16
- private feeRate: number;
17
- private peakEquity: number;
18
- private maxDrawdown = 0;
19
-
20
- constructor(initialCash: number = 10000, slippageBps: number = 50, feeRate: number = 0.002) {
21
- this.cash = initialCash;
22
- this.slippageBps = slippageBps;
23
- this.feeRate = feeRate;
24
- this.peakEquity = initialCash;
25
- this.recordEquity();
26
- }
27
-
28
- execute(signal: TradeSignal, market: MarketData): PaperTrade | null {
29
- const marketPrice = market.getPrice(signal.symbol);
30
- if (!marketPrice) {
31
- console.warn(`[paper] No price for ${signal.symbol}`);
32
- return null;
33
- }
34
-
35
- const isBuy = signal.side === 'buy' || signal.side === 'long';
36
- const slippage = (this.slippageBps / 10000) * marketPrice;
37
- const executedPrice = isBuy ? marketPrice + slippage : marketPrice - slippage;
38
- const fee = signal.size * executedPrice * this.feeRate;
39
-
40
- let realizedPnL = 0;
41
-
42
- if (isBuy) {
43
- const totalCost = signal.size * executedPrice + fee;
44
- if (totalCost > this.cash) {
45
- console.warn(`[paper] Insufficient funds: need $${totalCost.toFixed(2)}, have $${this.cash.toFixed(2)}`);
46
- return null;
47
- }
48
-
49
- this.cash -= totalCost;
50
- const existing = this.positions.get(signal.symbol);
51
- if (existing) {
52
- const totalQty = existing.quantity + signal.size;
53
- existing.avgPrice = (existing.avgPrice * existing.quantity + executedPrice * signal.size) / totalQty;
54
- existing.quantity = totalQty;
55
- } else {
56
- this.positions.set(signal.symbol, { quantity: signal.size, avgPrice: executedPrice });
57
- }
58
- } else {
59
- const existing = this.positions.get(signal.symbol);
60
- if (!existing || existing.quantity < signal.size) {
61
- console.warn(`[paper] No position to sell: ${signal.symbol}`);
62
- return null;
63
- }
64
-
65
- realizedPnL = (executedPrice - existing.avgPrice) * signal.size - fee;
66
- const proceeds = signal.size * executedPrice - fee;
67
- this.cash += proceeds;
68
- existing.quantity -= signal.size;
69
- if (existing.quantity <= 0.000001) {
70
- this.positions.delete(signal.symbol);
71
- }
72
- }
73
-
74
- const trade: PaperTrade = {
75
- id: randomUUID(),
76
- symbol: signal.symbol,
77
- side: isBuy ? 'buy' : 'sell',
78
- size: signal.size,
79
- entryPrice: executedPrice,
80
- fee,
81
- pnl: realizedPnL !== 0 ? realizedPnL : undefined,
82
- timestamp: Date.now(),
83
- venue: `paper_${signal.venue}`,
84
- };
85
-
86
- this.trades.push(trade);
87
- this.recordEquity();
88
-
89
- return trade;
90
- }
91
-
92
- /** Update equity snapshot with current market prices */
93
- recordEquityWithPrices(prices: Record<string, number>): void {
94
- this.currentPrices = prices;
95
- this.recordEquity();
96
- }
97
-
98
- private recordEquity(): void {
99
- const equity = this.getEquity();
100
- this.equityCurve.push({ timestamp: Date.now(), equity });
101
- if (equity > this.peakEquity) this.peakEquity = equity;
102
- const drawdown = (this.peakEquity - equity) / this.peakEquity;
103
- if (drawdown > this.maxDrawdown) this.maxDrawdown = drawdown;
104
- }
105
-
106
- /** Calculate equity using current market prices (falls back to cost basis if no price available) */
107
- getEquity(): number {
108
- let positionValue = 0;
109
- for (const [symbol, pos] of this.positions) {
110
- const currentPrice = this.currentPrices[symbol.toUpperCase()] ?? this.currentPrices[symbol] ?? pos.avgPrice;
111
- positionValue += pos.quantity * currentPrice;
112
- }
113
- return this.cash + positionValue;
114
- }
115
-
116
- getCash(): number {
117
- return this.cash;
118
- }
119
-
120
- getPositions(): Map<string, PaperPosition> {
121
- return new Map(this.positions);
122
- }
123
-
124
- getTrades(): PaperTrade[] {
125
- return [...this.trades];
126
- }
127
-
128
- getEquityCurve(): { timestamp: number; equity: number }[] {
129
- return [...this.equityCurve];
130
- }
131
-
132
- getMetrics(): PaperMetrics {
133
- const initialEquity = this.equityCurve[0]?.equity || 0;
134
- const currentEquity = this.getEquity();
135
- const totalReturn = initialEquity > 0 ? (currentEquity - initialEquity) / initialEquity : 0;
136
-
137
- // Calculate daily returns for Sharpe
138
- const dailyReturns = this.calculateDailyReturns();
139
- const sharpeRatio = this.calculateSharpe(dailyReturns);
140
-
141
- // Win/loss stats
142
- let wins = 0;
143
- let losses = 0;
144
- let grossProfit = 0;
145
- let grossLoss = 0;
146
-
147
- // Match buys and sells to calculate trade PnL
148
- const sellTrades = this.trades.filter(t => t.side === 'sell');
149
- for (const sell of sellTrades) {
150
- const buyTrades = this.trades.filter(t => t.side === 'buy' && t.symbol === sell.symbol);
151
- const avgEntry = buyTrades.reduce((sum, t) => sum + t.entryPrice, 0) / (buyTrades.length || 1);
152
- const pnl = (sell.entryPrice - avgEntry) * sell.size - sell.fee;
153
-
154
- if (pnl > 0) {
155
- wins++;
156
- grossProfit += pnl;
157
- } else {
158
- losses++;
159
- grossLoss += Math.abs(pnl);
160
- }
161
- }
162
-
163
- return {
164
- totalReturn,
165
- sharpeRatio,
166
- maxDrawdown: this.maxDrawdown,
167
- winRate: wins + losses > 0 ? wins / (wins + losses) : 0,
168
- profitFactor: grossLoss > 0 ? grossProfit / grossLoss : grossProfit > 0 ? Infinity : 0,
169
- totalTrades: this.trades.length,
170
- };
171
- }
172
-
173
- private calculateDailyReturns(): number[] {
174
- if (this.equityCurve.length < 2) return [];
175
-
176
- const dailyEquity = new Map<string, number>();
177
- for (const point of this.equityCurve) {
178
- const date = new Date(point.timestamp).toISOString().slice(0, 10);
179
- dailyEquity.set(date, point.equity);
180
- }
181
-
182
- const dates = Array.from(dailyEquity.keys()).sort();
183
- const returns: number[] = [];
184
- for (let i = 1; i < dates.length; i++) {
185
- const prev = dailyEquity.get(dates[i - 1])!;
186
- const curr = dailyEquity.get(dates[i])!;
187
- if (prev > 0) returns.push((curr - prev) / prev);
188
- }
189
-
190
- return returns;
191
- }
192
-
193
- private calculateSharpe(returns: number[]): number {
194
- if (returns.length < 2) return 0;
195
- const mean = returns.reduce((a, b) => a + b, 0) / returns.length;
196
- const variance = returns.reduce((sum, r) => sum + (r - mean) ** 2, 0) / (returns.length - 1);
197
- const std = Math.sqrt(variance);
198
- if (std === 0) return 0;
199
- return (mean / std) * Math.sqrt(365);
200
- }
201
- }
@@ -1 +0,0 @@
1
- export { PaperExecutor } from './executor.js';
@@ -1,200 +0,0 @@
1
- /**
2
- * Hyperliquid REST Client
3
- *
4
- * Info API for read-only queries (positions, fills, metadata).
5
- * Exchange API for order placement (via orders.ts).
6
- */
7
-
8
- import type {
9
- PerpConfig,
10
- PerpPosition,
11
- AccountSummary,
12
- PerpFill,
13
- PerpMarketData,
14
- AssetMeta,
15
- ClearinghouseState,
16
- AssetPosition,
17
- HyperliquidFill,
18
- HyperliquidOrder,
19
- L2Book,
20
- } from './types.js';
21
-
22
- export class HyperliquidClient {
23
- private readonly apiUrl: string;
24
- private meta: AssetMeta[] | null = null;
25
- private assetIndexCache: Map<string, number> = new Map();
26
-
27
- constructor(config: PerpConfig) {
28
- this.apiUrl = config.apiUrl;
29
- }
30
-
31
- // ── INFO API (read-only) ───────────────────────────────────
32
-
33
- async getMeta(): Promise<AssetMeta[]> {
34
- if (this.meta) return this.meta;
35
- const resp = await this.infoRequest({ type: 'meta' });
36
- this.meta = resp.universe as AssetMeta[];
37
- this.meta.forEach((asset: AssetMeta, idx: number) => {
38
- this.assetIndexCache.set(asset.name, idx);
39
- });
40
- return this.meta;
41
- }
42
-
43
- async getAssetIndex(coin: string): Promise<number> {
44
- if (this.assetIndexCache.has(coin)) return this.assetIndexCache.get(coin)!;
45
- await this.getMeta();
46
- const idx = this.assetIndexCache.get(coin);
47
- if (idx === undefined) throw new Error(`Unknown instrument: ${coin}`);
48
- return idx;
49
- }
50
-
51
- /** Get the size decimal precision for an instrument (for order size rounding) */
52
- async getSzDecimals(coin: string): Promise<number> {
53
- const meta = await this.getMeta();
54
- const asset = meta.find(a => a.name === coin) ?? meta.find(a => a.name.toUpperCase() === coin.toUpperCase());
55
- if (!asset) throw new Error(`Unknown instrument: ${coin}`);
56
- return asset.szDecimals;
57
- }
58
-
59
- async getAllMids(): Promise<Record<string, string>> {
60
- return this.infoRequest({ type: 'allMids' });
61
- }
62
-
63
- async getClearinghouseState(user: string): Promise<ClearinghouseState> {
64
- return this.infoRequest({ type: 'clearinghouseState', user });
65
- }
66
-
67
- async getUserFills(user: string, startTime?: number): Promise<HyperliquidFill[]> {
68
- return this.infoRequest({
69
- type: 'userFills',
70
- user,
71
- ...(startTime !== undefined && { startTime }),
72
- });
73
- }
74
-
75
- async getUserFillsByTime(
76
- user: string,
77
- startTime: number,
78
- endTime?: number,
79
- ): Promise<HyperliquidFill[]> {
80
- return this.infoRequest({
81
- type: 'userFillsByTime',
82
- user,
83
- startTime,
84
- ...(endTime !== undefined && { endTime }),
85
- });
86
- }
87
-
88
- async getOpenOrders(user: string): Promise<HyperliquidOrder[]> {
89
- return this.infoRequest({ type: 'openOrders', user });
90
- }
91
-
92
- async getL2Book(coin: string, depth?: number): Promise<L2Book> {
93
- return this.infoRequest({
94
- type: 'l2Book',
95
- coin,
96
- ...(depth !== undefined && { nSigFigs: depth }),
97
- });
98
- }
99
-
100
- // ── HIGH-LEVEL HELPERS ─────────────────────────────────────
101
-
102
- async getPositions(user: string): Promise<PerpPosition[]> {
103
- const state = await this.getClearinghouseState(user);
104
- return state.assetPositions
105
- .filter((p) => parseFloat(p.position.szi) !== 0)
106
- .map((p) => this.parsePosition(p));
107
- }
108
-
109
- async getAccountSummary(user: string): Promise<AccountSummary> {
110
- const state = await this.getClearinghouseState(user);
111
- const cms = state.crossMarginSummary;
112
-
113
- const totalEquity = parseFloat(cms.accountValue);
114
- const totalNotional = parseFloat(cms.totalNtlPos);
115
- const totalMarginUsed = parseFloat(cms.totalMarginUsed);
116
-
117
- return {
118
- totalEquity,
119
- availableMargin: totalEquity - totalMarginUsed,
120
- totalMarginUsed,
121
- totalUnrealizedPnl: parseFloat(cms.totalRawUsd) - totalEquity,
122
- totalNotional,
123
- maintenanceMargin: totalMarginUsed * 0.5,
124
- effectiveLeverage: totalEquity > 0 ? totalNotional / totalEquity : 0,
125
- cashBalance:
126
- parseFloat(cms.accountValue) -
127
- state.assetPositions.reduce(
128
- (sum, p) => sum + parseFloat(p.position.unrealizedPnl),
129
- 0,
130
- ),
131
- };
132
- }
133
-
134
- async getMarketData(instruments: string[]): Promise<PerpMarketData[]> {
135
- const mids = await this.getAllMids();
136
- return instruments
137
- .filter((inst) => mids[inst] !== undefined)
138
- .map((inst) => ({
139
- instrument: inst,
140
- midPrice: parseFloat(mids[inst]),
141
- bestBid: parseFloat(mids[inst]),
142
- bestAsk: parseFloat(mids[inst]),
143
- funding8h: 0,
144
- openInterest: 0,
145
- volume24h: 0,
146
- priceChange24h: 0,
147
- }));
148
- }
149
-
150
- parseFill(fill: HyperliquidFill): PerpFill {
151
- return {
152
- oid: fill.oid,
153
- coin: fill.coin,
154
- side: fill.side,
155
- px: fill.px,
156
- sz: fill.sz,
157
- fee: fill.fee,
158
- time: fill.time,
159
- hash: fill.hash,
160
- isMaker: fill.startPosition !== fill.px,
161
- builderFee: fill.builderFee,
162
- liquidation: fill.liquidation,
163
- };
164
- }
165
-
166
- // ── PRIVATE ────────────────────────────────────────────────
167
-
168
- private parsePosition(ap: AssetPosition): PerpPosition {
169
- const pos = ap.position;
170
- const size = parseFloat(pos.szi);
171
- const entryPrice = parseFloat(pos.entryPx || '0');
172
- const markPrice = parseFloat(pos.positionValue || '0') / Math.abs(size || 1);
173
-
174
- return {
175
- instrument: pos.coin,
176
- assetIndex: this.assetIndexCache.get(pos.coin) ?? -1,
177
- size,
178
- entryPrice,
179
- markPrice,
180
- unrealizedPnl: parseFloat(pos.unrealizedPnl),
181
- leverage: parseFloat(pos.leverage?.value || '1'),
182
- marginType: pos.leverage?.type === 'isolated' ? 'isolated' : 'cross',
183
- liquidationPrice: parseFloat(pos.liquidationPx || '0'),
184
- notionalUSD: Math.abs(size) * markPrice,
185
- marginUsed: parseFloat(pos.marginUsed),
186
- };
187
- }
188
-
189
- private async infoRequest(body: Record<string, unknown>): Promise<any> {
190
- const resp = await fetch(`${this.apiUrl}/info`, {
191
- method: 'POST',
192
- headers: { 'Content-Type': 'application/json' },
193
- body: JSON.stringify(body),
194
- });
195
- if (!resp.ok) {
196
- throw new Error(`Hyperliquid Info API error: ${resp.status} ${await resp.text()}`);
197
- }
198
- return resp.json();
199
- }
200
- }
package/src/perp/index.ts DELETED
@@ -1,12 +0,0 @@
1
- export * from './types.js';
2
- export { HyperliquidClient } from './client.js';
3
- export { HyperliquidSigner, getNextNonce, HYPERLIQUID_DOMAIN, HYPERLIQUID_USER_DOMAIN, USER_ACTION_TYPES } from './signer.js';
4
- export { HyperliquidOrderManager } from './orders.js';
5
- export { HyperliquidPositionManager } from './positions.js';
6
- export {
7
- HyperliquidWebSocket,
8
- type FillCallback,
9
- type FundingCallback,
10
- type LiquidationCallback,
11
- type FundingPayment,
12
- } from './websocket.js';