@exagent/agent 0.1.18 → 0.1.19

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/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { Address, Hash } from 'viem';
2
+ import { Address, Hash, WalletClient } from 'viem';
3
3
  import { ExagentClient } from '@exagent/sdk';
4
4
 
5
5
  declare const LLMProviderSchema: z.ZodEnum<["openai", "anthropic", "google", "deepseek", "mistral", "groq", "together", "ollama", "custom"]>;
@@ -91,6 +91,47 @@ declare const RelayConfigSchema: z.ZodOptional<z.ZodObject<{
91
91
  heartbeatIntervalMs?: number | undefined;
92
92
  }>>;
93
93
  type RelayConfig$1 = z.infer<typeof RelayConfigSchema>;
94
+ declare const PerpConfigSchema: z.ZodOptional<z.ZodObject<{
95
+ /** Enable perp trading */
96
+ enabled: z.ZodDefault<z.ZodBoolean>;
97
+ /** Hyperliquid REST API URL */
98
+ apiUrl: z.ZodDefault<z.ZodString>;
99
+ /** Hyperliquid WebSocket URL */
100
+ wsUrl: z.ZodDefault<z.ZodString>;
101
+ /** Builder address for fee collection (must have >= 100 USDC on HL) */
102
+ builderAddress: z.ZodString;
103
+ /** Builder fee in tenths of basis points (100 = 10 bps = 0.10%) */
104
+ builderFeeTenthsBps: z.ZodDefault<z.ZodNumber>;
105
+ /** Private key for the perp relayer (calls recordPerpTrade on Base). Falls back to agent wallet. */
106
+ perpRelayerKey: z.ZodOptional<z.ZodString>;
107
+ /** Maximum leverage per position (default: 10) */
108
+ maxLeverage: z.ZodDefault<z.ZodNumber>;
109
+ /** Maximum notional position size in USD (default: 50000) */
110
+ maxNotionalUSD: z.ZodDefault<z.ZodNumber>;
111
+ /** Allowed perp instruments (e.g. ["ETH", "BTC", "SOL"]). If empty, all instruments allowed. */
112
+ allowedInstruments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
113
+ }, "strip", z.ZodTypeAny, {
114
+ enabled: boolean;
115
+ apiUrl: string;
116
+ wsUrl: string;
117
+ builderAddress: string;
118
+ builderFeeTenthsBps: number;
119
+ maxLeverage: number;
120
+ maxNotionalUSD: number;
121
+ perpRelayerKey?: string | undefined;
122
+ allowedInstruments?: string[] | undefined;
123
+ }, {
124
+ builderAddress: string;
125
+ enabled?: boolean | undefined;
126
+ apiUrl?: string | undefined;
127
+ wsUrl?: string | undefined;
128
+ builderFeeTenthsBps?: number | undefined;
129
+ perpRelayerKey?: string | undefined;
130
+ maxLeverage?: number | undefined;
131
+ maxNotionalUSD?: number | undefined;
132
+ allowedInstruments?: string[] | undefined;
133
+ }>>;
134
+ type PerpConfig$1 = z.infer<typeof PerpConfigSchema>;
94
135
  declare const AgentConfigSchema: z.ZodObject<{
95
136
  agentId: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
96
137
  name: z.ZodString;
@@ -182,6 +223,46 @@ declare const AgentConfigSchema: z.ZodObject<{
182
223
  enabled?: boolean | undefined;
183
224
  heartbeatIntervalMs?: number | undefined;
184
225
  }>>;
226
+ perp: z.ZodOptional<z.ZodObject<{
227
+ /** Enable perp trading */
228
+ enabled: z.ZodDefault<z.ZodBoolean>;
229
+ /** Hyperliquid REST API URL */
230
+ apiUrl: z.ZodDefault<z.ZodString>;
231
+ /** Hyperliquid WebSocket URL */
232
+ wsUrl: z.ZodDefault<z.ZodString>;
233
+ /** Builder address for fee collection (must have >= 100 USDC on HL) */
234
+ builderAddress: z.ZodString;
235
+ /** Builder fee in tenths of basis points (100 = 10 bps = 0.10%) */
236
+ builderFeeTenthsBps: z.ZodDefault<z.ZodNumber>;
237
+ /** Private key for the perp relayer (calls recordPerpTrade on Base). Falls back to agent wallet. */
238
+ perpRelayerKey: z.ZodOptional<z.ZodString>;
239
+ /** Maximum leverage per position (default: 10) */
240
+ maxLeverage: z.ZodDefault<z.ZodNumber>;
241
+ /** Maximum notional position size in USD (default: 50000) */
242
+ maxNotionalUSD: z.ZodDefault<z.ZodNumber>;
243
+ /** Allowed perp instruments (e.g. ["ETH", "BTC", "SOL"]). If empty, all instruments allowed. */
244
+ allowedInstruments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
245
+ }, "strip", z.ZodTypeAny, {
246
+ enabled: boolean;
247
+ apiUrl: string;
248
+ wsUrl: string;
249
+ builderAddress: string;
250
+ builderFeeTenthsBps: number;
251
+ maxLeverage: number;
252
+ maxNotionalUSD: number;
253
+ perpRelayerKey?: string | undefined;
254
+ allowedInstruments?: string[] | undefined;
255
+ }, {
256
+ builderAddress: string;
257
+ enabled?: boolean | undefined;
258
+ apiUrl?: string | undefined;
259
+ wsUrl?: string | undefined;
260
+ builderFeeTenthsBps?: number | undefined;
261
+ perpRelayerKey?: string | undefined;
262
+ maxLeverage?: number | undefined;
263
+ maxNotionalUSD?: number | undefined;
264
+ allowedInstruments?: string[] | undefined;
265
+ }>>;
185
266
  allowedTokens: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
186
267
  }, "strip", z.ZodTypeAny, {
187
268
  agentId: string | number;
@@ -220,6 +301,17 @@ declare const AgentConfigSchema: z.ZodObject<{
220
301
  apiUrl: string;
221
302
  heartbeatIntervalMs: number;
222
303
  } | undefined;
304
+ perp?: {
305
+ enabled: boolean;
306
+ apiUrl: string;
307
+ wsUrl: string;
308
+ builderAddress: string;
309
+ builderFeeTenthsBps: number;
310
+ maxLeverage: number;
311
+ maxNotionalUSD: number;
312
+ perpRelayerKey?: string | undefined;
313
+ allowedInstruments?: string[] | undefined;
314
+ } | undefined;
223
315
  allowedTokens?: string[] | undefined;
224
316
  }, {
225
317
  agentId: string | number;
@@ -258,6 +350,17 @@ declare const AgentConfigSchema: z.ZodObject<{
258
350
  enabled?: boolean | undefined;
259
351
  heartbeatIntervalMs?: number | undefined;
260
352
  } | undefined;
353
+ perp?: {
354
+ builderAddress: string;
355
+ enabled?: boolean | undefined;
356
+ apiUrl?: string | undefined;
357
+ wsUrl?: string | undefined;
358
+ builderFeeTenthsBps?: number | undefined;
359
+ perpRelayerKey?: string | undefined;
360
+ maxLeverage?: number | undefined;
361
+ maxNotionalUSD?: number | undefined;
362
+ allowedInstruments?: string[] | undefined;
363
+ } | undefined;
261
364
  allowedTokens?: string[] | undefined;
262
365
  }>;
