@exagent/agent 0.3.6 → 0.3.8

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 (69) 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-GYYW4EKM.js +6756 -0
  5. package/dist/chunk-IVA2SCSN.js +6756 -0
  6. package/dist/chunk-JHXCSGPC.js +6352 -0
  7. package/dist/chunk-V6O4UXVN.js +6345 -0
  8. package/dist/chunk-WTECTX2Z.js +6345 -0
  9. package/dist/cli.js +2 -2
  10. package/dist/index.d.ts +24 -2
  11. package/dist/index.js +1 -1
  12. package/package.json +12 -9
  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 -250
  19. package/src/config.ts +0 -502
  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 -94
  31. package/src/llm/together.ts +0 -48
  32. package/src/llm-providers.ts +0 -8
  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 -288
  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 -392
  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 -265
  63. package/src/strategy/templates.ts +0 -74
  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/strategy-loader.test.ts +0 -150
  69. package/tsconfig.json +0 -8
@@ -1,277 +0,0 @@
1
- /**
2
- * Hyperliquid EIP-712 Signer
3
- *
4
- * Signs Hyperliquid L1 actions (orders, cancels, leverage changes)
5
- * using the "phantom agent" pattern:
6
- *
7
- * 1. Serialize action via msgpack (NOT JSON.stringify)
8
- * 2. Hash: keccak256(msgpack(action) + nonce_bytes + vault_marker)
9
- * 3. Sign EIP-712 typed data with domain "Exchange" / chainId 1337
10
- * and type Agent { source: string, connectionId: bytes32 }
11
- *
12
- * This is fundamentally different from user-signed actions (approveAgent,
13
- * withdraw, etc.) which use the "HyperliquidSignTransaction" domain with
14
- * chainId 42161. Those are NOT used for trading.
15
- *
16
- * Nonces are timestamp-based (ms), strictly increasing.
17
- */
18
-
19
- import { type WalletClient, keccak256 } from 'viem';
20
- import { encodeMsgpack, largeIntToBigInt, removeUndefinedKeys, toUint64Bytes } from './msgpack.js';
21
- import type { MsgpackValue } from './msgpack.js';
22
-
23
- // ── EIP-712 DOMAINS ─────────────────────────────────────────
24
-
25
- /**
26
- * L1 Action domain — "Exchange" with chainId 1337.
27
- * Used for trading actions (orders, cancels, leverage) via the phantom agent pattern.
28
- */
29
- export const HYPERLIQUID_DOMAIN = {
30
- name: 'Exchange' as const,
31
- version: '1' as const,
32
- chainId: 1337,
33
- verifyingContract: '0x0000000000000000000000000000000000000000' as `0x${string}`,
34
- } as const;
35
-
36
- /**
37
- * User-signed action domain — "HyperliquidSignTransaction" with chainId 42161 (Arbitrum).
38
- * Used for withdraw3, usdSend, approveAgent, and other non-trading actions.
39
- * These use direct EIP-712 signing (NOT the phantom agent pattern).
40
- */
41
- export const HYPERLIQUID_USER_DOMAIN = {
42
- name: 'HyperliquidSignTransaction' as const,
43
- version: '1' as const,
44
- chainId: 42161,
45
- verifyingContract: '0x0000000000000000000000000000000000000000' as `0x${string}`,
46
- } as const;
47
-
48
- /** EIP-712 types for Hyperliquid user-signed actions */
49
- export const USER_ACTION_TYPES = {
50
- withdraw: {
51
- 'HyperliquidTransaction:Withdraw': [
52
- { name: 'hyperliquidChain', type: 'string' },
53
- { name: 'destination', type: 'string' },
54
- { name: 'amount', type: 'string' },
55
- { name: 'time', type: 'uint64' },
56
- ],
57
- },
58
- usdSend: {
59
- 'HyperliquidTransaction:UsdSend': [
60
- { name: 'hyperliquidChain', type: 'string' },
61
- { name: 'destination', type: 'string' },
62
- { name: 'amount', type: 'string' },
63
- { name: 'time', type: 'uint64' },
64
- ],
65
- },
66
- } as const;
67
-
68
- const PHANTOM_AGENT_TYPES = {
69
- Agent: [
70
- { name: 'source', type: 'string' },
71
- { name: 'connectionId', type: 'bytes32' },
72
- ],
73
- } as const;
74
-
75
- // ── NONCE ────────────────────────────────────────────────────
76
-
77
- let lastNonce = 0n;
78
-
79
- export function getNextNonce(): bigint {
80
- const now = BigInt(Date.now());
81
- if (now <= lastNonce) {
82
- lastNonce = lastNonce + 1n;
83
- } else {
84
- lastNonce = now;
85
- }
86
- return lastNonce;
87
- }
88
-
89
- // ── L1 ACTION HASH ──────────────────────────────────────────
90
-
91
- /**
92
- * Create the L1 action hash for the phantom agent pattern.
93
- *
94
- * Hash = keccak256(
95
- * msgpack(action) +
96
- * nonce_as_uint64_be +
97
- * vault_marker(0x00 or 0x01 + address_bytes)
98
- * )
99
- */
100
- export function createL1ActionHash(args: {
101
- action: Record<string, unknown> | unknown[];
102
- nonce: number;
103
- vaultAddress?: `0x${string}`;
104
- }): `0x${string}` {
105
- const { action, nonce, vaultAddress } = args;
106
-
107
- // 1. Encode action as msgpack (with large int → BigInt conversion)
108
- const cleaned = removeUndefinedKeys(action as MsgpackValue);
109
- const withBigInts = largeIntToBigInt(cleaned);
110
- const actionBytes = encodeMsgpack(withBigInts);
111
-
112
- // 2. Nonce as big-endian uint64
113
- const nonceBytes = toUint64Bytes(nonce);
114
-
115
- // 3. Vault address marker
116
- const vaultMarker = vaultAddress
117
- ? new Uint8Array([1])
118
- : new Uint8Array([0]);
119
- const vaultBytes = vaultAddress
120
- ? hexToBytes(vaultAddress.slice(2))
121
- : new Uint8Array();
122
-
123
- // 4. Concatenate all bytes and keccak256
124
- const bytes = concatBytes(actionBytes, nonceBytes, vaultMarker, vaultBytes);
125
- return keccak256(bytes);
126
- }
127
-
128
- // ── SIGNER ───────────────────────────────────────────────────
129
-
130
- export class HyperliquidSigner {
131
- private readonly isTestnet: boolean;
132
-
133
- constructor(
134
- private readonly walletClient: WalletClient,
135
- isTestnet = false,
136
- ) {
137
- this.isTestnet = isTestnet;
138
- }
139
-
140
- /**
141
- * Sign an L1 action (order, cancel, updateLeverage, etc.)
142
- * using the phantom agent pattern.
143
- */
144
- async signAction(
145
- action: Record<string, unknown>,
146
- nonce?: bigint,
147
- vaultAddress?: `0x${string}`,
148
- ): Promise<{ signature: `0x${string}`; nonce: bigint }> {
149
- const actionNonce = nonce ?? getNextNonce();
150
- const nonceNumber = Number(actionNonce);
151
-
152
- const account = this.walletClient.account;
153
- if (!account) throw new Error('Wallet client has no account');
154
-
155
- // Compute the L1 action hash (msgpack + keccak256)
156
- const connectionId = createL1ActionHash({
157
- action,
158
- nonce: nonceNumber,
159
- vaultAddress,
160
- });
161
-
162
- // Sign the phantom agent message
163
- const signature = await this.walletClient.signTypedData({
164
- account,
165
- domain: HYPERLIQUID_DOMAIN,
166
- types: PHANTOM_AGENT_TYPES,
167
- primaryType: 'Agent' as const,
168
- message: {
169
- source: this.isTestnet ? 'b' : 'a',
170
- connectionId,
171
- },
172
- });
173
-
174
- return { signature, nonce: actionNonce };
175
- }
176
-
177
- /**
178
- * Sign a user-signed action (withdraw3, usdSend, approveAgent, etc.)
179
- * using the HyperliquidSignTransaction domain (chainId 42161).
180
- *
181
- * Unlike trading actions, these use direct EIP-712 typed data signing
182
- * with action-specific types — NOT the phantom agent pattern.
183
- */
184
- async signUserAction(
185
- actionType: keyof typeof USER_ACTION_TYPES,
186
- message: Record<string, unknown>,
187
- ): Promise<{ signature: `0x${string}` }> {
188
- const account = this.walletClient.account;
189
- if (!account) throw new Error('Wallet client has no account');
190
-
191
- const types = USER_ACTION_TYPES[actionType];
192
- const primaryType = Object.keys(types)[0] as string;
193
-
194
- const signature = await this.walletClient.signTypedData({
195
- account,
196
- domain: HYPERLIQUID_USER_DOMAIN,
197
- types: types as Record<string, readonly { name: string; type: string }[]>,
198
- primaryType,
199
- message,
200
- });
201
-
202
- return { signature };
203
- }
204
-
205
- /**
206
- * Build and sign a withdraw3 action for withdrawing USDC from Hyperliquid to Arbitrum.
207
- * Returns the complete payload ready to POST to /exchange.
208
- *
209
- * @param destination — The Arbitrum address to receive USDC
210
- * @param amount — Amount as string (e.g., "10.0" for $10)
211
- */
212
- async signWithdraw(
213
- destination: `0x${string}`,
214
- amount: string,
215
- ): Promise<{
216
- action: Record<string, unknown>;
217
- signature: { r: string; s: string; v: number };
218
- nonce: number;
219
- }> {
220
- const timestamp = Date.now();
221
-
222
- const message = {
223
- hyperliquidChain: this.isTestnet ? 'Testnet' : 'Mainnet',
224
- destination,
225
- amount,
226
- time: BigInt(timestamp),
227
- };
228
-
229
- const { signature } = await this.signUserAction('withdraw', message);
230
-
231
- const action = {
232
- type: 'withdraw3',
233
- hyperliquidChain: this.isTestnet ? 'Testnet' : 'Mainnet',
234
- signatureChainId: '0xa4b1', // Arbitrum chainId in hex
235
- destination,
236
- amount,
237
- time: timestamp,
238
- };
239
-
240
- return {
241
- action,
242
- signature: {
243
- r: signature.slice(0, 66),
244
- s: `0x${signature.slice(66, 130)}`,
245
- v: parseInt(signature.slice(130, 132), 16),
246
- },
247
- nonce: timestamp,
248
- };
249
- }
250
-
251
- getAddress(): `0x${string}` {
252
- const account = this.walletClient.account;
253
- if (!account) throw new Error('Wallet client has no account');
254
- return account.address;
255
- }
256
- }
257
-
258
- // ── PRIVATE HELPERS ─────────────────────────────────────────
259
-
260
- function hexToBytes(hex: string): Uint8Array {
261
- const bytes = new Uint8Array(hex.length / 2);
262
- for (let i = 0; i < bytes.length; i++) {
263
- bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
264
- }
265
- return bytes;
266
- }
267
-
268
- function concatBytes(...arrays: Uint8Array[]): Uint8Array {
269
- const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
270
- const result = new Uint8Array(totalLength);
271
- let offset = 0;
272
- for (const arr of arrays) {
273
- result.set(arr, offset);
274
- offset += arr.length;
275
- }
276
- return result;
277
- }
package/src/perp/types.ts DELETED
@@ -1,192 +0,0 @@
1
- /**
2
- * Hyperliquid Perp Trading Types
3
- *
4
- * Core type definitions for perp trading via Hyperliquid L1.
5
- * Fills are reported to the command center via WebSocket relay — no on-chain recording.
6
- */
7
-
8
- // ============================================================
9
- // CONFIG
10
- // ============================================================
11
-
12
- export interface PerpConfig {
13
- enabled: boolean;
14
- apiUrl: string;
15
- wsUrl: string;
16
- maxLeverage: number;
17
- maxNotionalUSD: number;
18
- allowedInstruments?: string[];
19
- }
20
-
21
- export const DEFAULT_PERP_CONFIG: PerpConfig = {
22
- enabled: false,
23
- apiUrl: 'https://api.hyperliquid.xyz',
24
- wsUrl: 'wss://api.hyperliquid.xyz/ws',
25
- maxLeverage: 10,
26
- maxNotionalUSD: 50_000,
27
- };
28
-
29
- // ============================================================
30
- // SIGNALS
31
- // ============================================================
32
-
33
- export type PerpAction =
34
- | 'open_long'
35
- | 'open_short'
36
- | 'close_long'
37
- | 'close_short'
38
- | 'hold';
39
-
40
- export interface PerpTradeSignal {
41
- action: PerpAction;
42
- instrument: string;
43
- size: number;
44
- price: number;
45
- leverage: number;
46
- orderType: 'limit' | 'market';
47
- reduceOnly: boolean;
48
- confidence: number;
49
- reasoning?: string;
50
- }
51
-
52
- // ============================================================
53
- // POSITIONS & ACCOUNT
54
- // ============================================================
55
-
56
- export interface PerpPosition {
57
- instrument: string;
58
- assetIndex: number;
59
- /** Positive = long, negative = short */
60
- size: number;
61
- entryPrice: number;
62
- markPrice: number;
63
- unrealizedPnl: number;
64
- leverage: number;
65
- marginType: 'cross' | 'isolated';
66
- liquidationPrice: number;
67
- notionalUSD: number;
68
- marginUsed: number;
69
- }
70
-
71
- export interface AccountSummary {
72
- totalEquity: number;
73
- availableMargin: number;
74
- totalMarginUsed: number;
75
- totalUnrealizedPnl: number;
76
- totalNotional: number;
77
- maintenanceMargin: number;
78
- effectiveLeverage: number;
79
- cashBalance: number;
80
- }
81
-
82
- // ============================================================
83
- // FILLS & MARKET DATA
84
- // ============================================================
85
-
86
- export interface PerpFill {
87
- oid: number;
88
- coin: string;
89
- /** B = buy (long), A = ask/sell (short) */
90
- side: 'B' | 'A';
91
- px: string;
92
- sz: string;
93
- fee: string;
94
- time: number;
95
- hash: string;
96
- isMaker: boolean;
97
- builderFee?: string;
98
- liquidation?: boolean;
99
- }
100
-
101
- export interface PerpMarketData {
102
- instrument: string;
103
- midPrice: number;
104
- bestBid: number;
105
- bestAsk: number;
106
- funding8h: number;
107
- openInterest: number;
108
- volume24h: number;
109
- priceChange24h: number;
110
- }
111
-
112
- // ============================================================
113
- // ORDER RESULTS
114
- // ============================================================
115
-
116
- export interface OrderResult {
117
- success: boolean;
118
- orderId?: number;
119
- status: 'filled' | 'resting' | 'error';
120
- avgPrice?: string;
121
- filledSize?: string;
122
- error?: string;
123
- }
124
-
125
- // ============================================================
126
- // RAW HYPERLIQUID API TYPES
127
- // ============================================================
128
-
129
- export interface AssetMeta {
130
- name: string;
131
- szDecimals: number;
132
- maxLeverage: number;
133
- onlyIsolated: boolean;
134
- }
135
-
136
- export interface ClearinghouseState {
137
- assetPositions: AssetPosition[];
138
- crossMarginSummary: {
139
- accountValue: string;
140
- totalNtlPos: string;
141
- totalRawUsd: string;
142
- totalMarginUsed: string;
143
- };
144
- }
145
-
146
- export interface AssetPosition {
147
- position: {
148
- coin: string;
149
- szi: string;
150
- entryPx: string;
151
- positionValue: string;
152
- unrealizedPnl: string;
153
- liquidationPx: string | null;
154
- marginUsed: string;
155
- leverage: { type: string; value: string } | null;
156
- };
157
- }
158
-
159
- export interface HyperliquidFill {
160
- coin: string;
161
- px: string;
162
- sz: string;
163
- side: 'B' | 'A';
164
- time: number;
165
- startPosition: string;
166
- dir: string;
167
- closedPnl: string;
168
- hash: string;
169
- oid: number;
170
- crossed: boolean;
171
- fee: string;
172
- tid: number;
173
- builderFee?: string;
174
- liquidation?: boolean;
175
- }
176
-
177
- export interface HyperliquidOrder {
178
- coin: string;
179
- side: 'B' | 'A';
180
- limitPx: string;
181
- sz: string;
182
- oid: number;
183
- timestamp: number;
184
- origSz: string;
185
- cloid: string | null;
186
- }
187
-
188
- export interface L2Book {
189
- coin: string;
190
- levels: Array<Array<{ px: string; sz: string; n: number }>>;
191
- time: number;
192
- }