@exagent/agent 0.3.4 → 0.3.6
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/{chunk-WTECTX2Z.js → chunk-ZRAOPQQW.js} +208 -147
- package/dist/cli.js +57 -37
- package/dist/index.js +1 -1
- package/package.json +18 -18
- package/src/cli.ts +32 -23
- package/src/config.ts +6 -3
- package/src/llm/anthropic.ts +3 -3
- package/src/llm/deepseek.ts +3 -3
- package/src/llm/google.ts +3 -3
- package/src/llm/groq.ts +3 -3
- package/src/llm/mistral.ts +3 -3
- package/src/llm/ollama.ts +3 -3
- package/src/llm/openai.ts +46 -3
- package/src/llm/together.ts +3 -3
- package/src/llm-providers.ts +8 -0
- package/src/prediction/client.ts +11 -4
- package/src/runtime.ts +3 -3
- package/src/setup.ts +29 -20
- package/src/strategy/loader.ts +136 -62
- package/src/strategy/templates.ts +0 -51
- package/test/strategy-loader.test.ts +150 -0
- package/.turbo/turbo-build.log +0 -17
- package/test-bridge-arb-to-base.mjs +0 -223
- package/test-funded-check.mjs +0 -79
- package/test-funded-phase19.mjs +0 -933
- package/test-hl-deposit-recover.mjs +0 -281
- package/test-hl-withdraw.mjs +0 -372
- package/test-live-signing.mjs +0 -374
- package/test-phase7.mjs +0 -416
- package/test-recover-arb.mjs +0 -206
- package/test-spot-bridge.mjs +0 -248
- package/test-wallet-setup.mjs +0 -126
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fix the Arb → Base bridge issue (InvalidQuoteTimestamp).
|
|
3
|
-
*
|
|
4
|
-
* Root cause: The Across SpokePool's depositQuoteTimeBuffer is tight.
|
|
5
|
-
* If there's any delay between getting the fee quote and submitting the tx,
|
|
6
|
-
* the quoteTimestamp becomes stale and the tx reverts.
|
|
7
|
-
*
|
|
8
|
-
* Fix: Do approval BEFORE getting the quote, then submit IMMEDIATELY after.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
createPublicClient,
|
|
13
|
-
createWalletClient,
|
|
14
|
-
http,
|
|
15
|
-
formatUnits,
|
|
16
|
-
formatEther,
|
|
17
|
-
parseEther,
|
|
18
|
-
maxUint256,
|
|
19
|
-
} from 'viem';
|
|
20
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
21
|
-
import { base, arbitrum } from 'viem/chains';
|
|
22
|
-
|
|
23
|
-
const DEPLOYER_KEY = '0x0991f4e17be491bb11f4cf1d079db1771fe669e2b0d735f2b3ffc0e32d230ac9';
|
|
24
|
-
const TEST_KEY = '0xb027d931f6c8b4b2681451716981432130806f01ff87001c74412b504b810dbe';
|
|
25
|
-
|
|
26
|
-
const deployer = privateKeyToAccount(DEPLOYER_KEY);
|
|
27
|
-
const testWallet = privateKeyToAccount(TEST_KEY);
|
|
28
|
-
|
|
29
|
-
const arbPublic = createPublicClient({ chain: arbitrum, transport: http('https://arb1.arbitrum.io/rpc') });
|
|
30
|
-
const arbDeployerWallet = createWalletClient({ account: deployer, chain: arbitrum, transport: http('https://arb1.arbitrum.io/rpc') });
|
|
31
|
-
const arbTestWallet = createWalletClient({ account: testWallet, chain: arbitrum, transport: http('https://arb1.arbitrum.io/rpc') });
|
|
32
|
-
|
|
33
|
-
const basePublic = createPublicClient({ chain: base, transport: http('https://mainnet.base.org') });
|
|
34
|
-
const baseTestWallet = createWalletClient({ account: testWallet, chain: base, transport: http('https://mainnet.base.org') });
|
|
35
|
-
|
|
36
|
-
const USDC_ARB = '0xaf88d065e77c8cC2239327C5EDb3A432268e5831';
|
|
37
|
-
const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
|
|
38
|
-
const ACROSS_SPOKE_ARB = '0xe35e9842fceaCA96570B734083f4a58e8F7C5f2A';
|
|
39
|
-
|
|
40
|
-
const ERC20_ABI = [
|
|
41
|
-
{ type: 'function', name: 'transfer', inputs: [{name:'to',type:'address'},{name:'amount',type:'uint256'}], outputs: [{type:'bool'}], stateMutability: 'nonpayable' },
|
|
42
|
-
{ type: 'function', name: 'balanceOf', inputs: [{name:'account',type:'address'}], outputs: [{type:'uint256'}], stateMutability: 'view' },
|
|
43
|
-
{ type: 'function', name: 'approve', inputs: [{name:'spender',type:'address'},{name:'amount',type:'uint256'}], outputs: [{type:'bool'}], stateMutability: 'nonpayable' },
|
|
44
|
-
{ type: 'function', name: 'allowance', inputs: [{name:'owner',type:'address'},{name:'spender',type:'address'}], outputs: [{type:'uint256'}], stateMutability: 'view' },
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
const ACROSS_SPOKE_ABI = [
|
|
48
|
-
{
|
|
49
|
-
type: 'function', name: 'depositV3',
|
|
50
|
-
inputs: [
|
|
51
|
-
{ name: 'depositor', type: 'address' }, { name: 'recipient', type: 'address' },
|
|
52
|
-
{ name: 'inputToken', type: 'address' }, { name: 'outputToken', type: 'address' },
|
|
53
|
-
{ name: 'inputAmount', type: 'uint256' }, { name: 'outputAmount', type: 'uint256' },
|
|
54
|
-
{ name: 'destinationChainId', type: 'uint256' },
|
|
55
|
-
{ name: 'exclusiveRelayer', type: 'address' },
|
|
56
|
-
{ name: 'quoteTimestamp', type: 'uint32' }, { name: 'fillDeadline', type: 'uint32' },
|
|
57
|
-
{ name: 'exclusivityDeadline', type: 'uint32' }, { name: 'message', type: 'bytes' },
|
|
58
|
-
],
|
|
59
|
-
outputs: [],
|
|
60
|
-
stateMutability: 'payable',
|
|
61
|
-
},
|
|
62
|
-
];
|
|
63
|
-
|
|
64
|
-
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
65
|
-
|
|
66
|
-
async function waitForTx(client, hash, label) {
|
|
67
|
-
console.log(` ⏳ ${label}: tx ${hash.slice(0, 10)}...`);
|
|
68
|
-
const receipt = await client.waitForTransactionReceipt({ hash, timeout: 120_000 });
|
|
69
|
-
if (receipt.status === 'reverted') throw new Error(`${label} REVERTED: ${hash}`);
|
|
70
|
-
console.log(` ✅ ${label}: confirmed (gas: ${receipt.gasUsed})`);
|
|
71
|
-
return receipt;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// ═══ Step 1: Fund deployer with ETH on Arb (from test wallet) ═══
|
|
75
|
-
console.log('═══ Step 1: Give deployer ETH on Arb for gas ═══');
|
|
76
|
-
|
|
77
|
-
const deployerArbEth = await arbPublic.getBalance({ address: deployer.address });
|
|
78
|
-
if (deployerArbEth < parseEther('0.0003')) {
|
|
79
|
-
console.log(' Sending 0.0005 ETH from test wallet to deployer on Arb...');
|
|
80
|
-
const h = await arbTestWallet.sendTransaction({
|
|
81
|
-
to: deployer.address,
|
|
82
|
-
value: parseEther('0.0005'),
|
|
83
|
-
});
|
|
84
|
-
await waitForTx(arbPublic, h, 'ETH to deployer');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// ═══ Step 2: Deployer sends USDC to test wallet ═══
|
|
88
|
-
console.log('\n═══ Step 2: Deployer sends USDC to test wallet on Arb ═══');
|
|
89
|
-
|
|
90
|
-
const deployerUsdc = await arbPublic.readContract({ address: USDC_ARB, abi: ERC20_ABI, functionName: 'balanceOf', args: [deployer.address] });
|
|
91
|
-
console.log(` Deployer USDC: ${formatUnits(deployerUsdc, 6)}`);
|
|
92
|
-
|
|
93
|
-
if (deployerUsdc > 0n) {
|
|
94
|
-
const h = await arbDeployerWallet.writeContract({
|
|
95
|
-
address: USDC_ARB, abi: ERC20_ABI, functionName: 'transfer',
|
|
96
|
-
args: [testWallet.address, deployerUsdc],
|
|
97
|
-
});
|
|
98
|
-
await waitForTx(arbPublic, h, 'USDC to test wallet');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const testUsdc = await arbPublic.readContract({ address: USDC_ARB, abi: ERC20_ABI, functionName: 'balanceOf', args: [testWallet.address] });
|
|
102
|
-
console.log(` Test wallet USDC: ${formatUnits(testUsdc, 6)}`);
|
|
103
|
-
|
|
104
|
-
// ═══ Step 3: Pre-approve USDC to Across SpokePool (BEFORE getting quote) ═══
|
|
105
|
-
console.log('\n═══ Step 3: Pre-approve USDC to Across ═══');
|
|
106
|
-
|
|
107
|
-
const allowance = await arbPublic.readContract({
|
|
108
|
-
address: USDC_ARB, abi: ERC20_ABI, functionName: 'allowance',
|
|
109
|
-
args: [testWallet.address, ACROSS_SPOKE_ARB],
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
if (allowance < testUsdc) {
|
|
113
|
-
const h = await arbTestWallet.writeContract({
|
|
114
|
-
address: USDC_ARB, abi: ERC20_ABI, functionName: 'approve',
|
|
115
|
-
args: [ACROSS_SPOKE_ARB, maxUint256],
|
|
116
|
-
});
|
|
117
|
-
await waitForTx(arbPublic, h, 'Approve Across');
|
|
118
|
-
} else {
|
|
119
|
-
console.log(' Already approved');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// ═══ Step 4: Get quote + submit bridge IMMEDIATELY (no delays!) ═══
|
|
123
|
-
console.log('\n═══ Step 4: Bridge USDC Arb → Base (quote + submit together) ═══');
|
|
124
|
-
|
|
125
|
-
const bridgeAmount = testUsdc;
|
|
126
|
-
console.log(` Bridging ${formatUnits(bridgeAmount, 6)} USDC...`);
|
|
127
|
-
|
|
128
|
-
// Get fee quote
|
|
129
|
-
const params = new URLSearchParams({
|
|
130
|
-
inputToken: USDC_ARB,
|
|
131
|
-
outputToken: USDC_BASE,
|
|
132
|
-
originChainId: '42161',
|
|
133
|
-
destinationChainId: '8453',
|
|
134
|
-
amount: bridgeAmount.toString(),
|
|
135
|
-
recipient: testWallet.address,
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
const feeRes = await fetch(`https://app.across.to/api/suggested-fees?${params}`);
|
|
139
|
-
if (!feeRes.ok) {
|
|
140
|
-
console.log(` ❌ Fee API error: ${await feeRes.text()}`);
|
|
141
|
-
process.exit(1);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const feeData = await feeRes.json();
|
|
145
|
-
|
|
146
|
-
if (feeData.isAmountTooLow) {
|
|
147
|
-
console.log(' ❌ Amount too low for bridge');
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const outputAmount = BigInt(bridgeAmount) - BigInt(feeData.totalRelayFee.total);
|
|
152
|
-
const quoteTimestamp = parseInt(feeData.timestamp);
|
|
153
|
-
const fillDeadline = Math.floor(Date.now() / 1000) + 21600;
|
|
154
|
-
|
|
155
|
-
console.log(` Quote timestamp: ${quoteTimestamp}`);
|
|
156
|
-
console.log(` Output: ${formatUnits(outputAmount, 6)} USDC`);
|
|
157
|
-
|
|
158
|
-
// IMMEDIATELY submit — no awaits between quote and this call!
|
|
159
|
-
console.log(' Submitting depositV3 IMMEDIATELY...');
|
|
160
|
-
const bridgeHash = await arbTestWallet.writeContract({
|
|
161
|
-
address: ACROSS_SPOKE_ARB,
|
|
162
|
-
abi: ACROSS_SPOKE_ABI,
|
|
163
|
-
functionName: 'depositV3',
|
|
164
|
-
args: [
|
|
165
|
-
testWallet.address, testWallet.address,
|
|
166
|
-
USDC_ARB, USDC_BASE,
|
|
167
|
-
bridgeAmount, outputAmount,
|
|
168
|
-
8453n,
|
|
169
|
-
'0x0000000000000000000000000000000000000000',
|
|
170
|
-
quoteTimestamp, fillDeadline, 0, '0x',
|
|
171
|
-
],
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
await waitForTx(arbPublic, bridgeHash, 'Arb→Base bridge');
|
|
175
|
-
|
|
176
|
-
// Poll for fill
|
|
177
|
-
console.log(' Polling for fill...');
|
|
178
|
-
for (let i = 0; i < 60; i++) {
|
|
179
|
-
await sleep(2000);
|
|
180
|
-
try {
|
|
181
|
-
const sRes = await fetch(`https://app.across.to/api/deposit/status?depositTxHash=${bridgeHash}&originChainId=42161`);
|
|
182
|
-
if (sRes.ok) {
|
|
183
|
-
const s = await sRes.json();
|
|
184
|
-
if (s.status === 'filled') { console.log(' ✅ Bridge filled!'); break; }
|
|
185
|
-
if (i % 5 === 0) console.log(` ... ${s.status} (${i*2}s)`);
|
|
186
|
-
}
|
|
187
|
-
} catch {}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
await sleep(3000);
|
|
191
|
-
|
|
192
|
-
// ═══ Step 5: Return all funds to deployer on Base ═══
|
|
193
|
-
console.log('\n═══ Step 5: Return funds to deployer ═══');
|
|
194
|
-
|
|
195
|
-
const baseUsdc = await basePublic.readContract({ address: USDC_BASE, abi: ERC20_ABI, functionName: 'balanceOf', args: [testWallet.address] });
|
|
196
|
-
if (baseUsdc > 0n) {
|
|
197
|
-
console.log(` Returning ${formatUnits(baseUsdc, 6)} USDC...`);
|
|
198
|
-
const h = await baseTestWallet.writeContract({
|
|
199
|
-
address: USDC_BASE, abi: ERC20_ABI, functionName: 'transfer',
|
|
200
|
-
args: [deployer.address, baseUsdc],
|
|
201
|
-
});
|
|
202
|
-
await waitForTx(basePublic, h, 'Return USDC');
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Return remaining Base ETH
|
|
206
|
-
const baseEth = await basePublic.getBalance({ address: testWallet.address });
|
|
207
|
-
if (baseEth > 200000000000000n) {
|
|
208
|
-
const returnEth = baseEth - 100000000000000n;
|
|
209
|
-
const h = await baseTestWallet.sendTransaction({ to: deployer.address, value: returnEth });
|
|
210
|
-
await waitForTx(basePublic, h, 'Return ETH');
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Final report
|
|
214
|
-
console.log('\n═══ Final Deployer Balance ═══');
|
|
215
|
-
const dEth = await basePublic.getBalance({ address: deployer.address });
|
|
216
|
-
const dUsdc = await basePublic.readContract({ address: USDC_BASE, abi: ERC20_ABI, functionName: 'balanceOf', args: [deployer.address] });
|
|
217
|
-
console.log(` Base: ${formatEther(dEth)} ETH, ${formatUnits(dUsdc, 6)} USDC`);
|
|
218
|
-
|
|
219
|
-
const dArbUsdc = await arbPublic.readContract({ address: USDC_ARB, abi: ERC20_ABI, functionName: 'balanceOf', args: [deployer.address] });
|
|
220
|
-
const dArbEth = await arbPublic.getBalance({ address: deployer.address });
|
|
221
|
-
console.log(` Arb: ${formatEther(dArbEth)} ETH, ${formatUnits(dArbUsdc, 6)} USDC`);
|
|
222
|
-
|
|
223
|
-
console.log('\nDone!');
|
package/test-funded-check.mjs
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check deployer and test wallet balances before funded tests.
|
|
3
|
-
* Read-only — no transactions.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { createPublicClient, http, formatEther, formatUnits } from 'viem';
|
|
7
|
-
import { base, arbitrum, polygon } from 'viem/chains';
|
|
8
|
-
|
|
9
|
-
const DEPLOYER = '0x1374Ee64A05011877660fD53A0D757B65Cbc73ce';
|
|
10
|
-
const TEST_WALLET_1 = '0xf5C450448E531162141e69c70F9D8cfA637604F4';
|
|
11
|
-
|
|
12
|
-
const ERC20_ABI = [
|
|
13
|
-
{ type: 'function', name: 'balanceOf', inputs: [{ name: 'account', type: 'address' }], outputs: [{ type: 'uint256' }], stateMutability: 'view' },
|
|
14
|
-
{ type: 'function', name: 'decimals', inputs: [], outputs: [{ type: 'uint8' }], stateMutability: 'view' },
|
|
15
|
-
{ type: 'function', name: 'symbol', inputs: [], outputs: [{ type: 'string' }], stateMutability: 'view' },
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
const TOKENS = {
|
|
19
|
-
base: {
|
|
20
|
-
USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
21
|
-
USDbC: '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA',
|
|
22
|
-
},
|
|
23
|
-
arbitrum: {
|
|
24
|
-
USDC: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
|
|
25
|
-
'USDC.e': '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8',
|
|
26
|
-
},
|
|
27
|
-
polygon: {
|
|
28
|
-
USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
|
|
29
|
-
'USDC.e': '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const clients = {
|
|
34
|
-
base: createPublicClient({ chain: base, transport: http('https://mainnet.base.org') }),
|
|
35
|
-
arbitrum: createPublicClient({ chain: arbitrum, transport: http('https://arb1.arbitrum.io/rpc') }),
|
|
36
|
-
polygon: createPublicClient({ chain: polygon, transport: http('https://polygon-bor-rpc.publicnode.com') }),
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
async function checkWallet(name, address) {
|
|
40
|
-
console.log(`\n─── ${name}: ${address} ───`);
|
|
41
|
-
|
|
42
|
-
for (const [chainName, client] of Object.entries(clients)) {
|
|
43
|
-
try {
|
|
44
|
-
const ethBal = await client.getBalance({ address });
|
|
45
|
-
const ethStr = formatEther(ethBal);
|
|
46
|
-
const nativeName = chainName === 'polygon' ? 'POL' : 'ETH';
|
|
47
|
-
|
|
48
|
-
const tokens = TOKENS[chainName];
|
|
49
|
-
let tokenLine = '';
|
|
50
|
-
for (const [symbol, tokenAddr] of Object.entries(tokens)) {
|
|
51
|
-
try {
|
|
52
|
-
const bal = await client.readContract({ address: tokenAddr, abi: ERC20_ABI, functionName: 'balanceOf', args: [address] });
|
|
53
|
-
const decimals = await client.readContract({ address: tokenAddr, abi: ERC20_ABI, functionName: 'decimals' });
|
|
54
|
-
const formatted = formatUnits(bal, decimals);
|
|
55
|
-
if (parseFloat(formatted) > 0) {
|
|
56
|
-
tokenLine += ` | ${formatted} ${symbol}`;
|
|
57
|
-
}
|
|
58
|
-
} catch {
|
|
59
|
-
// token might not exist on chain
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (parseFloat(ethStr) > 0 || tokenLine) {
|
|
64
|
-
console.log(` ${chainName}: ${ethStr} ${nativeName}${tokenLine}`);
|
|
65
|
-
}
|
|
66
|
-
} catch (err) {
|
|
67
|
-
console.log(` ${chainName}: RPC error (${err.shortMessage || err.message})`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
console.log('Wallet Balance Check');
|
|
73
|
-
console.log('====================');
|
|
74
|
-
|
|
75
|
-
await checkWallet('Deployer', DEPLOYER);
|
|
76
|
-
await checkWallet('Test Wallet 1 (Phase 7)', TEST_WALLET_1);
|
|
77
|
-
|
|
78
|
-
console.log('\n====================');
|
|
79
|
-
console.log('Done. Use these balances to plan funded tests.');
|