263
366
  type AgentConfig = z.infer<typeof AgentConfigSchema>;
@@ -414,13 +517,13 @@ declare class VaultManager {
414
517
  * Used by both the SDK relay client and the API relay service.
415
518
  */
416
519
  type AgentMode = 'idle' | 'trading';
417
- type CommandType = 'start_trading' | 'stop_trading' | 'update_risk_params' | 'update_trading_interval' | 'create_vault' | 'refresh_status' | 'shutdown';
520
+ type CommandType = 'start_trading' | 'stop_trading' | 'enable_hyperliquid' | 'disable_hyperliquid' | 'start_perp_trading' | 'stop_perp_trading' | 'update_risk_params' | 'update_perp_params' | 'update_trading_interval' | 'create_vault' | 'refresh_status' | 'shutdown';
418
521
  interface RelayCommand {
419
522
  id: string;
420
523
  type: CommandType;
421
524
  params?: Record<string, unknown>;
422
525
  }
423
- type MessageType = 'trade_executed' | 'trade_failed' | 'funds_low' | 'risk_limit_hit' | 'vault_created' | 'config_updated' | 'llm_error' | 'command_result' | 'system';
526
+ type MessageType = 'trade_executed' | 'trade_failed' | 'perp_fill' | 'perp_liquidation_warning' | 'perp_funding' | 'funds_low' | 'risk_limit_hit' | 'vault_created' | 'config_updated' | 'llm_error' | 'command_result' | 'system';
424
527
  type MessageLevel = 'info' | 'warning' | 'error' | 'success';
425
528
  interface AgentStatusPayload {
426
529
  mode: AgentMode;
@@ -445,6 +548,16 @@ interface AgentStatusPayload {
445
548
  hasVault: boolean;
446
549
  vaultAddress: string | null;
447
550
  };
551
+ perp?: {
552
+ enabled: boolean;
553
+ trading: boolean;
554
+ equity: number;
555
+ unrealizedPnl: number;
556
+ marginUsed: number;
557
+ openPositions: number;
558
+ effectiveLeverage: number;
559
+ pendingRecords: number;
560
+ };
448
561
  }
449
562
  interface RelayConfig {
450
563
  enabled: boolean;
@@ -483,6 +596,16 @@ declare class AgentRuntime {
483
596
  private processAlive;
484
597
  private riskUniverse;
485
598
  private allowedTokens;
599
+ private perpClient;
600
+ private perpSigner;
601
+ private perpOrders;
602
+ private perpPositions;
603
+ private perpWebSocket;
604
+ private perpRecorder;
605
+ private perpOnboarding;
606
+ private perpStrategy;
607
+ private perpConnected;
608
+ private perpTradingActive;
486
609
  constructor(config: RuntimeConfig);
487
610
  /**
488
611
  * Initialize the agent runtime
@@ -496,6 +619,11 @@ declare class AgentRuntime {
496
619
  * Initialize the vault manager based on config
497
620
  */
498
621
  private initializeVaultManager;
622
+ /**
623
+ * Initialize Hyperliquid perp trading components.
624
+ * Only initializes if perp is enabled in config AND risk universe >= 2.
625
+ */
626
+ private initializePerp;
499
627
  /**
500
628
  * Ensure the current wallet is linked to the agent.
501
629
  * If the trading wallet differs from the owner, enters a recovery loop
@@ -537,6 +665,12 @@ declare class AgentRuntime {
537
665
  * Run a single trading cycle
538
666
  */
539
667
  private runCycle;
668
+ /**
669
+ * Run a single perp trading cycle.
670
+ * Fetches market data, positions, calls perp strategy, applies risk filters, executes.
671
+ * Fills arrive async via WebSocket and are auto-recorded on Base.
672
+ */
673
+ private runPerpCycle;
540
674
  /**
541
675
  * Check if ETH balance is below threshold and notify.
542
676
  * Returns true if trading should continue, false if ETH is critically low.
@@ -796,6 +930,174 @@ declare class TradeExecutor {
796
930
  private delay;
797
931
  }
798
932
 
933
+ /**
934
+ * Hyperliquid Perp Trading Types
935
+ *
936
+ * Core type definitions for perp trading via Hyperliquid L1.
937
+ * Agents record fills on-chain via Router.recordPerpTrade() for leaderboard attribution.
938
+ */
939
+
940
+ interface PerpConfig {
941
+ /** Enable perp trading */
942
+ enabled: boolean;
943
+ /** Hyperliquid REST API URL */
944
+ apiUrl: string;
945
+ /** Hyperliquid WebSocket URL */
946
+ wsUrl: string;
947
+ /** Builder address for fee collection (must have >= 100 USDC on HL) */
948
+ builderAddress: string;
949
+ /** Builder fee in tenths of basis points (100 = 10 bps = 0.10%) */
950
+ builderFeeTenthsBps: number;
951
+ /** Private key for the perp relayer (calls recordPerpTrade on Base). Falls back to agent wallet. */
952
+ perpRelayerKey?: string;
953
+ /** Maximum leverage per position (default: 10) */
954
+ maxLeverage: number;
955
+ /** Maximum notional position size in USD (default: 50000) */
956
+ maxNotionalUSD: number;
957
+ /** Allowed instruments (e.g. ["ETH", "BTC", "SOL"]). If empty, all instruments allowed. */
958
+ allowedInstruments?: string[];
959
+ }
960
+ type PerpAction = 'open_long' | 'open_short' | 'close_long' | 'close_short' | 'hold';
961
+ interface PerpTradeSignal {
962
+ /** Trading action */
963
+ action: PerpAction;
964
+ /** Instrument symbol (e.g. "ETH", "BTC", "SOL") */
965
+ instrument: string;
966
+ /** Position size in base units (e.g. 1.5 ETH) */
967
+ size: number;
968
+ /** Limit price (0 = market order) */
969
+ price: number;
970
+ /** Leverage multiplier (1-50) */
971
+ leverage: number;
972
+ /** Order type */
973
+ orderType: 'limit' | 'market';
974
+ /** Only reduce existing position (close/partial close) */
975
+ reduceOnly: boolean;
976
+ /** Signal confidence (0.0 - 1.0) */
977
+ confidence: number;
978
+ /** LLM reasoning for this signal */
979
+ reasoning?: string;
980
+ }
981
+ interface PerpPosition {
982
+ /** Instrument symbol */
983
+ instrument: string;
984
+ /** Hyperliquid asset index */
985
+ assetIndex: number;
986
+ /** Position size (positive = long, negative = short) */
987
+ size: number;
988
+ /** Average entry price */
989
+ entryPrice: number;
990
+ /** Current mark price */
991
+ markPrice: number;
992
+ /** Unrealized PnL in USD */
993
+ unrealizedPnl: number;
994
+ /** Current leverage */
995
+ leverage: number;
996
+ /** Margin type */
997
+ marginType: 'cross' | 'isolated';
998
+ /** Estimated liquidation price */
999
+ liquidationPrice: number;
1000
+ /** Notional value in USD (|size| * markPrice) */
1001
+ notionalUSD: number;
1002
+ /** Margin used for this position */
1003
+ marginUsed: number;
1004
+ }
1005
+ interface AccountSummary {
1006
+ /** Total account equity (cash + unrealized PnL) */
1007
+ totalEquity: number;
1008
+ /** Available margin for new positions */
1009
+ availableMargin: number;
1010
+ /** Total margin used across all positions */
1011
+ totalMarginUsed: number;
1012
+ /** Total unrealized PnL across all positions */
1013
+ totalUnrealizedPnl: number;
1014
+ /** Total notional exposure */
1015
+ totalNotional: number;
1016
+ /** Maintenance margin requirement */
1017
+ maintenanceMargin: number;
1018
+ /** Effective aggregate leverage (totalNotional / totalEquity) */
1019
+ effectiveLeverage: number;
1020
+ /** Cash balance (USDC) */
1021
+ cashBalance: number;
1022
+ }
1023
+ interface PerpFill {
1024
+ /** Order ID on Hyperliquid */
1025
+ oid: number;
1026
+ /** Instrument symbol */
1027
+ coin: string;
1028
+ /** Direction */
1029
+ side: 'B' | 'A';
1030
+ /** Fill price */
1031
+ px: string;
1032
+ /** Fill size */
1033
+ sz: string;
1034
+ /** Fee paid */
1035
+ fee: string;
1036
+ /** Fill timestamp (ms) */
1037
+ time: number;
1038
+ /** Fill hash from Hyperliquid */
1039
+ hash: string;
1040
+ /** Whether this was a maker fill */
1041
+ isMaker: boolean;
1042
+ /** Builder fee paid (if any) */
1043
+ builderFee?: string;
1044
+ /** Whether this was a liquidation */
1045
+ liquidation?: boolean;
1046
+ }
1047
+ interface PerpMarketData {
1048
+ /** Instrument symbol */
1049
+ instrument: string;
1050
+ /** Mid-market price */
1051
+ midPrice: number;
1052
+ /** Best bid */
1053
+ bestBid: number;
1054
+ /** Best ask */
1055
+ bestAsk: number;
1056
+ /** 8-hour funding rate */
1057
+ funding8h: number;
1058
+ /** Open interest in USD */
1059
+ openInterest: number;
1060
+ /** 24h volume in USD */
1061
+ volume24h: number;
1062
+ /** 24h price change (percentage) */
1063
+ priceChange24h: number;
1064
+ }
1065
+ /**
1066
+ * Perp strategy function signature.
1067
+ * Called once per perp trading cycle.
1068
+ *
1069
+ * @param marketData - Current market data for allowed instruments
1070
+ * @param positions - Current open positions
1071
+ * @param account - Account equity and margin state
1072
+ * @param llm - LLM adapter for reasoning
1073
+ * @param config - Agent configuration
1074
+ * @returns Array of perp trade signals
1075
+ */
1076
+ type PerpStrategyFunction = (marketData: PerpMarketData[], positions: PerpPosition[], account: AccountSummary, llm: LLMAdapter, config: Record<string, unknown>) => Promise<PerpTradeSignal[]>;
1077
+ interface OrderResult {
1078
+ /** Whether the order was accepted */
1079
+ success: boolean;
1080
+ /** Hyperliquid order ID */
1081
+ orderId?: number;
1082
+ /** Fill status */
1083
+ status: 'filled' | 'resting' | 'error';
1084
+ /** Average fill price (if filled) */
1085
+ avgPrice?: string;
1086
+ /** Total filled size (if filled) */
1087
+ filledSize?: string;
1088
+ /** Error message (if error) */
1089
+ error?: string;
1090
+ }
1091
+ interface RecordPerpTradeParams {
1092
+ agentId: bigint;
1093
+ configHash: `0x${string}`;
1094
+ instrument: string;
1095
+ isLong: boolean;
1096
+ notionalUSD: bigint;
1097
+ feeUSD: bigint;
1098
+ fillId: `0x${string}`;
1099
+ }
1100
+
799
1101
  /**
800
1102
  * Risk Manager
801
1103
  * Applies guardrails to trade signals before execution
@@ -850,6 +1152,26 @@ declare class RiskManager {
850
1152
  dailyLossLimit: number;
851
1153
  isLimitHit: boolean;
852
1154
  };
1155
+ /**
1156
+ * Filter perp trade signals through risk checks.
1157
+ * Reduce-only signals (closes) always pass.
1158
+ *
1159
+ * @param signals - Raw perp signals from strategy
1160
+ * @param positions - Current open positions on Hyperliquid
1161
+ * @param account - Current account equity and margin
1162
+ * @param maxLeverage - Maximum allowed leverage
1163
+ * @param maxNotionalUSD - Maximum notional per position
1164
+ * @returns Signals that pass risk checks
1165
+ */
1166
+ filterPerpSignals(signals: PerpTradeSignal[], positions: PerpPosition[], account: AccountSummary, maxLeverage: number, maxNotionalUSD: number): PerpTradeSignal[];
1167
+ /**
1168
+ * Validate an individual perp signal.
1169
+ */
1170
+ private validatePerpSignal;
1171
+ /**
1172
+ * Calculate liquidation proximity for a position (0.0 = safe, 1.0 = liquidated).
1173
+ */
1174
+ private calculateLiquidationProximity;
853
1175
  }
854
1176
 
855
1177
  /**
@@ -983,6 +1305,520 @@ declare class RelayClient {
983
1305
  disconnect(): void;
984
1306
  }
985
1307
 
1308
+ /**
1309
+ * Hyperliquid REST Client
1310
+ *
1311
+ * Wraps @nktkas/hyperliquid for Info + Exchange API access.
1312
+ * Handles meta caching, asset index lookups, and typed responses.
1313
+ */
1314
+
1315
+ declare class HyperliquidClient {
1316
+ private readonly apiUrl;
1317
+ private meta;
1318
+ private assetIndexCache;
1319
+ constructor(config: PerpConfig);
1320
+ /** Fetch perpetuals metadata (asset specs, names, indices) */
1321
+ getMeta(): Promise<AssetMeta[]>;
1322
+ /** Get asset index from symbol (e.g. "ETH" -> 1). Caches after first getMeta() call. */
1323
+ getAssetIndex(coin: string): Promise<number>;
1324
+ /** Get mid-market prices for all perpetuals */
1325
+ getAllMids(): Promise<Record<string, string>>;
1326
+ /** Get clearinghouse state (positions, margin, equity) for a user */
1327
+ getClearinghouseState(user: string): Promise<ClearinghouseState>;
1328
+ /** Get user's recent fills */
1329
+ getUserFills(user: string, startTime?: number): Promise<HyperliquidFill[]>;
1330
+ /** Get user's fills in a time range */
1331
+ getUserFillsByTime(user: string, startTime: number, endTime?: number): Promise<HyperliquidFill[]>;
1332
+ /** Get user's open orders */
1333
+ getOpenOrders(user: string): Promise<HyperliquidOrder[]>;
1334
+ /** Get user's funding history */
1335
+ getUserFunding(user: string, startTime: number): Promise<HyperliquidFunding[]>;
1336
+ /** Check max approved builder fee for a user */
1337
+ getMaxBuilderFee(user: string, builder: string): Promise<number>;
1338
+ /** Get L2 order book for a coin */
1339
+ getL2Book(coin: string, depth?: number): Promise<L2Book>;
1340
+ /** Get parsed positions for a user address */
1341
+ getPositions(user: string): Promise<PerpPosition[]>;
1342
+ /** Get account summary (equity, margin, leverage) */
1343
+ getAccountSummary(user: string): Promise<AccountSummary>;
1344
+ /** Get market data for a list of instruments */
1345
+ getMarketData(instruments: string[]): Promise<PerpMarketData[]>;
1346
+ /** Convert fills to our PerpFill type */
1347
+ parseFill(fill: HyperliquidFill): PerpFill;
1348
+ private parsePosition;
1349
+ private infoRequest;
1350
+ }
1351
+ interface AssetMeta {
1352
+ name: string;
1353
+ szDecimals: number;
1354
+ maxLeverage: number;
1355
+ onlyIsolated: boolean;
1356
+ }
1357
+ interface ClearinghouseState {
1358
+ assetPositions: AssetPosition[];
1359
+ crossMarginSummary: {
1360
+ accountValue: string;
1361
+ totalNtlPos: string;
1362
+ totalRawUsd: string;
1363
+ totalMarginUsed: string;
1364
+ };
1365
+ }
1366
+ interface AssetPosition {
1367
+ position: {
1368
+ coin: string;
1369
+ szi: string;
1370
+ entryPx: string;
1371
+ positionValue: string;
1372
+ unrealizedPnl: string;
1373
+ liquidationPx: string | null;
1374
+ marginUsed: string;
1375
+ leverage: {
1376
+ type: string;
1377
+ value: string;
1378
+ } | null;
1379
+ };
1380
+ }
1381
+ interface HyperliquidFill {
1382
+ coin: string;
1383
+ px: string;
1384
+ sz: string;
1385
+ side: 'B' | 'A';
1386
+ time: number;
1387
+ startPosition: string;
1388
+ dir: string;
1389
+ closedPnl: string;
1390
+ hash: string;
1391
+ oid: number;
1392
+ crossed: boolean;
1393
+ fee: string;
1394
+ tid: number;
1395
+ builderFee?: string;
1396
+ liquidation?: boolean;
1397
+ }
1398
+ interface HyperliquidOrder {
1399
+ coin: string;
1400
+ side: 'B' | 'A';
1401
+ limitPx: string;
1402
+ sz: string;
1403
+ oid: number;
1404
+ timestamp: number;
1405
+ origSz: string;
1406
+ cloid: string | null;
1407
+ }
1408
+ interface HyperliquidFunding {
1409
+ time: number;
1410
+ coin: string;
1411
+ usdc: string;
1412
+ szi: string;
1413
+ fundingRate: string;
1414
+ }
1415
+ interface L2Book {
1416
+ coin: string;
1417
+ levels: Array<Array<{
1418
+ px: string;
1419
+ sz: string;
1420
+ n: number;
1421
+ }>>;
1422
+ time: number;
1423
+ }
1424
+
1425
+ /**
1426
+ * Hyperliquid EIP-712 Signer
1427
+ *
1428
+ * Handles EIP-712 signing for Hyperliquid L1 actions (orders, cancels, transfers).
1429
+ * Uses viem's signTypedData for compatibility with our existing wallet infrastructure.
1430
+ *
1431
+ * Key details:
1432
+ * - Domain chainId is ALWAYS 42161 (Arbitrum), regardless of user's actual chain
1433
+ * - Nonces are timestamp-based (milliseconds), NOT sequential
1434
+ * - Hyperliquid stores the 100 highest nonces per address
1435
+ */
1436
+
1437
+ /** Hyperliquid's fixed EIP-712 domain (never changes) */
1438
+ declare const HYPERLIQUID_DOMAIN: {
1439
+ readonly name: "HyperliquidSignTransaction";
1440
+ readonly version: "1";
1441
+ readonly chainId: 42161n;
1442
+ readonly verifyingContract: `0x${string}`;
1443
+ };
1444
+ /**
1445
+ * Generate a timestamp-based nonce.
1446
+ * Ensures strictly increasing nonces even when called in rapid succession.
1447
+ */
1448
+ declare function getNextNonce(): bigint;
1449
+ declare class HyperliquidSigner {
1450
+ private readonly walletClient;
1451
+ constructor(walletClient: WalletClient);
1452
+ /**
1453
+ * Sign an exchange action (order, cancel, etc.)
1454
+ *
1455
+ * @param action - The action object (will be JSON-serialized)
1456
+ * @param nonce - Nonce (defaults to current timestamp)
1457
+ * @returns Signature hex string
1458
+ */
1459
+ signAction(action: Record<string, unknown>, nonce?: bigint): Promise<{
1460
+ signature: `0x${string}`;
1461
+ nonce: bigint;
1462
+ }>;
1463
+ /**
1464
+ * Sign a user-level approval action (approve builder fee, approve agent).
1465
+ * These use the same EIP-712 structure but with different action payloads.
1466
+ */
1467
+ signApproval(action: Record<string, unknown>, nonce?: bigint): Promise<{
1468
+ signature: `0x${string}`;
1469
+ nonce: bigint;
1470
+ }>;
1471
+ /**
1472
+ * Get the signer's address
1473
+ */
1474
+ getAddress(): `0x${string}`;
1475
+ }
1476
+ /**
1477
+ * Convert a Hyperliquid fill hash to a bytes32 fill ID for on-chain recording.
1478
+ * Uses keccak256 to ensure consistent 32-byte output.
1479
+ */
1480
+ declare function fillHashToBytes32(fillHash: string): `0x${string}`;
1481
+ /**
1482
+ * Convert a fill OID to a bytes32 fill ID (fallback if no hash available).
1483
+ */
1484
+ declare function fillOidToBytes32(oid: number): `0x${string}`;
1485
+
1486
+ /**
1487
+ * Hyperliquid Order Management
1488
+ *
1489
+ * Handles order placement, cancellation, and leverage updates on Hyperliquid L1.
1490
+ * All orders include builder fee for monetization.
1491
+ * Fills are recorded on Base via the recorder module.
1492
+ */
1493
+
1494
+ declare class OrderManager {
1495
+ private readonly client;
1496
+ private readonly signer;
1497
+ private readonly config;
1498
+ constructor(client: HyperliquidClient, signer: HyperliquidSigner, config: PerpConfig);
1499
+ /**
1500
+ * Place an order on Hyperliquid from a trade signal.
1501
+ * Attaches builder fee for revenue collection.
1502
+ */
1503
+ placeOrder(signal: PerpTradeSignal): Promise<OrderResult>;
1504
+ /**
1505
+ * Cancel an open order by ID.
1506
+ */
1507
+ cancelOrder(instrument: string, orderId: number): Promise<boolean>;
1508
+ /**
1509
+ * Close an entire position for an instrument.
1510
+ * Uses a market order with reduceOnly flag.
1511
+ */
1512
+ closePosition(instrument: string, positionSize: number): Promise<OrderResult>;
1513
+ /**
1514
+ * Update leverage for an instrument.
1515
+ */
1516
+ updateLeverage(instrument: string, leverage: number, isCross?: boolean): Promise<boolean>;
1517
+ /**
1518
+ * Get a market price string for IOC orders.
1519
+ * Uses a generous slippage buffer to ensure fills.
1520
+ */
1521
+ private getMarketPrice;
1522
+ /**
1523
+ * Parse Hyperliquid exchange response into OrderResult.
1524
+ */
1525
+ private parseOrderResponse;
1526
+ /**
1527
+ * Send a signed request to the Hyperliquid Exchange API.
1528
+ */
1529
+ private exchangeRequest;
1530
+ }
1531
+
1532
+ /**
1533
+ * Hyperliquid Position Tracking
1534
+ *
1535
+ * Provides high-level position management, account summary,
1536
+ * and liquidation proximity monitoring.
1537
+ */
1538
+
1539
+ declare class PositionManager {
1540
+ private readonly client;
1541
+ private readonly userAddress;
1542
+ /** Cached positions (updated each cycle) */
1543
+ private cachedPositions;
1544
+ private cachedAccount;
1545
+ private lastRefreshAt;
1546
+ /** Cache TTL in ms (5 seconds — positions refresh each cycle anyway) */
1547
+ private readonly cacheTtlMs;
1548
+ constructor(client: HyperliquidClient, userAddress: string);
1549
+ /**
1550
+ * Get all open positions. Uses cache if fresh.
1551
+ */
1552
+ getPositions(forceRefresh?: boolean): Promise<PerpPosition[]>;
1553
+ /**
1554
+ * Get a specific position by instrument.
1555
+ * Returns null if no position is open.
1556
+ */
1557
+ getPosition(instrument: string): Promise<PerpPosition | null>;
1558
+ /**
1559
+ * Get account summary (equity, margin, leverage).
1560
+ */
1561
+ getAccountSummary(forceRefresh?: boolean): Promise<AccountSummary>;
1562
+ /**
1563
+ * Get liquidation proximity for all positions.
1564
+ * Returns a value between 0.0 (safe) and 1.0 (at liquidation price).
1565
+ * Values above 0.7 should trigger risk warnings.
1566
+ */
1567
+ getLiquidationProximity(): Promise<Map<string, number>>;
1568
+ /**
1569
+ * Check if any position is dangerously close to liquidation.
1570
+ * Returns instruments with proximity > threshold.
1571
+ */
1572
+ getDangerousPositions(threshold?: number): Promise<PerpPosition[]>;
1573
+ /**
1574
+ * Get total unrealized PnL across all positions.
1575
+ */
1576
+ getTotalUnrealizedPnl(): Promise<number>;
1577
+ /**
1578
+ * Get total notional exposure.
1579
+ */
1580
+ getTotalNotional(): Promise<number>;
1581
+ /**
1582
+ * Get position count.
1583
+ */
1584
+ getPositionCount(): Promise<number>;
1585
+ /**
1586
+ * Force refresh positions and account from Hyperliquid.
1587
+ */
1588
+ refresh(): Promise<void>;
1589
+ /**
1590
+ * Check if cache is still fresh.
1591
+ */
1592
+ private isCacheFresh;
1593
+ }
1594
+
1595
+ /**
1596
+ * Hyperliquid WebSocket Client
1597
+ *
1598
+ * Subscribes to real-time fill and funding events.
1599
+ * Auto-reconnects with exponential backoff.
1600
+ * Checkpoints last processed fill time for REST backfill on reconnect.
1601
+ */
1602
+
1603
+ type FillCallback = (fill: PerpFill) => void;
1604
+ type FundingCallback = (funding: FundingPayment) => void;
1605
+ type LiquidationCallback = (instrument: string, size: number) => void;
1606
+ interface FundingPayment {
1607
+ time: number;
1608
+ coin: string;
1609
+ usdc: string;
1610
+ szi: string;
1611
+ fundingRate: string;
1612
+ }
1613
+ declare class HyperliquidWebSocket {
1614
+ private readonly wsUrl;
1615
+ private readonly userAddress;
1616
+ private readonly client;
1617
+ private ws;
1618
+ private reconnectAttempts;
1619
+ private readonly maxReconnectAttempts;
1620
+ private readonly baseReconnectMs;
1621
+ private readonly maxReconnectMs;
1622
+ private reconnectTimer;
1623
+ private pingTimer;
1624
+ private isConnecting;
1625
+ private shouldReconnect;
1626
+ /** Last processed fill time (ms) — used for REST backfill on reconnect */
1627
+ private lastProcessedFillTime;
1628
+ /** Callbacks */
1629
+ private onFill;
1630
+ private onFunding;
1631
+ private onLiquidation;
1632
+ constructor(config: PerpConfig, userAddress: string, client: HyperliquidClient);
1633
+ /**
1634
+ * Connect to Hyperliquid WebSocket and subscribe to user events.
1635
+ */
1636
+ connect(): Promise<void>;
1637
+ /**
1638
+ * Disconnect and stop reconnecting.
1639
+ */
1640
+ disconnect(): void;
1641
+ /**
1642
+ * Check if WebSocket is connected.
1643
+ */
1644
+ get isConnected(): boolean;
1645
+ /**
1646
+ * Register callback for fill events.
1647
+ */
1648
+ onFillReceived(callback: FillCallback): void;
1649
+ /**
1650
+ * Register callback for funding payment events.
1651
+ */
1652
+ onFundingReceived(callback: FundingCallback): void;
1653
+ /**
1654
+ * Register callback for liquidation events.
1655
+ */
1656
+ onLiquidationDetected(callback: LiquidationCallback): void;
1657
+ /**
1658
+ * Get the last processed fill time (for external checkpoint management).
1659
+ */
1660
+ getLastProcessedFillTime(): number;
1661
+ private handleMessage;
1662
+ private handleFillMessage;
1663
+ private handleFundingMessage;
1664
+ /**
1665
+ * Backfill fills that may have been missed during WebSocket downtime.
1666
+ * Uses the last processed fill time as the starting point.
1667
+ */
1668
+ private backfillMissedFills;
1669
+ private scheduleReconnect;
1670
+ private startPing;
1671
+ private stopPing;
1672
+ private subscribe;
1673
+ }
1674
+
1675
+ /**
1676
+ * Perp Trade Recorder
1677
+ *
1678
+ * Records Hyperliquid perp fills on Base via Router.recordPerpTrade().
1679
+ * This is what makes perp trades visible on the leaderboard and indexer.
1680
+ *
1681
+ * Key details:
1682
+ * - Each fill is individually recorded on-chain
1683
+ * - Fill ID deduplication prevents double-recording (contract enforces)
1684
+ * - Retry queue handles transient failures
1685
+ * - notionalUSD = px * sz * 1e6 (6-decimal)
1686
+ * - feeUSD = fee * 1e6 (6-decimal)
1687
+ */
1688
+
1689
+ declare class PerpTradeRecorder {
1690
+ private readonly publicClient;
1691
+ private readonly walletClient;
1692
+ private readonly account;
1693
+ private readonly agentId;
1694
+ private configHash;
1695
+ /** Retry queue for failed recordings */
1696
+ private retryQueue;
1697
+ /** Set of fill IDs already recorded (or in-progress) to prevent local dups */
1698
+ private recordedFills;
1699
+ /** Timer for processing retry queue */
1700
+ private retryTimer;
1701
+ constructor(opts: {
1702
+ privateKey: `0x${string}`;
1703
+ rpcUrl?: string;
1704
+ agentId: bigint;
1705
+ configHash: `0x${string}`;
1706
+ });
1707
+ /**
1708
+ * Record a fill on-chain.
1709
+ * Converts the Hyperliquid fill into recordPerpTrade params and submits.
1710
+ */
1711
+ recordFill(fill: PerpFill): Promise<{
1712
+ success: boolean;
1713
+ txHash?: string;
1714
+ error?: string;
1715
+ }>;
1716
+ /**
1717
+ * Update the config hash (when epoch changes).
1718
+ */
1719
+ updateConfigHash(configHash: `0x${string}`): void;
1720
+ /**
1721
+ * Get the number of fills pending retry.
1722
+ */
1723
+ get pendingRetries(): number;
1724
+ /**
1725
+ * Get the number of fills recorded (local dedup set size).
1726
+ */
1727
+ get recordedCount(): number;
1728
+ /**
1729
+ * Stop the recorder (clear retry timer).
1730
+ */
1731
+ stop(): void;
1732
+ /**
1733
+ * Submit a recordPerpTrade transaction on Base.
1734
+ */
1735
+ private submitRecord;
1736
+ /**
1737
+ * Process the retry queue — attempt to re-submit failed recordings.
1738
+ */
1739
+ private processRetryQueue;
1740
+ /**
1741
+ * Calculate notional USD from a fill (6-decimal).
1742
+ * notionalUSD = px * sz * 1e6
1743
+ */
1744
+ private calculateNotionalUSD;
1745
+ /**
1746
+ * Calculate fee USD from a fill (6-decimal).
1747
+ * feeUSD = fee * 1e6 (fee is already in USD on Hyperliquid)
1748
+ */
1749
+ private calculateFeeUSD;
1750
+ }
1751
+
1752
+ /**
1753
+ * Hyperliquid Onboarding
1754
+ *
1755
+ * Handles one-time setup tasks for perp trading:
1756
+ * - Builder fee approval (required before orders with builder fee)
1757
+ * - Balance verification
1758
+ * - Risk universe check (perps require universe >= 2)
1759
+ */
1760
+
1761
+ declare class PerpOnboarding {
1762
+ private readonly client;
1763
+ private readonly signer;
1764
+ private readonly config;
1765
+ constructor(client: HyperliquidClient, signer: HyperliquidSigner, config: PerpConfig);
1766
+ /**
1767
+ * Check if the user has approved the builder fee.
1768
+ * Builder fee must be approved before orders can include builder fees.
1769
+ */
1770
+ isBuilderFeeApproved(): Promise<boolean>;
1771
+ /**
1772
+ * Approve the builder fee on Hyperliquid.
1773
+ * This is a one-time approval per builder address.
1774
+ */
1775
+ approveBuilderFee(): Promise<boolean>;
1776
+ /**
1777
+ * Check if the user has sufficient USDC balance on Hyperliquid.
1778
+ * Returns the account equity in USD.
1779
+ */
1780
+ checkBalance(): Promise<{
1781
+ hasBalance: boolean;
1782
+ equity: number;
1783
+ }>;
1784
+ /**
1785
+ * Verify that the agent's risk universe allows perp trading.
1786
+ * Perps require risk universe >= 2 (Derivatives or higher).
1787
+ */
1788
+ verifyRiskUniverse(riskUniverse: number): {
1789
+ allowed: boolean;
1790
+ message: string;
1791
+ };
1792
+ /**
1793
+ * Run all onboarding checks and return status.
1794
+ * Does NOT auto-approve — caller must explicitly approve after review.
1795
+ */
1796
+ checkOnboardingStatus(riskUniverse: number): Promise<OnboardingStatus>;
1797
+ /**
1798
+ * Run full onboarding: check status and auto-approve builder fee if needed.
1799
+ * Returns the final status after all actions.
1800
+ */
1801
+ onboard(riskUniverse: number): Promise<OnboardingStatus>;
1802
+ }
1803
+ interface OnboardingStatus {
1804
+ /** Whether the agent is fully ready for perp trading */
1805
+ ready: boolean;
1806
+ /** Whether risk universe allows perps */
1807
+ riskUniverseOk: boolean;
1808
+ /** Risk universe message */
1809
+ riskUniverseMessage: string;
1810
+ /** Whether user has USDC balance on Hyperliquid */
1811
+ hasBalance: boolean;
1812
+ /** Account equity in USD */
1813
+ equity: number;
1814
+ /** Whether builder fee is approved */
1815
+ builderFeeApproved: boolean;
1816
+ /** Builder address */
1817
+ builderAddress: string;
1818
+ /** Builder fee in bps */
1819
+ builderFeeBps: number;
1820
+ }
1821
+
986
1822
  /**
987
1823
  * Secure Environment Storage
988
1824
  *
@@ -1025,4 +1861,4 @@ declare function decryptEnvFile(encPath: string, passphrase: string): Record<str
1025
1861
  */
1026
1862
  declare function loadSecureEnv(basePath: string, passphrase?: string): boolean;
1027
1863
 
1028
- export { type AgentConfig, AgentConfigSchema, type AgentMode, AgentRuntime, type AgentStatusPayload, AnthropicAdapter, BaseLLMAdapter, type CommandType, DeepSeekAdapter, GoogleAdapter, GroqAdapter, type LLMAdapter, type LLMConfig, LLMConfigSchema, type LLMMessage, type LLMMetadata, type LLMProvider, LLMProviderSchema, type LLMResponse, type MarketData, MarketDataService, type MessageLevel, type MessageType, MistralAdapter, OllamaAdapter, OpenAIAdapter, RelayClient, type RelayCommand, type RelayConfig$1 as RelayConfig, RelayConfigSchema, RiskManager, type RiskUniverse, RiskUniverseSchema, type RuntimeConfig, STRATEGY_TEMPLATES, type StrategyFunction, type StrategyTemplate, TogetherAdapter, TradeExecutor, type TradeSignal, type TradingConfig, TradingConfigSchema, type VaultConfig, VaultConfigSchema, VaultManager, type VaultManagerConfig, type VaultPolicy, VaultPolicySchema, type VaultStatus, createLLMAdapter, createSampleConfig, decryptEnvFile, encryptEnvFile, getAllStrategyTemplates, getStrategyTemplate, loadConfig, loadSecureEnv, loadStrategy, validateConfig, validateStrategy };
1864
+ export { type AccountSummary, type AgentConfig, AgentConfigSchema, type AgentMode, AgentRuntime, type AgentStatusPayload, AnthropicAdapter, BaseLLMAdapter, type CommandType, DeepSeekAdapter, type FillCallback, type FundingCallback, type FundingPayment, GoogleAdapter, GroqAdapter, HYPERLIQUID_DOMAIN, HyperliquidClient, HyperliquidSigner, HyperliquidWebSocket, type LLMAdapter, type LLMConfig, LLMConfigSchema, type LLMMessage, type LLMMetadata, type LLMProvider, LLMProviderSchema, type LLMResponse, type LiquidationCallback, type MarketData, MarketDataService, type MessageLevel, type MessageType, MistralAdapter, OllamaAdapter, type OnboardingStatus, OpenAIAdapter, OrderManager, type OrderResult, type PerpAction, type PerpConfig$1 as PerpConfig, PerpConfigSchema, type PerpFill, type PerpMarketData, PerpOnboarding, type PerpPosition, type PerpStrategyFunction, PerpTradeRecorder, type PerpTradeSignal, type PerpConfig as PerpTradingConfig, PositionManager, type RecordPerpTradeParams, RelayClient, type RelayCommand, type RelayConfig$1 as RelayConfig, RelayConfigSchema, RiskManager, type RiskUniverse, RiskUniverseSchema, type RuntimeConfig, STRATEGY_TEMPLATES, type StrategyFunction, type StrategyTemplate, TogetherAdapter, TradeExecutor, type TradeSignal, type TradingConfig, TradingConfigSchema, type VaultConfig, VaultConfigSchema, VaultManager, type VaultManagerConfig, type VaultPolicy, VaultPolicySchema, type VaultStatus, createLLMAdapter, createSampleConfig, decryptEnvFile, encryptEnvFile, fillHashToBytes32, fillOidToBytes32, getAllStrategyTemplates, getNextNonce, getStrategyTemplate, loadConfig, loadSecureEnv, loadStrategy, validateConfig, validateStrategy };