@exagent/sdk 0.1.15 → 0.1.17
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 +163 -997
- package/dist/index.d.ts +163 -997
- package/dist/index.js +33 -1007
- package/dist/index.mjs +35 -1006
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
createPublicClient,
|
|
4
4
|
createWalletClient,
|
|
5
5
|
http,
|
|
6
|
-
decodeErrorResult
|
|
6
|
+
decodeErrorResult,
|
|
7
|
+
maxUint256
|
|
7
8
|
} from "viem";
|
|
8
9
|
import { privateKeyToAccount } from "viem/accounts";
|
|
9
10
|
|
|
@@ -1163,821 +1164,6 @@ var ExagentVault = class {
|
|
|
1163
1164
|
}
|
|
1164
1165
|
};
|
|
1165
1166
|
|
|
1166
|
-
// src/contracts/staking.ts
|
|
1167
|
-
var EXAGENT_STAKING_ABI = [
|
|
1168
|
-
// ============ State Variables ============
|
|
1169
|
-
{ type: "function", name: "exaToken", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
1170
|
-
{ type: "function", name: "totalDeposited", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1171
|
-
{ type: "function", name: "totalLocked", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1172
|
-
{ type: "function", name: "totalVeEXA", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1173
|
-
{ type: "function", name: "totalEffectiveVeEXA", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1174
|
-
// ============ Constants ============
|
|
1175
|
-
{ type: "function", name: "MIN_LOCK_DURATION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1176
|
-
{ type: "function", name: "MAX_LOCK_DURATION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1177
|
-
{ type: "function", name: "VAULT_ACCESS_THRESHOLD", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1178
|
-
{ type: "function", name: "PRECISION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1179
|
-
// ============ Phase 1: Deposit / Withdraw ============
|
|
1180
|
-
{
|
|
1181
|
-
type: "function",
|
|
1182
|
-
name: "deposit",
|
|
1183
|
-
inputs: [{ name: "amount", type: "uint256" }],
|
|
1184
|
-
outputs: [],
|
|
1185
|
-
stateMutability: "nonpayable"
|
|
1186
|
-
},
|
|
1187
|
-
{
|
|
1188
|
-
type: "function",
|
|
1189
|
-
name: "withdraw",
|
|
1190
|
-
inputs: [{ name: "amount", type: "uint256" }],
|
|
1191
|
-
outputs: [],
|
|
1192
|
-
stateMutability: "nonpayable"
|
|
1193
|
-
},
|
|
1194
|
-
// ============ Phase 2: Lock / Unlock ============
|
|
1195
|
-
{
|
|
1196
|
-
type: "function",
|
|
1197
|
-
name: "lock",
|
|
1198
|
-
inputs: [
|
|
1199
|
-
{ name: "amount", type: "uint256" },
|
|
1200
|
-
{ name: "lockDuration", type: "uint256" }
|
|
1201
|
-
],
|
|
1202
|
-
outputs: [],
|
|
1203
|
-
stateMutability: "nonpayable"
|
|
1204
|
-
},
|
|
1205
|
-
{
|
|
1206
|
-
type: "function",
|
|
1207
|
-
name: "extendLock",
|
|
1208
|
-
inputs: [{ name: "newLockDuration", type: "uint256" }],
|
|
1209
|
-
outputs: [],
|
|
1210
|
-
stateMutability: "nonpayable"
|
|
1211
|
-
},
|
|
1212
|
-
{ type: "function", name: "unlock", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1213
|
-
{ type: "function", name: "emergencyWithdraw", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1214
|
-
// ============ Reward Functions ============
|
|
1215
|
-
{ type: "function", name: "claimRewards", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1216
|
-
{ type: "function", name: "claimRewardsMulti", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1217
|
-
{
|
|
1218
|
-
type: "function",
|
|
1219
|
-
name: "claimRewardsToken",
|
|
1220
|
-
inputs: [{ name: "token", type: "address" }],
|
|
1221
|
-
outputs: [],
|
|
1222
|
-
stateMutability: "nonpayable"
|
|
1223
|
-
},
|
|
1224
|
-
// ============ View Functions ============
|
|
1225
|
-
{
|
|
1226
|
-
type: "function",
|
|
1227
|
-
name: "depositedAmount",
|
|
1228
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1229
|
-
outputs: [{ type: "uint256" }],
|
|
1230
|
-
stateMutability: "view"
|
|
1231
|
-
},
|
|
1232
|
-
{
|
|
1233
|
-
type: "function",
|
|
1234
|
-
name: "locks",
|
|
1235
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1236
|
-
outputs: [
|
|
1237
|
-
{ name: "amount", type: "uint256" },
|
|
1238
|
-
{ name: "unlockTime", type: "uint256" },
|
|
1239
|
-
{ name: "lockDuration", type: "uint256" },
|
|
1240
|
-
{ name: "vEXABalance", type: "uint256" }
|
|
1241
|
-
],
|
|
1242
|
-
stateMutability: "view"
|
|
1243
|
-
},
|
|
1244
|
-
{
|
|
1245
|
-
type: "function",
|
|
1246
|
-
name: "getVeEXABalance",
|
|
1247
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1248
|
-
outputs: [{ type: "uint256" }],
|
|
1249
|
-
stateMutability: "view"
|
|
1250
|
-
},
|
|
1251
|
-
{
|
|
1252
|
-
type: "function",
|
|
1253
|
-
name: "getEffectiveVeEXA",
|
|
1254
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1255
|
-
outputs: [{ type: "uint256" }],
|
|
1256
|
-
stateMutability: "view"
|
|
1257
|
-
},
|
|
1258
|
-
{
|
|
1259
|
-
type: "function",
|
|
1260
|
-
name: "calculateVeEXA",
|
|
1261
|
-
inputs: [
|
|
1262
|
-
{ name: "amount", type: "uint256" },
|
|
1263
|
-
{ name: "lockDuration", type: "uint256" }
|
|
1264
|
-
],
|
|
1265
|
-
outputs: [{ type: "uint256" }],
|
|
1266
|
-
stateMutability: "pure"
|
|
1267
|
-
},
|
|
1268
|
-
{
|
|
1269
|
-
type: "function",
|
|
1270
|
-
name: "pendingRewards",
|
|
1271
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1272
|
-
outputs: [{ type: "uint256" }],
|
|
1273
|
-
stateMutability: "view"
|
|
1274
|
-
},
|
|
1275
|
-
{
|
|
1276
|
-
type: "function",
|
|
1277
|
-
name: "pendingRewardsForToken",
|
|
1278
|
-
inputs: [
|
|
1279
|
-
{ name: "user", type: "address" },
|
|
1280
|
-
{ name: "token", type: "address" }
|
|
1281
|
-
],
|
|
1282
|
-
outputs: [{ type: "uint256" }],
|
|
1283
|
-
stateMutability: "view"
|
|
1284
|
-
},
|
|
1285
|
-
{
|
|
1286
|
-
type: "function",
|
|
1287
|
-
name: "getEarningsTier",
|
|
1288
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1289
|
-
outputs: [
|
|
1290
|
-
{ name: "multiplierBps", type: "uint256" },
|
|
1291
|
-
{ name: "tierName", type: "string" }
|
|
1292
|
-
],
|
|
1293
|
-
stateMutability: "view"
|
|
1294
|
-
},
|
|
1295
|
-
{
|
|
1296
|
-
type: "function",
|
|
1297
|
-
name: "getEmergencyWithdrawPenalty",
|
|
1298
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1299
|
-
outputs: [{ name: "penaltyBps", type: "uint256" }],
|
|
1300
|
-
stateMutability: "view"
|
|
1301
|
-
},
|
|
1302
|
-
{
|
|
1303
|
-
type: "function",
|
|
1304
|
-
name: "hasVaultAccess",
|
|
1305
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1306
|
-
outputs: [{ type: "bool" }],
|
|
1307
|
-
stateMutability: "view"
|
|
1308
|
-
},
|
|
1309
|
-
{
|
|
1310
|
-
type: "function",
|
|
1311
|
-
name: "getUnlockedBalance",
|
|
1312
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1313
|
-
outputs: [{ type: "uint256" }],
|
|
1314
|
-
stateMutability: "view"
|
|
1315
|
-
},
|
|
1316
|
-
{
|
|
1317
|
-
type: "function",
|
|
1318
|
-
name: "getRewardTokens",
|
|
1319
|
-
inputs: [],
|
|
1320
|
-
outputs: [{ type: "address[]" }],
|
|
1321
|
-
stateMutability: "view"
|
|
1322
|
-
},
|
|
1323
|
-
{
|
|
1324
|
-
type: "function",
|
|
1325
|
-
name: "isRewardToken",
|
|
1326
|
-
inputs: [{ name: "token", type: "address" }],
|
|
1327
|
-
outputs: [{ type: "bool" }],
|
|
1328
|
-
stateMutability: "view"
|
|
1329
|
-
},
|
|
1330
|
-
// ============ Events ============
|
|
1331
|
-
{
|
|
1332
|
-
type: "event",
|
|
1333
|
-
name: "Deposited",
|
|
1334
|
-
inputs: [
|
|
1335
|
-
{ name: "user", type: "address", indexed: true },
|
|
1336
|
-
{ name: "amount", type: "uint256", indexed: false },
|
|
1337
|
-
{ name: "totalDeposited", type: "uint256", indexed: false }
|
|
1338
|
-
]
|
|
1339
|
-
},
|
|
1340
|
-
{
|
|
1341
|
-
type: "event",
|
|
1342
|
-
name: "Withdrawn",
|
|
1343
|
-
inputs: [
|
|
1344
|
-
{ name: "user", type: "address", indexed: true },
|
|
1345
|
-
{ name: "amount", type: "uint256", indexed: false },
|
|
1346
|
-
{ name: "totalDeposited", type: "uint256", indexed: false }
|
|
1347
|
-
]
|
|
1348
|
-
},
|
|
1349
|
-
{
|
|
1350
|
-
type: "event",
|
|
1351
|
-
name: "Locked",
|
|
1352
|
-
inputs: [
|
|
1353
|
-
{ name: "user", type: "address", indexed: true },
|
|
1354
|
-
{ name: "amount", type: "uint256", indexed: false },
|
|
1355
|
-
{ name: "lockDuration", type: "uint256", indexed: false },
|
|
1356
|
-
{ name: "unlockTime", type: "uint256", indexed: false },
|
|
1357
|
-
{ name: "vEXABalance", type: "uint256", indexed: false }
|
|
1358
|
-
]
|
|
1359
|
-
},
|
|
1360
|
-
{
|
|
1361
|
-
type: "event",
|
|
1362
|
-
name: "Unlocked",
|
|
1363
|
-
inputs: [
|
|
1364
|
-
{ name: "user", type: "address", indexed: true },
|
|
1365
|
-
{ name: "amount", type: "uint256", indexed: false }
|
|
1366
|
-
]
|
|
1367
|
-
},
|
|
1368
|
-
{
|
|
1369
|
-
type: "event",
|
|
1370
|
-
name: "EmergencyWithdrawal",
|
|
1371
|
-
inputs: [
|
|
1372
|
-
{ name: "user", type: "address", indexed: true },
|
|
1373
|
-
{ name: "returned", type: "uint256", indexed: false },
|
|
1374
|
-
{ name: "penalty", type: "uint256", indexed: false },
|
|
1375
|
-
{ name: "penaltyBps", type: "uint256", indexed: false }
|
|
1376
|
-
]
|
|
1377
|
-
},
|
|
1378
|
-
{
|
|
1379
|
-
type: "event",
|
|
1380
|
-
name: "LockExtended",
|
|
1381
|
-
inputs: [
|
|
1382
|
-
{ name: "user", type: "address", indexed: true },
|
|
1383
|
-
{ name: "newUnlockTime", type: "uint256", indexed: false },
|
|
1384
|
-
{ name: "newVeEXABalance", type: "uint256", indexed: false }
|
|
1385
|
-
]
|
|
1386
|
-
},
|
|
1387
|
-
{
|
|
1388
|
-
type: "event",
|
|
1389
|
-
name: "RewardsClaimed",
|
|
1390
|
-
inputs: [
|
|
1391
|
-
{ name: "user", type: "address", indexed: true },
|
|
1392
|
-
{ name: "amount", type: "uint256", indexed: false }
|
|
1393
|
-
]
|
|
1394
|
-
},
|
|
1395
|
-
{
|
|
1396
|
-
type: "event",
|
|
1397
|
-
name: "MultiTokenRewardsClaimed",
|
|
1398
|
-
inputs: [
|
|
1399
|
-
{ name: "user", type: "address", indexed: true },
|
|
1400
|
-
{ name: "token", type: "address", indexed: true },
|
|
1401
|
-
{ name: "amount", type: "uint256", indexed: false }
|
|
1402
|
-
]
|
|
1403
|
-
}
|
|
1404
|
-
];
|
|
1405
|
-
var ERC20_APPROVE_ABI2 = [
|
|
1406
|
-
{
|
|
1407
|
-
type: "function",
|
|
1408
|
-
name: "approve",
|
|
1409
|
-
inputs: [
|
|
1410
|
-
{ name: "spender", type: "address" },
|
|
1411
|
-
{ name: "amount", type: "uint256" }
|
|
1412
|
-
],
|
|
1413
|
-
outputs: [{ type: "bool" }],
|
|
1414
|
-
stateMutability: "nonpayable"
|
|
1415
|
-
}
|
|
1416
|
-
];
|
|
1417
|
-
var ExagentStaking = class {
|
|
1418
|
-
address;
|
|
1419
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1420
|
-
publicClient;
|
|
1421
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1422
|
-
walletClient;
|
|
1423
|
-
chain;
|
|
1424
|
-
account;
|
|
1425
|
-
constructor(stakingAddress, publicClient, walletClient, chain, account) {
|
|
1426
|
-
this.address = stakingAddress;
|
|
1427
|
-
this.publicClient = publicClient;
|
|
1428
|
-
this.walletClient = walletClient;
|
|
1429
|
-
if (!chain) {
|
|
1430
|
-
throw new Error("Chain parameter is required");
|
|
1431
|
-
}
|
|
1432
|
-
this.chain = chain;
|
|
1433
|
-
this.account = account;
|
|
1434
|
-
}
|
|
1435
|
-
// ============ Phase 1: Deposit / Withdraw ============
|
|
1436
|
-
/**
|
|
1437
|
-
* Deposit EXA tokens for vault access (no lock required)
|
|
1438
|
-
* @param amount Amount of EXA to deposit (in wei)
|
|
1439
|
-
* @returns Transaction hash
|
|
1440
|
-
*
|
|
1441
|
-
* @example
|
|
1442
|
-
* ```typescript
|
|
1443
|
-
* // Deposit 1000 EXA to unlock vault access
|
|
1444
|
-
* const tx = await staking.deposit(parseEther('1000'));
|
|
1445
|
-
* ```
|
|
1446
|
-
*/
|
|
1447
|
-
async deposit(amount) {
|
|
1448
|
-
if (!this.walletClient || !this.account) {
|
|
1449
|
-
throw new Error("Wallet client required for write operations");
|
|
1450
|
-
}
|
|
1451
|
-
const hash = await this.walletClient.writeContract({
|
|
1452
|
-
address: this.address,
|
|
1453
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1454
|
-
functionName: "deposit",
|
|
1455
|
-
args: [amount],
|
|
1456
|
-
account: this.account,
|
|
1457
|
-
chain: this.chain
|
|
1458
|
-
});
|
|
1459
|
-
return hash;
|
|
1460
|
-
}
|
|
1461
|
-
/**
|
|
1462
|
-
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
1463
|
-
* @param amount Amount of EXA to withdraw (in wei)
|
|
1464
|
-
* @returns Transaction hash
|
|
1465
|
-
*/
|
|
1466
|
-
async withdraw(amount) {
|
|
1467
|
-
if (!this.walletClient || !this.account) {
|
|
1468
|
-
throw new Error("Wallet client required for write operations");
|
|
1469
|
-
}
|
|
1470
|
-
const hash = await this.walletClient.writeContract({
|
|
1471
|
-
address: this.address,
|
|
1472
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1473
|
-
functionName: "withdraw",
|
|
1474
|
-
args: [amount],
|
|
1475
|
-
account: this.account,
|
|
1476
|
-
chain: this.chain
|
|
1477
|
-
});
|
|
1478
|
-
return hash;
|
|
1479
|
-
}
|
|
1480
|
-
// ============ Phase 2: Lock / Unlock ============
|
|
1481
|
-
/**
|
|
1482
|
-
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
1483
|
-
* @param amount Amount of deposited EXA to lock (in wei)
|
|
1484
|
-
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
1485
|
-
* @returns Transaction hash
|
|
1486
|
-
*
|
|
1487
|
-
* @example
|
|
1488
|
-
* ```typescript
|
|
1489
|
-
* // Lock 1000 EXA for 6 months
|
|
1490
|
-
* const tx = await staking.lock(
|
|
1491
|
-
* parseEther('1000'),
|
|
1492
|
-
* ExagentStaking.LOCK_6_MONTHS
|
|
1493
|
-
* );
|
|
1494
|
-
* ```
|
|
1495
|
-
*/
|
|
1496
|
-
async lock(amount, lockDuration) {
|
|
1497
|
-
if (!this.walletClient || !this.account) {
|
|
1498
|
-
throw new Error("Wallet client required for write operations");
|
|
1499
|
-
}
|
|
1500
|
-
const hash = await this.walletClient.writeContract({
|
|
1501
|
-
address: this.address,
|
|
1502
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1503
|
-
functionName: "lock",
|
|
1504
|
-
args: [amount, lockDuration],
|
|
1505
|
-
account: this.account,
|
|
1506
|
-
chain: this.chain
|
|
1507
|
-
});
|
|
1508
|
-
return hash;
|
|
1509
|
-
}
|
|
1510
|
-
/**
|
|
1511
|
-
* Extend lock duration for additional voting power
|
|
1512
|
-
* @param newLockDuration New lock duration in seconds (must be longer than remaining)
|
|
1513
|
-
* @returns Transaction hash
|
|
1514
|
-
*/
|
|
1515
|
-
async extendLock(newLockDuration) {
|
|
1516
|
-
if (!this.walletClient || !this.account) {
|
|
1517
|
-
throw new Error("Wallet client required for write operations");
|
|
1518
|
-
}
|
|
1519
|
-
const hash = await this.walletClient.writeContract({
|
|
1520
|
-
address: this.address,
|
|
1521
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1522
|
-
functionName: "extendLock",
|
|
1523
|
-
args: [newLockDuration],
|
|
1524
|
-
account: this.account,
|
|
1525
|
-
chain: this.chain
|
|
1526
|
-
});
|
|
1527
|
-
return hash;
|
|
1528
|
-
}
|
|
1529
|
-
/**
|
|
1530
|
-
* Unlock EXA after lock expires (normal path — no penalty)
|
|
1531
|
-
* Returns locked amount to unlocked deposited balance.
|
|
1532
|
-
* @returns Transaction hash
|
|
1533
|
-
*/
|
|
1534
|
-
async unlock() {
|
|
1535
|
-
if (!this.walletClient || !this.account) {
|
|
1536
|
-
throw new Error("Wallet client required for write operations");
|
|
1537
|
-
}
|
|
1538
|
-
const hash = await this.walletClient.writeContract({
|
|
1539
|
-
address: this.address,
|
|
1540
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1541
|
-
functionName: "unlock",
|
|
1542
|
-
args: [],
|
|
1543
|
-
account: this.account,
|
|
1544
|
-
chain: this.chain
|
|
1545
|
-
});
|
|
1546
|
-
return hash;
|
|
1547
|
-
}
|
|
1548
|
-
/**
|
|
1549
|
-
* Emergency withdrawal — instant exit from lock with graduated penalty
|
|
1550
|
-
* Two-phase penalty: 50%→20% over the first quarter of the lock, then flat 20% until expiry.
|
|
1551
|
-
* Penalty goes to treasury. Remaining returns to unlocked deposit balance.
|
|
1552
|
-
* @returns Transaction hash
|
|
1553
|
-
*/
|
|
1554
|
-
async emergencyWithdraw() {
|
|
1555
|
-
if (!this.walletClient || !this.account) {
|
|
1556
|
-
throw new Error("Wallet client required for write operations");
|
|
1557
|
-
}
|
|
1558
|
-
const hash = await this.walletClient.writeContract({
|
|
1559
|
-
address: this.address,
|
|
1560
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1561
|
-
functionName: "emergencyWithdraw",
|
|
1562
|
-
args: [],
|
|
1563
|
-
account: this.account,
|
|
1564
|
-
chain: this.chain
|
|
1565
|
-
});
|
|
1566
|
-
return hash;
|
|
1567
|
-
}
|
|
1568
|
-
// ============ Reward Functions ============
|
|
1569
|
-
/**
|
|
1570
|
-
* Claim accumulated EXA rewards
|
|
1571
|
-
* @returns Transaction hash
|
|
1572
|
-
*/
|
|
1573
|
-
async claimRewards() {
|
|
1574
|
-
if (!this.walletClient || !this.account) {
|
|
1575
|
-
throw new Error("Wallet client required for write operations");
|
|
1576
|
-
}
|
|
1577
|
-
const hash = await this.walletClient.writeContract({
|
|
1578
|
-
address: this.address,
|
|
1579
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1580
|
-
functionName: "claimRewards",
|
|
1581
|
-
args: [],
|
|
1582
|
-
account: this.account,
|
|
1583
|
-
chain: this.chain
|
|
1584
|
-
});
|
|
1585
|
-
return hash;
|
|
1586
|
-
}
|
|
1587
|
-
/**
|
|
1588
|
-
* Claim all pending multi-token rewards (ETH, USDC, etc.)
|
|
1589
|
-
* @returns Transaction hash
|
|
1590
|
-
*/
|
|
1591
|
-
async claimRewardsMulti() {
|
|
1592
|
-
if (!this.walletClient || !this.account) {
|
|
1593
|
-
throw new Error("Wallet client required for write operations");
|
|
1594
|
-
}
|
|
1595
|
-
const hash = await this.walletClient.writeContract({
|
|
1596
|
-
address: this.address,
|
|
1597
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1598
|
-
functionName: "claimRewardsMulti",
|
|
1599
|
-
args: [],
|
|
1600
|
-
account: this.account,
|
|
1601
|
-
chain: this.chain
|
|
1602
|
-
});
|
|
1603
|
-
return hash;
|
|
1604
|
-
}
|
|
1605
|
-
/**
|
|
1606
|
-
* Claim pending rewards for a specific token
|
|
1607
|
-
* @param token The reward token address to claim
|
|
1608
|
-
* @returns Transaction hash
|
|
1609
|
-
*/
|
|
1610
|
-
async claimRewardsToken(token) {
|
|
1611
|
-
if (!this.walletClient || !this.account) {
|
|
1612
|
-
throw new Error("Wallet client required for write operations");
|
|
1613
|
-
}
|
|
1614
|
-
const hash = await this.walletClient.writeContract({
|
|
1615
|
-
address: this.address,
|
|
1616
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1617
|
-
functionName: "claimRewardsToken",
|
|
1618
|
-
args: [token],
|
|
1619
|
-
account: this.account,
|
|
1620
|
-
chain: this.chain
|
|
1621
|
-
});
|
|
1622
|
-
return hash;
|
|
1623
|
-
}
|
|
1624
|
-
// ============ Read Functions ============
|
|
1625
|
-
/**
|
|
1626
|
-
* Get comprehensive staking info for a user (deposit + lock)
|
|
1627
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1628
|
-
* @returns Combined staking info
|
|
1629
|
-
*/
|
|
1630
|
-
async getStakingInfo(userAddress) {
|
|
1631
|
-
const user = userAddress ?? this.account?.address;
|
|
1632
|
-
if (!user) {
|
|
1633
|
-
throw new Error("User address required");
|
|
1634
|
-
}
|
|
1635
|
-
const [deposited, lockResult, currentVeEXA, vaultAccess, unlockedBalance] = await Promise.all([
|
|
1636
|
-
this.publicClient.readContract({
|
|
1637
|
-
address: this.address,
|
|
1638
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1639
|
-
functionName: "depositedAmount",
|
|
1640
|
-
args: [user]
|
|
1641
|
-
}),
|
|
1642
|
-
this.publicClient.readContract({
|
|
1643
|
-
address: this.address,
|
|
1644
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1645
|
-
functionName: "locks",
|
|
1646
|
-
args: [user]
|
|
1647
|
-
}),
|
|
1648
|
-
this.publicClient.readContract({
|
|
1649
|
-
address: this.address,
|
|
1650
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1651
|
-
functionName: "getVeEXABalance",
|
|
1652
|
-
args: [user]
|
|
1653
|
-
}),
|
|
1654
|
-
this.publicClient.readContract({
|
|
1655
|
-
address: this.address,
|
|
1656
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1657
|
-
functionName: "hasVaultAccess",
|
|
1658
|
-
args: [user]
|
|
1659
|
-
}),
|
|
1660
|
-
this.publicClient.readContract({
|
|
1661
|
-
address: this.address,
|
|
1662
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1663
|
-
functionName: "getUnlockedBalance",
|
|
1664
|
-
args: [user]
|
|
1665
|
-
})
|
|
1666
|
-
]);
|
|
1667
|
-
const lockData = lockResult;
|
|
1668
|
-
const depositedBigint = deposited;
|
|
1669
|
-
const lockedAmount = lockData[0];
|
|
1670
|
-
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
1671
|
-
const depositInfo = {
|
|
1672
|
-
deposited: depositedBigint,
|
|
1673
|
-
locked: lockedAmount,
|
|
1674
|
-
unlocked: unlockedBalance,
|
|
1675
|
-
hasVaultAccess: vaultAccess
|
|
1676
|
-
};
|
|
1677
|
-
let lockInfo = null;
|
|
1678
|
-
if (lockedAmount > 0n) {
|
|
1679
|
-
const isUnlocked = lockData[1] <= now;
|
|
1680
|
-
const remainingLockTime = isUnlocked ? 0n : lockData[1] - now;
|
|
1681
|
-
lockInfo = {
|
|
1682
|
-
amount: lockData[0],
|
|
1683
|
-
unlockTime: lockData[1],
|
|
1684
|
-
lockDuration: lockData[2],
|
|
1685
|
-
vEXABalance: lockData[3],
|
|
1686
|
-
currentVeEXA,
|
|
1687
|
-
isUnlocked,
|
|
1688
|
-
remainingLockTime
|
|
1689
|
-
};
|
|
1690
|
-
}
|
|
1691
|
-
return { deposit: depositInfo, lock: lockInfo };
|
|
1692
|
-
}
|
|
1693
|
-
/**
|
|
1694
|
-
* Get deposit info for a user
|
|
1695
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1696
|
-
* @returns Deposit info
|
|
1697
|
-
*/
|
|
1698
|
-
async getDepositInfo(userAddress) {
|
|
1699
|
-
const user = userAddress ?? this.account?.address;
|
|
1700
|
-
if (!user) {
|
|
1701
|
-
throw new Error("User address required");
|
|
1702
|
-
}
|
|
1703
|
-
const [deposited, lockResult, vaultAccess, unlockedBalance] = await Promise.all([
|
|
1704
|
-
this.publicClient.readContract({
|
|
1705
|
-
address: this.address,
|
|
1706
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1707
|
-
functionName: "depositedAmount",
|
|
1708
|
-
args: [user]
|
|
1709
|
-
}),
|
|
1710
|
-
this.publicClient.readContract({
|
|
1711
|
-
address: this.address,
|
|
1712
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1713
|
-
functionName: "locks",
|
|
1714
|
-
args: [user]
|
|
1715
|
-
}),
|
|
1716
|
-
this.publicClient.readContract({
|
|
1717
|
-
address: this.address,
|
|
1718
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1719
|
-
functionName: "hasVaultAccess",
|
|
1720
|
-
args: [user]
|
|
1721
|
-
}),
|
|
1722
|
-
this.publicClient.readContract({
|
|
1723
|
-
address: this.address,
|
|
1724
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1725
|
-
functionName: "getUnlockedBalance",
|
|
1726
|
-
args: [user]
|
|
1727
|
-
})
|
|
1728
|
-
]);
|
|
1729
|
-
const lockData = lockResult;
|
|
1730
|
-
return {
|
|
1731
|
-
deposited,
|
|
1732
|
-
locked: lockData[0],
|
|
1733
|
-
unlocked: unlockedBalance,
|
|
1734
|
-
hasVaultAccess: vaultAccess
|
|
1735
|
-
};
|
|
1736
|
-
}
|
|
1737
|
-
/**
|
|
1738
|
-
* Get current vEXA balance (with time decay applied)
|
|
1739
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1740
|
-
* @returns Current vEXA balance
|
|
1741
|
-
*/
|
|
1742
|
-
async getVeEXABalance(userAddress) {
|
|
1743
|
-
const user = userAddress ?? this.account?.address;
|
|
1744
|
-
if (!user) {
|
|
1745
|
-
throw new Error("User address required");
|
|
1746
|
-
}
|
|
1747
|
-
return this.publicClient.readContract({
|
|
1748
|
-
address: this.address,
|
|
1749
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1750
|
-
functionName: "getVeEXABalance",
|
|
1751
|
-
args: [user]
|
|
1752
|
-
});
|
|
1753
|
-
}
|
|
1754
|
-
/**
|
|
1755
|
-
* Get effective vEXA (with tier multiplier applied)
|
|
1756
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1757
|
-
* @returns Effective vEXA balance
|
|
1758
|
-
*/
|
|
1759
|
-
async getEffectiveVeEXA(userAddress) {
|
|
1760
|
-
const user = userAddress ?? this.account?.address;
|
|
1761
|
-
if (!user) {
|
|
1762
|
-
throw new Error("User address required");
|
|
1763
|
-
}
|
|
1764
|
-
return this.publicClient.readContract({
|
|
1765
|
-
address: this.address,
|
|
1766
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1767
|
-
functionName: "getEffectiveVeEXA",
|
|
1768
|
-
args: [user]
|
|
1769
|
-
});
|
|
1770
|
-
}
|
|
1771
|
-
/**
|
|
1772
|
-
* Check if user has vault access (meets deposit threshold)
|
|
1773
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1774
|
-
* @returns True if user can access vaults
|
|
1775
|
-
*/
|
|
1776
|
-
async hasVaultAccess(userAddress) {
|
|
1777
|
-
const user = userAddress ?? this.account?.address;
|
|
1778
|
-
if (!user) {
|
|
1779
|
-
throw new Error("User address required");
|
|
1780
|
-
}
|
|
1781
|
-
return this.publicClient.readContract({
|
|
1782
|
-
address: this.address,
|
|
1783
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1784
|
-
functionName: "hasVaultAccess",
|
|
1785
|
-
args: [user]
|
|
1786
|
-
});
|
|
1787
|
-
}
|
|
1788
|
-
/**
|
|
1789
|
-
* Get earnings tier for a user (Bronze/Silver/Gold/Platinum/Diamond)
|
|
1790
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1791
|
-
* @returns Tier info with multiplier and name
|
|
1792
|
-
*/
|
|
1793
|
-
async getEarningsTier(userAddress) {
|
|
1794
|
-
const user = userAddress ?? this.account?.address;
|
|
1795
|
-
if (!user) {
|
|
1796
|
-
throw new Error("User address required");
|
|
1797
|
-
}
|
|
1798
|
-
const result = await this.publicClient.readContract({
|
|
1799
|
-
address: this.address,
|
|
1800
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1801
|
-
functionName: "getEarningsTier",
|
|
1802
|
-
args: [user]
|
|
1803
|
-
});
|
|
1804
|
-
return {
|
|
1805
|
-
multiplierBps: result[0],
|
|
1806
|
-
tierName: result[1]
|
|
1807
|
-
};
|
|
1808
|
-
}
|
|
1809
|
-
/**
|
|
1810
|
-
* Get current emergency withdrawal penalty for a user
|
|
1811
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1812
|
-
* @returns Penalty in basis points (5000 = 50% at lock start, ramps to 2000 over first 25% of lock, then flat 2000)
|
|
1813
|
-
*/
|
|
1814
|
-
async getEmergencyWithdrawPenalty(userAddress) {
|
|
1815
|
-
const user = userAddress ?? this.account?.address;
|
|
1816
|
-
if (!user) {
|
|
1817
|
-
throw new Error("User address required");
|
|
1818
|
-
}
|
|
1819
|
-
return this.publicClient.readContract({
|
|
1820
|
-
address: this.address,
|
|
1821
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1822
|
-
functionName: "getEmergencyWithdrawPenalty",
|
|
1823
|
-
args: [user]
|
|
1824
|
-
});
|
|
1825
|
-
}
|
|
1826
|
-
/**
|
|
1827
|
-
* Get pending EXA rewards for a user
|
|
1828
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1829
|
-
* @returns Pending reward amount in wei
|
|
1830
|
-
*/
|
|
1831
|
-
async pendingRewards(userAddress) {
|
|
1832
|
-
const user = userAddress ?? this.account?.address;
|
|
1833
|
-
if (!user) {
|
|
1834
|
-
throw new Error("User address required");
|
|
1835
|
-
}
|
|
1836
|
-
return this.publicClient.readContract({
|
|
1837
|
-
address: this.address,
|
|
1838
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1839
|
-
functionName: "pendingRewards",
|
|
1840
|
-
args: [user]
|
|
1841
|
-
});
|
|
1842
|
-
}
|
|
1843
|
-
/**
|
|
1844
|
-
* Get pending rewards for a specific token
|
|
1845
|
-
* @param token The reward token address
|
|
1846
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1847
|
-
* @returns Pending reward amount in wei
|
|
1848
|
-
*/
|
|
1849
|
-
async pendingRewardsMulti(token, userAddress) {
|
|
1850
|
-
const user = userAddress ?? this.account?.address;
|
|
1851
|
-
if (!user) {
|
|
1852
|
-
throw new Error("User address required");
|
|
1853
|
-
}
|
|
1854
|
-
return this.publicClient.readContract({
|
|
1855
|
-
address: this.address,
|
|
1856
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1857
|
-
functionName: "pendingRewardsForToken",
|
|
1858
|
-
args: [user, token]
|
|
1859
|
-
});
|
|
1860
|
-
}
|
|
1861
|
-
/**
|
|
1862
|
-
* Get list of whitelisted reward tokens
|
|
1863
|
-
* @returns Array of reward token addresses
|
|
1864
|
-
*/
|
|
1865
|
-
async getRewardTokens() {
|
|
1866
|
-
return this.publicClient.readContract({
|
|
1867
|
-
address: this.address,
|
|
1868
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1869
|
-
functionName: "getRewardTokens"
|
|
1870
|
-
});
|
|
1871
|
-
}
|
|
1872
|
-
/**
|
|
1873
|
-
* Check if a token is whitelisted for rewards
|
|
1874
|
-
* @param token The token address to check
|
|
1875
|
-
* @returns True if token is whitelisted
|
|
1876
|
-
*/
|
|
1877
|
-
async isRewardToken(token) {
|
|
1878
|
-
return this.publicClient.readContract({
|
|
1879
|
-
address: this.address,
|
|
1880
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1881
|
-
functionName: "isRewardToken",
|
|
1882
|
-
args: [token]
|
|
1883
|
-
});
|
|
1884
|
-
}
|
|
1885
|
-
/**
|
|
1886
|
-
* Get total EXA deposited across all users
|
|
1887
|
-
* @returns Total deposited amount in wei
|
|
1888
|
-
*/
|
|
1889
|
-
async getTotalDeposited() {
|
|
1890
|
-
return this.publicClient.readContract({
|
|
1891
|
-
address: this.address,
|
|
1892
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1893
|
-
functionName: "totalDeposited"
|
|
1894
|
-
});
|
|
1895
|
-
}
|
|
1896
|
-
/**
|
|
1897
|
-
* Get total EXA locked across all users
|
|
1898
|
-
* @returns Total locked amount in wei
|
|
1899
|
-
*/
|
|
1900
|
-
async getTotalLocked() {
|
|
1901
|
-
return this.publicClient.readContract({
|
|
1902
|
-
address: this.address,
|
|
1903
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1904
|
-
functionName: "totalLocked"
|
|
1905
|
-
});
|
|
1906
|
-
}
|
|
1907
|
-
/**
|
|
1908
|
-
* Get total vEXA supply across all users
|
|
1909
|
-
* @returns Total vEXA supply
|
|
1910
|
-
*/
|
|
1911
|
-
async getTotalVeEXA() {
|
|
1912
|
-
return this.publicClient.readContract({
|
|
1913
|
-
address: this.address,
|
|
1914
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1915
|
-
functionName: "totalVeEXA"
|
|
1916
|
-
});
|
|
1917
|
-
}
|
|
1918
|
-
/**
|
|
1919
|
-
* Calculate vEXA balance for a given lock (preview)
|
|
1920
|
-
* @param amount Amount of EXA to lock
|
|
1921
|
-
* @param lockDuration Lock duration in seconds
|
|
1922
|
-
* @returns Expected vEXA balance
|
|
1923
|
-
*/
|
|
1924
|
-
async calculateVeEXA(amount, lockDuration) {
|
|
1925
|
-
return this.publicClient.readContract({
|
|
1926
|
-
address: this.address,
|
|
1927
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1928
|
-
functionName: "calculateVeEXA",
|
|
1929
|
-
args: [amount, lockDuration]
|
|
1930
|
-
});
|
|
1931
|
-
}
|
|
1932
|
-
/**
|
|
1933
|
-
* Get the EXA token address
|
|
1934
|
-
* @returns EXA token contract address
|
|
1935
|
-
*/
|
|
1936
|
-
async getExaTokenAddress() {
|
|
1937
|
-
return this.publicClient.readContract({
|
|
1938
|
-
address: this.address,
|
|
1939
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1940
|
-
functionName: "exaToken"
|
|
1941
|
-
});
|
|
1942
|
-
}
|
|
1943
|
-
// ============ Helper Functions ============
|
|
1944
|
-
/**
|
|
1945
|
-
* Approve EXA token spending for deposits
|
|
1946
|
-
* @param amount Amount to approve
|
|
1947
|
-
* @returns Transaction hash
|
|
1948
|
-
*/
|
|
1949
|
-
async approveExa(amount) {
|
|
1950
|
-
if (!this.walletClient || !this.account) {
|
|
1951
|
-
throw new Error("Wallet client required for write operations");
|
|
1952
|
-
}
|
|
1953
|
-
const exaToken = await this.getExaTokenAddress();
|
|
1954
|
-
const hash = await this.walletClient.writeContract({
|
|
1955
|
-
address: exaToken,
|
|
1956
|
-
abi: ERC20_APPROVE_ABI2,
|
|
1957
|
-
functionName: "approve",
|
|
1958
|
-
args: [this.address, amount],
|
|
1959
|
-
account: this.account,
|
|
1960
|
-
chain: this.chain
|
|
1961
|
-
});
|
|
1962
|
-
return hash;
|
|
1963
|
-
}
|
|
1964
|
-
// ============ Lock Duration Constants ============
|
|
1965
|
-
/** Minimum lock duration: 30 days in seconds */
|
|
1966
|
-
static MIN_LOCK_DURATION = 30n * 24n * 60n * 60n;
|
|
1967
|
-
/** Maximum lock duration: 2 years in seconds */
|
|
1968
|
-
static MAX_LOCK_DURATION = 730n * 24n * 60n * 60n;
|
|
1969
|
-
/** 1 month lock duration in seconds */
|
|
1970
|
-
static LOCK_1_MONTH = 30n * 24n * 60n * 60n;
|
|
1971
|
-
/** 3 months lock duration in seconds */
|
|
1972
|
-
static LOCK_3_MONTHS = 90n * 24n * 60n * 60n;
|
|
1973
|
-
/** 6 months lock duration in seconds */
|
|
1974
|
-
static LOCK_6_MONTHS = 180n * 24n * 60n * 60n;
|
|
1975
|
-
/** 1 year lock duration in seconds */
|
|
1976
|
-
static LOCK_1_YEAR = 365n * 24n * 60n * 60n;
|
|
1977
|
-
/** 2 years lock duration in seconds */
|
|
1978
|
-
static LOCK_2_YEARS = 730n * 24n * 60n * 60n;
|
|
1979
|
-
};
|
|
1980
|
-
|
|
1981
1167
|
// src/constants.ts
|
|
1982
1168
|
import { base } from "viem/chains";
|
|
1983
1169
|
var SDK_VERSION = "0.1.14";
|
|
@@ -1994,12 +1180,9 @@ var CHAIN_CONFIG = {
|
|
|
1994
1180
|
var CONTRACT_ADDRESSES = {
|
|
1995
1181
|
mainnet: {
|
|
1996
1182
|
agentRegistry: "0x2261706C751F8ac5cdDb481B7b56EA2137d4A723",
|
|
1997
|
-
exaToken: "0x13403Fb738C97cF7564F279288468c140AaEd05c",
|
|
1998
|
-
staking: "0xe925727B21f1B86008f291E8f3102345A57B6c17",
|
|
1999
1183
|
router: "0x1BCFa13f677fDCf697D8b7d5120f544817F1de1A",
|
|
2000
|
-
vaultFactory: "
|
|
2001
|
-
feeCollector: "
|
|
2002
|
-
buyback: "0x39967532b640B2f735548c7a5b46d8D890A0B2f2",
|
|
1184
|
+
vaultFactory: "0x1E0e4E445A9fda2e7aBBfFEcA80392ABb0921554",
|
|
1185
|
+
feeCollector: "0x00Ab9847049b5496619dFDd1A7bd36FA49eB7195",
|
|
2003
1186
|
serviceEscrow: "0x63A4d1dA774422EFC2cc57d71F948231BD812516"
|
|
2004
1187
|
}
|
|
2005
1188
|
};
|
|
@@ -2023,19 +1206,12 @@ var EXAGENT_API_CONFIG = {
|
|
|
2023
1206
|
mainnet: "https://exagent-api.onrender.com"
|
|
2024
1207
|
};
|
|
2025
1208
|
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
2026
|
-
var PHASE_1_CONTRACTS = /* @__PURE__ */ new Set([
|
|
2027
|
-
"agentRegistry",
|
|
2028
|
-
"exaToken",
|
|
2029
|
-
"staking",
|
|
2030
|
-
"router",
|
|
2031
|
-
"feeCollector"
|
|
2032
|
-
]);
|
|
2033
1209
|
function validateContractAddresses(network) {
|
|
2034
1210
|
const addresses = CONTRACT_ADDRESSES[network];
|
|
2035
|
-
const
|
|
2036
|
-
if (
|
|
1211
|
+
const missing = Object.entries(addresses).filter(([, addr]) => addr === ZERO_ADDRESS).map(([name]) => name);
|
|
1212
|
+
if (missing.length > 0) {
|
|
2037
1213
|
throw new Error(
|
|
2038
|
-
`
|
|
1214
|
+
`Contract addresses not deployed on ${network}. Missing: ${missing.join(", ")}. Update @exagent/sdk to the latest version.`
|
|
2039
1215
|
);
|
|
2040
1216
|
}
|
|
2041
1217
|
}
|
|
@@ -2067,7 +1243,6 @@ var ExagentClient = class {
|
|
|
2067
1243
|
apiKey;
|
|
2068
1244
|
// Contract interfaces
|
|
2069
1245
|
registry;
|
|
2070
|
-
staking;
|
|
2071
1246
|
// Cached agent ID
|
|
2072
1247
|
_agentId;
|
|
2073
1248
|
constructor(config) {
|
|
@@ -2102,13 +1277,6 @@ var ExagentClient = class {
|
|
|
2102
1277
|
chain,
|
|
2103
1278
|
this.account
|
|
2104
1279
|
);
|
|
2105
|
-
this.staking = new ExagentStaking(
|
|
2106
|
-
addresses.staking,
|
|
2107
|
-
this.publicClient,
|
|
2108
|
-
this.walletClient,
|
|
2109
|
-
chain,
|
|
2110
|
-
this.account
|
|
2111
|
-
);
|
|
2112
1280
|
}
|
|
2113
1281
|
/** Standard headers for all API requests (includes SDK version for gating) */
|
|
2114
1282
|
apiHeaders(contentType) {
|
|
@@ -2257,7 +1425,7 @@ var ExagentClient = class {
|
|
|
2257
1425
|
await this.approveToken(
|
|
2258
1426
|
approval.token,
|
|
2259
1427
|
approval.spender,
|
|
2260
|
-
|
|
1428
|
+
maxUint256
|
|
2261
1429
|
);
|
|
2262
1430
|
}
|
|
2263
1431
|
const txParams = {
|
|
@@ -2278,6 +1446,7 @@ var ExagentClient = class {
|
|
|
2278
1446
|
} catch (err) {
|
|
2279
1447
|
const errorData = err?.data;
|
|
2280
1448
|
if (errorData && errorData.length > 2) {
|
|
1449
|
+
console.error(`Gas estimation revert data: ${errorData}`);
|
|
2281
1450
|
try {
|
|
2282
1451
|
const decoded = decodeErrorResult({
|
|
2283
1452
|
abi: [...EXAGENT_ROUTER_ABI, ...EXAGENT_REGISTRY_ABI],
|
|
@@ -2286,6 +1455,7 @@ var ExagentClient = class {
|
|
|
2286
1455
|
throw new Error(`Trade will revert: ${decoded.errorName}${decoded.args ? ` (${decoded.args.join(", ")})` : ""}`);
|
|
2287
1456
|
} catch (decodeErr) {
|
|
2288
1457
|
if (decodeErr instanceof Error && decodeErr.message.startsWith("Trade will revert:")) throw decodeErr;
|
|
1458
|
+
throw new Error(`Trade will revert: unknown error selector ${errorData.slice(0, 10)} (raw: ${errorData.slice(0, 66)})`);
|
|
2289
1459
|
}
|
|
2290
1460
|
}
|
|
2291
1461
|
throw new Error(`Trade will revert: gas estimation failed. ${err?.message || "Unknown reason"}`);
|
|
@@ -2350,7 +1520,9 @@ var ExagentClient = class {
|
|
|
2350
1520
|
}
|
|
2351
1521
|
}
|
|
2352
1522
|
/**
|
|
2353
|
-
* Approve token spending for router
|
|
1523
|
+
* Approve token spending for router.
|
|
1524
|
+
* Verifies the approval receipt succeeded — previous version silently continued
|
|
1525
|
+
* on reverted approvals, causing downstream "transfer amount exceeds allowance" errors.
|
|
2354
1526
|
*/
|
|
2355
1527
|
async approveToken(token, spender, amount) {
|
|
2356
1528
|
const approveData = this.encodeApprove(spender, amount);
|
|
@@ -2360,7 +1532,12 @@ var ExagentClient = class {
|
|
|
2360
1532
|
to: token,
|
|
2361
1533
|
data: approveData
|
|
2362
1534
|
});
|
|
2363
|
-
await this.publicClient.waitForTransactionReceipt({ hash });
|
|
1535
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
|
|
1536
|
+
if (receipt.status === "reverted") {
|
|
1537
|
+
throw new Error(
|
|
1538
|
+
`Token approval reverted: approve(${spender}, ${amount}) on ${token}. The token may have non-standard approval behavior.`
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
2364
1541
|
return hash;
|
|
2365
1542
|
}
|
|
2366
1543
|
/**
|
|
@@ -2521,113 +1698,6 @@ var ExagentClient = class {
|
|
|
2521
1698
|
const vault = this.getVault(vaultAddress);
|
|
2522
1699
|
return vault.redeem(shares);
|
|
2523
1700
|
}
|
|
2524
|
-
// ============ Staking Functions ============
|
|
2525
|
-
/**
|
|
2526
|
-
* Deposit EXA tokens for vault access (no lock required)
|
|
2527
|
-
* @param amount Amount of EXA to deposit (in wei)
|
|
2528
|
-
* @returns Transaction hash
|
|
2529
|
-
*
|
|
2530
|
-
* @example
|
|
2531
|
-
* ```typescript
|
|
2532
|
-
* // Deposit 1000 EXA to unlock vault access
|
|
2533
|
-
* const tx = await exagent.depositExa(parseEther('1000'));
|
|
2534
|
-
* ```
|
|
2535
|
-
*/
|
|
2536
|
-
async depositExa(amount) {
|
|
2537
|
-
await this.staking.approveExa(amount);
|
|
2538
|
-
return this.staking.deposit(amount);
|
|
2539
|
-
}
|
|
2540
|
-
/**
|
|
2541
|
-
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
2542
|
-
* @param amount Amount of EXA to withdraw (in wei)
|
|
2543
|
-
* @returns Transaction hash
|
|
2544
|
-
*/
|
|
2545
|
-
async withdrawExa(amount) {
|
|
2546
|
-
return this.staking.withdraw(amount);
|
|
2547
|
-
}
|
|
2548
|
-
/**
|
|
2549
|
-
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
2550
|
-
* @param amount Amount of deposited EXA to lock (in wei)
|
|
2551
|
-
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
2552
|
-
* @returns Transaction hash
|
|
2553
|
-
*
|
|
2554
|
-
* @example
|
|
2555
|
-
* ```typescript
|
|
2556
|
-
* // Lock 1000 EXA for 6 months
|
|
2557
|
-
* const tx = await exagent.lockExa(
|
|
2558
|
-
* parseEther('1000'),
|
|
2559
|
-
* ExagentStaking.LOCK_6_MONTHS
|
|
2560
|
-
* );
|
|
2561
|
-
* ```
|
|
2562
|
-
*/
|
|
2563
|
-
async lockExa(amount, lockDuration) {
|
|
2564
|
-
return this.staking.lock(amount, lockDuration);
|
|
2565
|
-
}
|
|
2566
|
-
/**
|
|
2567
|
-
* Unlock EXA after lock expires (no penalty)
|
|
2568
|
-
* @returns Transaction hash
|
|
2569
|
-
*/
|
|
2570
|
-
async unlockExa() {
|
|
2571
|
-
return this.staking.unlock();
|
|
2572
|
-
}
|
|
2573
|
-
/**
|
|
2574
|
-
* Emergency withdrawal from active lock (graduated 50%→20% penalty)
|
|
2575
|
-
* @returns Transaction hash
|
|
2576
|
-
*/
|
|
2577
|
-
async emergencyWithdrawExa() {
|
|
2578
|
-
return this.staking.emergencyWithdraw();
|
|
2579
|
-
}
|
|
2580
|
-
/**
|
|
2581
|
-
* Get comprehensive staking info (deposit + lock) for the connected wallet
|
|
2582
|
-
* @returns Staking info including deposit status and lock status
|
|
2583
|
-
*/
|
|
2584
|
-
async getStakingInfo() {
|
|
2585
|
-
return this.staking.getStakingInfo();
|
|
2586
|
-
}
|
|
2587
|
-
/**
|
|
2588
|
-
* Get deposit info for the connected wallet
|
|
2589
|
-
* @returns Deposit info (deposited, locked, unlocked, vault access)
|
|
2590
|
-
*/
|
|
2591
|
-
async getDepositInfo() {
|
|
2592
|
-
return this.staking.getDepositInfo();
|
|
2593
|
-
}
|
|
2594
|
-
/**
|
|
2595
|
-
* Get current vEXA balance for the connected wallet
|
|
2596
|
-
* @returns Current vEXA balance (with time decay applied)
|
|
2597
|
-
*/
|
|
2598
|
-
async getVeEXABalance() {
|
|
2599
|
-
return this.staking.getVeEXABalance();
|
|
2600
|
-
}
|
|
2601
|
-
/**
|
|
2602
|
-
* Check if connected wallet has vault access (meets deposit threshold)
|
|
2603
|
-
* @returns True if user can access vaults
|
|
2604
|
-
*/
|
|
2605
|
-
async hasVaultAccess() {
|
|
2606
|
-
return this.staking.hasVaultAccess();
|
|
2607
|
-
}
|
|
2608
|
-
/**
|
|
2609
|
-
* Get earnings tier for the connected wallet
|
|
2610
|
-
* @returns Tier info with multiplier and name
|
|
2611
|
-
*/
|
|
2612
|
-
async getEarningsTier() {
|
|
2613
|
-
return this.staking.getEarningsTier();
|
|
2614
|
-
}
|
|
2615
|
-
/**
|
|
2616
|
-
* Get emergency withdrawal penalty for the connected wallet
|
|
2617
|
-
* @returns Penalty in basis points (5000 = 50% at start, 2000 = 20% near expiry)
|
|
2618
|
-
*/
|
|
2619
|
-
async getEmergencyWithdrawPenalty() {
|
|
2620
|
-
return this.staking.getEmergencyWithdrawPenalty();
|
|
2621
|
-
}
|
|
2622
|
-
/**
|
|
2623
|
-
* Claim all pending staking rewards (EXA + multi-token)
|
|
2624
|
-
* @returns Transaction hashes for EXA and multi-token claims
|
|
2625
|
-
*/
|
|
2626
|
-
async claimAllRewards() {
|
|
2627
|
-
const exaRewards = await this.staking.claimRewards();
|
|
2628
|
-
const multiTokenRewards = await this.staking.claimRewardsMulti();
|
|
2629
|
-
return { exaRewards, multiTokenRewards };
|
|
2630
|
-
}
|
|
2631
1701
|
// ============ ERC-8004 Global Agent Identity ============
|
|
2632
1702
|
/**
|
|
2633
1703
|
* Get the ERC-8004 global agent identifier for the current agent
|
|
@@ -2724,20 +1794,9 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2724
1794
|
{ type: "function", name: "allowedAssets", inputs: [{ name: "asset", type: "address" }], outputs: [{ type: "bool" }], stateMutability: "view" },
|
|
2725
1795
|
{ type: "function", name: "vaults", inputs: [{ name: "agentId", type: "uint256" }, { name: "asset", type: "address" }], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2726
1796
|
{ type: "function", name: "agentVaultCount", inputs: [{ name: "agentId", type: "uint256" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
inputs: [{ name: "creator", type: "address" }],
|
|
2731
|
-
outputs: [{ name: "canCreate", type: "bool" }, { name: "reason", type: "string" }],
|
|
2732
|
-
stateMutability: "view"
|
|
2733
|
-
},
|
|
2734
|
-
{
|
|
2735
|
-
type: "function",
|
|
2736
|
-
name: "canCreateVerifiedVault",
|
|
2737
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
2738
|
-
outputs: [{ name: "isVerified", type: "bool" }, { name: "reason", type: "string" }],
|
|
2739
|
-
stateMutability: "view"
|
|
2740
|
-
},
|
|
1797
|
+
// NOTE: canCreateVault() and canCreateVerifiedVault() do not exist on the
|
|
1798
|
+
// deployed ExagentVaultFactoryV2 contract. SDK methods that called these
|
|
1799
|
+
// now use inline validation (allowedAssets, vaults, MIN_SEED_AMOUNT) instead.
|
|
2741
1800
|
// Write functions
|
|
2742
1801
|
{
|
|
2743
1802
|
type: "function",
|
|
@@ -2798,12 +1857,7 @@ var ExagentVaultFactory = class {
|
|
|
2798
1857
|
* Get vault creation requirements (mainnet: seed-based, no burn fee)
|
|
2799
1858
|
*/
|
|
2800
1859
|
async getRequirements() {
|
|
2801
|
-
const [
|
|
2802
|
-
this.publicClient.readContract({
|
|
2803
|
-
address: this.address,
|
|
2804
|
-
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2805
|
-
functionName: "VERIFIED_VEXA_REQUIREMENT"
|
|
2806
|
-
}),
|
|
1860
|
+
const [minSeedAmount, unverifiedCapMultiplier, verifiedCapMultiplier] = await Promise.all([
|
|
2807
1861
|
this.publicClient.readContract({
|
|
2808
1862
|
address: this.address,
|
|
2809
1863
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
@@ -2818,52 +1872,29 @@ var ExagentVaultFactory = class {
|
|
|
2818
1872
|
address: this.address,
|
|
2819
1873
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2820
1874
|
functionName: "VERIFIED_CAP_MULTIPLIER"
|
|
2821
|
-
}),
|
|
2822
|
-
this.publicClient.readContract({
|
|
2823
|
-
address: this.address,
|
|
2824
|
-
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2825
|
-
functionName: "stakingContract"
|
|
2826
1875
|
})
|
|
2827
1876
|
]);
|
|
2828
1877
|
return {
|
|
2829
|
-
veXARequired,
|
|
2830
1878
|
minSeedAmount,
|
|
2831
1879
|
unverifiedCapMultiplier,
|
|
2832
|
-
verifiedCapMultiplier
|
|
2833
|
-
stakingContract
|
|
1880
|
+
verifiedCapMultiplier
|
|
2834
1881
|
};
|
|
2835
1882
|
}
|
|
2836
1883
|
/**
|
|
2837
|
-
* Check if an address can create a vault
|
|
1884
|
+
* Check if an address can create a vault.
|
|
1885
|
+
* Performs inline validation since the on-chain contract does not expose
|
|
1886
|
+
* a canCreateVault() view function.
|
|
2838
1887
|
* @param creator Address to check
|
|
2839
1888
|
*/
|
|
2840
1889
|
async canCreateVault(creator) {
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
}
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
reason: result[1]
|
|
2850
|
-
};
|
|
2851
|
-
}
|
|
2852
|
-
/**
|
|
2853
|
-
* Check if an agent can create a verified vault (higher deposit cap)
|
|
2854
|
-
* @param agentId Agent ID to check
|
|
2855
|
-
*/
|
|
2856
|
-
async canCreateVerifiedVault(agentId) {
|
|
2857
|
-
const result = await this.publicClient.readContract({
|
|
2858
|
-
address: this.address,
|
|
2859
|
-
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2860
|
-
functionName: "canCreateVerifiedVault",
|
|
2861
|
-
args: [agentId]
|
|
2862
|
-
});
|
|
2863
|
-
return {
|
|
2864
|
-
isVerified: result[0],
|
|
2865
|
-
reason: result[1]
|
|
2866
|
-
};
|
|
1890
|
+
try {
|
|
1891
|
+
const isUsdcAllowed = await this.isAssetAllowed("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913");
|
|
1892
|
+
if (!isUsdcAllowed) {
|
|
1893
|
+
return { canCreate: false, reason: "USDC is not an allowed asset" };
|
|
1894
|
+
}
|
|
1895
|
+
} catch {
|
|
1896
|
+
}
|
|
1897
|
+
return { canCreate: true, reason: "" };
|
|
2867
1898
|
}
|
|
2868
1899
|
/**
|
|
2869
1900
|
* Check if an asset is whitelisted for vault creation
|
|
@@ -3015,11 +2046,9 @@ export {
|
|
|
3015
2046
|
EXAGENT_API_CONFIG,
|
|
3016
2047
|
EXAGENT_REGISTRY_ABI,
|
|
3017
2048
|
EXAGENT_ROUTER_ABI,
|
|
3018
|
-
EXAGENT_STAKING_ABI,
|
|
3019
2049
|
EXAGENT_VAULT_FACTORY_ABI,
|
|
3020
2050
|
ExagentClient,
|
|
3021
2051
|
ExagentRegistry,
|
|
3022
|
-
ExagentStaking,
|
|
3023
2052
|
ExagentVault,
|
|
3024
2053
|
ExagentVaultFactory,
|
|
3025
2054
|
SDK_VERSION,
|