@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.js
CHANGED
|
@@ -27,11 +27,9 @@ __export(index_exports, {
|
|
|
27
27
|
EXAGENT_API_CONFIG: () => EXAGENT_API_CONFIG,
|
|
28
28
|
EXAGENT_REGISTRY_ABI: () => EXAGENT_REGISTRY_ABI,
|
|
29
29
|
EXAGENT_ROUTER_ABI: () => EXAGENT_ROUTER_ABI,
|
|
30
|
-
EXAGENT_STAKING_ABI: () => EXAGENT_STAKING_ABI,
|
|
31
30
|
EXAGENT_VAULT_FACTORY_ABI: () => EXAGENT_VAULT_FACTORY_ABI,
|
|
32
31
|
ExagentClient: () => ExagentClient,
|
|
33
32
|
ExagentRegistry: () => ExagentRegistry,
|
|
34
|
-
ExagentStaking: () => ExagentStaking,
|
|
35
33
|
ExagentVault: () => ExagentVault,
|
|
36
34
|
ExagentVaultFactory: () => ExagentVaultFactory,
|
|
37
35
|
SDK_VERSION: () => SDK_VERSION,
|
|
@@ -1199,821 +1197,6 @@ var ExagentVault = class {
|
|
|
1199
1197
|
}
|
|
1200
1198
|
};
|
|
1201
1199
|
|
|
1202
|
-
// src/contracts/staking.ts
|
|
1203
|
-
var EXAGENT_STAKING_ABI = [
|
|
1204
|
-
// ============ State Variables ============
|
|
1205
|
-
{ type: "function", name: "exaToken", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
1206
|
-
{ type: "function", name: "totalDeposited", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1207
|
-
{ type: "function", name: "totalLocked", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1208
|
-
{ type: "function", name: "totalVeEXA", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1209
|
-
{ type: "function", name: "totalEffectiveVeEXA", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1210
|
-
// ============ Constants ============
|
|
1211
|
-
{ type: "function", name: "MIN_LOCK_DURATION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1212
|
-
{ type: "function", name: "MAX_LOCK_DURATION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1213
|
-
{ type: "function", name: "VAULT_ACCESS_THRESHOLD", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1214
|
-
{ type: "function", name: "PRECISION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1215
|
-
// ============ Phase 1: Deposit / Withdraw ============
|
|
1216
|
-
{
|
|
1217
|
-
type: "function",
|
|
1218
|
-
name: "deposit",
|
|
1219
|
-
inputs: [{ name: "amount", type: "uint256" }],
|
|
1220
|
-
outputs: [],
|
|
1221
|
-
stateMutability: "nonpayable"
|
|
1222
|
-
},
|
|
1223
|
-
{
|
|
1224
|
-
type: "function",
|
|
1225
|
-
name: "withdraw",
|
|
1226
|
-
inputs: [{ name: "amount", type: "uint256" }],
|
|
1227
|
-
outputs: [],
|
|
1228
|
-
stateMutability: "nonpayable"
|
|
1229
|
-
},
|
|
1230
|
-
// ============ Phase 2: Lock / Unlock ============
|
|
1231
|
-
{
|
|
1232
|
-
type: "function",
|
|
1233
|
-
name: "lock",
|
|
1234
|
-
inputs: [
|
|
1235
|
-
{ name: "amount", type: "uint256" },
|
|
1236
|
-
{ name: "lockDuration", type: "uint256" }
|
|
1237
|
-
],
|
|
1238
|
-
outputs: [],
|
|
1239
|
-
stateMutability: "nonpayable"
|
|
1240
|
-
},
|
|
1241
|
-
{
|
|
1242
|
-
type: "function",
|
|
1243
|
-
name: "extendLock",
|
|
1244
|
-
inputs: [{ name: "newLockDuration", type: "uint256" }],
|
|
1245
|
-
outputs: [],
|
|
1246
|
-
stateMutability: "nonpayable"
|
|
1247
|
-
},
|
|
1248
|
-
{ type: "function", name: "unlock", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1249
|
-
{ type: "function", name: "emergencyWithdraw", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1250
|
-
// ============ Reward Functions ============
|
|
1251
|
-
{ type: "function", name: "claimRewards", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1252
|
-
{ type: "function", name: "claimRewardsMulti", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1253
|
-
{
|
|
1254
|
-
type: "function",
|
|
1255
|
-
name: "claimRewardsToken",
|
|
1256
|
-
inputs: [{ name: "token", type: "address" }],
|
|
1257
|
-
outputs: [],
|
|
1258
|
-
stateMutability: "nonpayable"
|
|
1259
|
-
},
|
|
1260
|
-
// ============ View Functions ============
|
|
1261
|
-
{
|
|
1262
|
-
type: "function",
|
|
1263
|
-
name: "depositedAmount",
|
|
1264
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1265
|
-
outputs: [{ type: "uint256" }],
|
|
1266
|
-
stateMutability: "view"
|
|
1267
|
-
},
|
|
1268
|
-
{
|
|
1269
|
-
type: "function",
|
|
1270
|
-
name: "locks",
|
|
1271
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1272
|
-
outputs: [
|
|
1273
|
-
{ name: "amount", type: "uint256" },
|
|
1274
|
-
{ name: "unlockTime", type: "uint256" },
|
|
1275
|
-
{ name: "lockDuration", type: "uint256" },
|
|
1276
|
-
{ name: "vEXABalance", type: "uint256" }
|
|
1277
|
-
],
|
|
1278
|
-
stateMutability: "view"
|
|
1279
|
-
},
|
|
1280
|
-
{
|
|
1281
|
-
type: "function",
|
|
1282
|
-
name: "getVeEXABalance",
|
|
1283
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1284
|
-
outputs: [{ type: "uint256" }],
|
|
1285
|
-
stateMutability: "view"
|
|
1286
|
-
},
|
|
1287
|
-
{
|
|
1288
|
-
type: "function",
|
|
1289
|
-
name: "getEffectiveVeEXA",
|
|
1290
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1291
|
-
outputs: [{ type: "uint256" }],
|
|
1292
|
-
stateMutability: "view"
|
|
1293
|
-
},
|
|
1294
|
-
{
|
|
1295
|
-
type: "function",
|
|
1296
|
-
name: "calculateVeEXA",
|
|
1297
|
-
inputs: [
|
|
1298
|
-
{ name: "amount", type: "uint256" },
|
|
1299
|
-
{ name: "lockDuration", type: "uint256" }
|
|
1300
|
-
],
|
|
1301
|
-
outputs: [{ type: "uint256" }],
|
|
1302
|
-
stateMutability: "pure"
|
|
1303
|
-
},
|
|
1304
|
-
{
|
|
1305
|
-
type: "function",
|
|
1306
|
-
name: "pendingRewards",
|
|
1307
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1308
|
-
outputs: [{ type: "uint256" }],
|
|
1309
|
-
stateMutability: "view"
|
|
1310
|
-
},
|
|
1311
|
-
{
|
|
1312
|
-
type: "function",
|
|
1313
|
-
name: "pendingRewardsForToken",
|
|
1314
|
-
inputs: [
|
|
1315
|
-
{ name: "user", type: "address" },
|
|
1316
|
-
{ name: "token", type: "address" }
|
|
1317
|
-
],
|
|
1318
|
-
outputs: [{ type: "uint256" }],
|
|
1319
|
-
stateMutability: "view"
|
|
1320
|
-
},
|
|
1321
|
-
{
|
|
1322
|
-
type: "function",
|
|
1323
|
-
name: "getEarningsTier",
|
|
1324
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1325
|
-
outputs: [
|
|
1326
|
-
{ name: "multiplierBps", type: "uint256" },
|
|
1327
|
-
{ name: "tierName", type: "string" }
|
|
1328
|
-
],
|
|
1329
|
-
stateMutability: "view"
|
|
1330
|
-
},
|
|
1331
|
-
{
|
|
1332
|
-
type: "function",
|
|
1333
|
-
name: "getEmergencyWithdrawPenalty",
|
|
1334
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1335
|
-
outputs: [{ name: "penaltyBps", type: "uint256" }],
|
|
1336
|
-
stateMutability: "view"
|
|
1337
|
-
},
|
|
1338
|
-
{
|
|
1339
|
-
type: "function",
|
|
1340
|
-
name: "hasVaultAccess",
|
|
1341
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1342
|
-
outputs: [{ type: "bool" }],
|
|
1343
|
-
stateMutability: "view"
|
|
1344
|
-
},
|
|
1345
|
-
{
|
|
1346
|
-
type: "function",
|
|
1347
|
-
name: "getUnlockedBalance",
|
|
1348
|
-
inputs: [{ name: "user", type: "address" }],
|
|
1349
|
-
outputs: [{ type: "uint256" }],
|
|
1350
|
-
stateMutability: "view"
|
|
1351
|
-
},
|
|
1352
|
-
{
|
|
1353
|
-
type: "function",
|
|
1354
|
-
name: "getRewardTokens",
|
|
1355
|
-
inputs: [],
|
|
1356
|
-
outputs: [{ type: "address[]" }],
|
|
1357
|
-
stateMutability: "view"
|
|
1358
|
-
},
|
|
1359
|
-
{
|
|
1360
|
-
type: "function",
|
|
1361
|
-
name: "isRewardToken",
|
|
1362
|
-
inputs: [{ name: "token", type: "address" }],
|
|
1363
|
-
outputs: [{ type: "bool" }],
|
|
1364
|
-
stateMutability: "view"
|
|
1365
|
-
},
|
|
1366
|
-
// ============ Events ============
|
|
1367
|
-
{
|
|
1368
|
-
type: "event",
|
|
1369
|
-
name: "Deposited",
|
|
1370
|
-
inputs: [
|
|
1371
|
-
{ name: "user", type: "address", indexed: true },
|
|
1372
|
-
{ name: "amount", type: "uint256", indexed: false },
|
|
1373
|
-
{ name: "totalDeposited", type: "uint256", indexed: false }
|
|
1374
|
-
]
|
|
1375
|
-
},
|
|
1376
|
-
{
|
|
1377
|
-
type: "event",
|
|
1378
|
-
name: "Withdrawn",
|
|
1379
|
-
inputs: [
|
|
1380
|
-
{ name: "user", type: "address", indexed: true },
|
|
1381
|
-
{ name: "amount", type: "uint256", indexed: false },
|
|
1382
|
-
{ name: "totalDeposited", type: "uint256", indexed: false }
|
|
1383
|
-
]
|
|
1384
|
-
},
|
|
1385
|
-
{
|
|
1386
|
-
type: "event",
|
|
1387
|
-
name: "Locked",
|
|
1388
|
-
inputs: [
|
|
1389
|
-
{ name: "user", type: "address", indexed: true },
|
|
1390
|
-
{ name: "amount", type: "uint256", indexed: false },
|
|
1391
|
-
{ name: "lockDuration", type: "uint256", indexed: false },
|
|
1392
|
-
{ name: "unlockTime", type: "uint256", indexed: false },
|
|
1393
|
-
{ name: "vEXABalance", type: "uint256", indexed: false }
|
|
1394
|
-
]
|
|
1395
|
-
},
|
|
1396
|
-
{
|
|
1397
|
-
type: "event",
|
|
1398
|
-
name: "Unlocked",
|
|
1399
|
-
inputs: [
|
|
1400
|
-
{ name: "user", type: "address", indexed: true },
|
|
1401
|
-
{ name: "amount", type: "uint256", indexed: false }
|
|
1402
|
-
]
|
|
1403
|
-
},
|
|
1404
|
-
{
|
|
1405
|
-
type: "event",
|
|
1406
|
-
name: "EmergencyWithdrawal",
|
|
1407
|
-
inputs: [
|
|
1408
|
-
{ name: "user", type: "address", indexed: true },
|
|
1409
|
-
{ name: "returned", type: "uint256", indexed: false },
|
|
1410
|
-
{ name: "penalty", type: "uint256", indexed: false },
|
|
1411
|
-
{ name: "penaltyBps", type: "uint256", indexed: false }
|
|
1412
|
-
]
|
|
1413
|
-
},
|
|
1414
|
-
{
|
|
1415
|
-
type: "event",
|
|
1416
|
-
name: "LockExtended",
|
|
1417
|
-
inputs: [
|
|
1418
|
-
{ name: "user", type: "address", indexed: true },
|
|
1419
|
-
{ name: "newUnlockTime", type: "uint256", indexed: false },
|
|
1420
|
-
{ name: "newVeEXABalance", type: "uint256", indexed: false }
|
|
1421
|
-
]
|
|
1422
|
-
},
|
|
1423
|
-
{
|
|
1424
|
-
type: "event",
|
|
1425
|
-
name: "RewardsClaimed",
|
|
1426
|
-
inputs: [
|
|
1427
|
-
{ name: "user", type: "address", indexed: true },
|
|
1428
|
-
{ name: "amount", type: "uint256", indexed: false }
|
|
1429
|
-
]
|
|
1430
|
-
},
|
|
1431
|
-
{
|
|
1432
|
-
type: "event",
|
|
1433
|
-
name: "MultiTokenRewardsClaimed",
|
|
1434
|
-
inputs: [
|
|
1435
|
-
{ name: "user", type: "address", indexed: true },
|
|
1436
|
-
{ name: "token", type: "address", indexed: true },
|
|
1437
|
-
{ name: "amount", type: "uint256", indexed: false }
|
|
1438
|
-
]
|
|
1439
|
-
}
|
|
1440
|
-
];
|
|
1441
|
-
var ERC20_APPROVE_ABI2 = [
|
|
1442
|
-
{
|
|
1443
|
-
type: "function",
|
|
1444
|
-
name: "approve",
|
|
1445
|
-
inputs: [
|
|
1446
|
-
{ name: "spender", type: "address" },
|
|
1447
|
-
{ name: "amount", type: "uint256" }
|
|
1448
|
-
],
|
|
1449
|
-
outputs: [{ type: "bool" }],
|
|
1450
|
-
stateMutability: "nonpayable"
|
|
1451
|
-
}
|
|
1452
|
-
];
|
|
1453
|
-
var ExagentStaking = class {
|
|
1454
|
-
address;
|
|
1455
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1456
|
-
publicClient;
|
|
1457
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1458
|
-
walletClient;
|
|
1459
|
-
chain;
|
|
1460
|
-
account;
|
|
1461
|
-
constructor(stakingAddress, publicClient, walletClient, chain, account) {
|
|
1462
|
-
this.address = stakingAddress;
|
|
1463
|
-
this.publicClient = publicClient;
|
|
1464
|
-
this.walletClient = walletClient;
|
|
1465
|
-
if (!chain) {
|
|
1466
|
-
throw new Error("Chain parameter is required");
|
|
1467
|
-
}
|
|
1468
|
-
this.chain = chain;
|
|
1469
|
-
this.account = account;
|
|
1470
|
-
}
|
|
1471
|
-
// ============ Phase 1: Deposit / Withdraw ============
|
|
1472
|
-
/**
|
|
1473
|
-
* Deposit EXA tokens for vault access (no lock required)
|
|
1474
|
-
* @param amount Amount of EXA to deposit (in wei)
|
|
1475
|
-
* @returns Transaction hash
|
|
1476
|
-
*
|
|
1477
|
-
* @example
|
|
1478
|
-
* ```typescript
|
|
1479
|
-
* // Deposit 1000 EXA to unlock vault access
|
|
1480
|
-
* const tx = await staking.deposit(parseEther('1000'));
|
|
1481
|
-
* ```
|
|
1482
|
-
*/
|
|
1483
|
-
async deposit(amount) {
|
|
1484
|
-
if (!this.walletClient || !this.account) {
|
|
1485
|
-
throw new Error("Wallet client required for write operations");
|
|
1486
|
-
}
|
|
1487
|
-
const hash = await this.walletClient.writeContract({
|
|
1488
|
-
address: this.address,
|
|
1489
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1490
|
-
functionName: "deposit",
|
|
1491
|
-
args: [amount],
|
|
1492
|
-
account: this.account,
|
|
1493
|
-
chain: this.chain
|
|
1494
|
-
});
|
|
1495
|
-
return hash;
|
|
1496
|
-
}
|
|
1497
|
-
/**
|
|
1498
|
-
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
1499
|
-
* @param amount Amount of EXA to withdraw (in wei)
|
|
1500
|
-
* @returns Transaction hash
|
|
1501
|
-
*/
|
|
1502
|
-
async withdraw(amount) {
|
|
1503
|
-
if (!this.walletClient || !this.account) {
|
|
1504
|
-
throw new Error("Wallet client required for write operations");
|
|
1505
|
-
}
|
|
1506
|
-
const hash = await this.walletClient.writeContract({
|
|
1507
|
-
address: this.address,
|
|
1508
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1509
|
-
functionName: "withdraw",
|
|
1510
|
-
args: [amount],
|
|
1511
|
-
account: this.account,
|
|
1512
|
-
chain: this.chain
|
|
1513
|
-
});
|
|
1514
|
-
return hash;
|
|
1515
|
-
}
|
|
1516
|
-
// ============ Phase 2: Lock / Unlock ============
|
|
1517
|
-
/**
|
|
1518
|
-
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
1519
|
-
* @param amount Amount of deposited EXA to lock (in wei)
|
|
1520
|
-
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
1521
|
-
* @returns Transaction hash
|
|
1522
|
-
*
|
|
1523
|
-
* @example
|
|
1524
|
-
* ```typescript
|
|
1525
|
-
* // Lock 1000 EXA for 6 months
|
|
1526
|
-
* const tx = await staking.lock(
|
|
1527
|
-
* parseEther('1000'),
|
|
1528
|
-
* ExagentStaking.LOCK_6_MONTHS
|
|
1529
|
-
* );
|
|
1530
|
-
* ```
|
|
1531
|
-
*/
|
|
1532
|
-
async lock(amount, lockDuration) {
|
|
1533
|
-
if (!this.walletClient || !this.account) {
|
|
1534
|
-
throw new Error("Wallet client required for write operations");
|
|
1535
|
-
}
|
|
1536
|
-
const hash = await this.walletClient.writeContract({
|
|
1537
|
-
address: this.address,
|
|
1538
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1539
|
-
functionName: "lock",
|
|
1540
|
-
args: [amount, lockDuration],
|
|
1541
|
-
account: this.account,
|
|
1542
|
-
chain: this.chain
|
|
1543
|
-
});
|
|
1544
|
-
return hash;
|
|
1545
|
-
}
|
|
1546
|
-
/**
|
|
1547
|
-
* Extend lock duration for additional voting power
|
|
1548
|
-
* @param newLockDuration New lock duration in seconds (must be longer than remaining)
|
|
1549
|
-
* @returns Transaction hash
|
|
1550
|
-
*/
|
|
1551
|
-
async extendLock(newLockDuration) {
|
|
1552
|
-
if (!this.walletClient || !this.account) {
|
|
1553
|
-
throw new Error("Wallet client required for write operations");
|
|
1554
|
-
}
|
|
1555
|
-
const hash = await this.walletClient.writeContract({
|
|
1556
|
-
address: this.address,
|
|
1557
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1558
|
-
functionName: "extendLock",
|
|
1559
|
-
args: [newLockDuration],
|
|
1560
|
-
account: this.account,
|
|
1561
|
-
chain: this.chain
|
|
1562
|
-
});
|
|
1563
|
-
return hash;
|
|
1564
|
-
}
|
|
1565
|
-
/**
|
|
1566
|
-
* Unlock EXA after lock expires (normal path — no penalty)
|
|
1567
|
-
* Returns locked amount to unlocked deposited balance.
|
|
1568
|
-
* @returns Transaction hash
|
|
1569
|
-
*/
|
|
1570
|
-
async unlock() {
|
|
1571
|
-
if (!this.walletClient || !this.account) {
|
|
1572
|
-
throw new Error("Wallet client required for write operations");
|
|
1573
|
-
}
|
|
1574
|
-
const hash = await this.walletClient.writeContract({
|
|
1575
|
-
address: this.address,
|
|
1576
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1577
|
-
functionName: "unlock",
|
|
1578
|
-
args: [],
|
|
1579
|
-
account: this.account,
|
|
1580
|
-
chain: this.chain
|
|
1581
|
-
});
|
|
1582
|
-
return hash;
|
|
1583
|
-
}
|
|
1584
|
-
/**
|
|
1585
|
-
* Emergency withdrawal — instant exit from lock with graduated penalty
|
|
1586
|
-
* Two-phase penalty: 50%→20% over the first quarter of the lock, then flat 20% until expiry.
|
|
1587
|
-
* Penalty goes to treasury. Remaining returns to unlocked deposit balance.
|
|
1588
|
-
* @returns Transaction hash
|
|
1589
|
-
*/
|
|
1590
|
-
async emergencyWithdraw() {
|
|
1591
|
-
if (!this.walletClient || !this.account) {
|
|
1592
|
-
throw new Error("Wallet client required for write operations");
|
|
1593
|
-
}
|
|
1594
|
-
const hash = await this.walletClient.writeContract({
|
|
1595
|
-
address: this.address,
|
|
1596
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1597
|
-
functionName: "emergencyWithdraw",
|
|
1598
|
-
args: [],
|
|
1599
|
-
account: this.account,
|
|
1600
|
-
chain: this.chain
|
|
1601
|
-
});
|
|
1602
|
-
return hash;
|
|
1603
|
-
}
|
|
1604
|
-
// ============ Reward Functions ============
|
|
1605
|
-
/**
|
|
1606
|
-
* Claim accumulated EXA rewards
|
|
1607
|
-
* @returns Transaction hash
|
|
1608
|
-
*/
|
|
1609
|
-
async claimRewards() {
|
|
1610
|
-
if (!this.walletClient || !this.account) {
|
|
1611
|
-
throw new Error("Wallet client required for write operations");
|
|
1612
|
-
}
|
|
1613
|
-
const hash = await this.walletClient.writeContract({
|
|
1614
|
-
address: this.address,
|
|
1615
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1616
|
-
functionName: "claimRewards",
|
|
1617
|
-
args: [],
|
|
1618
|
-
account: this.account,
|
|
1619
|
-
chain: this.chain
|
|
1620
|
-
});
|
|
1621
|
-
return hash;
|
|
1622
|
-
}
|
|
1623
|
-
/**
|
|
1624
|
-
* Claim all pending multi-token rewards (ETH, USDC, etc.)
|
|
1625
|
-
* @returns Transaction hash
|
|
1626
|
-
*/
|
|
1627
|
-
async claimRewardsMulti() {
|
|
1628
|
-
if (!this.walletClient || !this.account) {
|
|
1629
|
-
throw new Error("Wallet client required for write operations");
|
|
1630
|
-
}
|
|
1631
|
-
const hash = await this.walletClient.writeContract({
|
|
1632
|
-
address: this.address,
|
|
1633
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1634
|
-
functionName: "claimRewardsMulti",
|
|
1635
|
-
args: [],
|
|
1636
|
-
account: this.account,
|
|
1637
|
-
chain: this.chain
|
|
1638
|
-
});
|
|
1639
|
-
return hash;
|
|
1640
|
-
}
|
|
1641
|
-
/**
|
|
1642
|
-
* Claim pending rewards for a specific token
|
|
1643
|
-
* @param token The reward token address to claim
|
|
1644
|
-
* @returns Transaction hash
|
|
1645
|
-
*/
|
|
1646
|
-
async claimRewardsToken(token) {
|
|
1647
|
-
if (!this.walletClient || !this.account) {
|
|
1648
|
-
throw new Error("Wallet client required for write operations");
|
|
1649
|
-
}
|
|
1650
|
-
const hash = await this.walletClient.writeContract({
|
|
1651
|
-
address: this.address,
|
|
1652
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1653
|
-
functionName: "claimRewardsToken",
|
|
1654
|
-
args: [token],
|
|
1655
|
-
account: this.account,
|
|
1656
|
-
chain: this.chain
|
|
1657
|
-
});
|
|
1658
|
-
return hash;
|
|
1659
|
-
}
|
|
1660
|
-
// ============ Read Functions ============
|
|
1661
|
-
/**
|
|
1662
|
-
* Get comprehensive staking info for a user (deposit + lock)
|
|
1663
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1664
|
-
* @returns Combined staking info
|
|
1665
|
-
*/
|
|
1666
|
-
async getStakingInfo(userAddress) {
|
|
1667
|
-
const user = userAddress ?? this.account?.address;
|
|
1668
|
-
if (!user) {
|
|
1669
|
-
throw new Error("User address required");
|
|
1670
|
-
}
|
|
1671
|
-
const [deposited, lockResult, currentVeEXA, vaultAccess, unlockedBalance] = await Promise.all([
|
|
1672
|
-
this.publicClient.readContract({
|
|
1673
|
-
address: this.address,
|
|
1674
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1675
|
-
functionName: "depositedAmount",
|
|
1676
|
-
args: [user]
|
|
1677
|
-
}),
|
|
1678
|
-
this.publicClient.readContract({
|
|
1679
|
-
address: this.address,
|
|
1680
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1681
|
-
functionName: "locks",
|
|
1682
|
-
args: [user]
|
|
1683
|
-
}),
|
|
1684
|
-
this.publicClient.readContract({
|
|
1685
|
-
address: this.address,
|
|
1686
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1687
|
-
functionName: "getVeEXABalance",
|
|
1688
|
-
args: [user]
|
|
1689
|
-
}),
|
|
1690
|
-
this.publicClient.readContract({
|
|
1691
|
-
address: this.address,
|
|
1692
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1693
|
-
functionName: "hasVaultAccess",
|
|
1694
|
-
args: [user]
|
|
1695
|
-
}),
|
|
1696
|
-
this.publicClient.readContract({
|
|
1697
|
-
address: this.address,
|
|
1698
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1699
|
-
functionName: "getUnlockedBalance",
|
|
1700
|
-
args: [user]
|
|
1701
|
-
})
|
|
1702
|
-
]);
|
|
1703
|
-
const lockData = lockResult;
|
|
1704
|
-
const depositedBigint = deposited;
|
|
1705
|
-
const lockedAmount = lockData[0];
|
|
1706
|
-
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
1707
|
-
const depositInfo = {
|
|
1708
|
-
deposited: depositedBigint,
|
|
1709
|
-
locked: lockedAmount,
|
|
1710
|
-
unlocked: unlockedBalance,
|
|
1711
|
-
hasVaultAccess: vaultAccess
|
|
1712
|
-
};
|
|
1713
|
-
let lockInfo = null;
|
|
1714
|
-
if (lockedAmount > 0n) {
|
|
1715
|
-
const isUnlocked = lockData[1] <= now;
|
|
1716
|
-
const remainingLockTime = isUnlocked ? 0n : lockData[1] - now;
|
|
1717
|
-
lockInfo = {
|
|
1718
|
-
amount: lockData[0],
|
|
1719
|
-
unlockTime: lockData[1],
|
|
1720
|
-
lockDuration: lockData[2],
|
|
1721
|
-
vEXABalance: lockData[3],
|
|
1722
|
-
currentVeEXA,
|
|
1723
|
-
isUnlocked,
|
|
1724
|
-
remainingLockTime
|
|
1725
|
-
};
|
|
1726
|
-
}
|
|
1727
|
-
return { deposit: depositInfo, lock: lockInfo };
|
|
1728
|
-
}
|
|
1729
|
-
/**
|
|
1730
|
-
* Get deposit info for a user
|
|
1731
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1732
|
-
* @returns Deposit info
|
|
1733
|
-
*/
|
|
1734
|
-
async getDepositInfo(userAddress) {
|
|
1735
|
-
const user = userAddress ?? this.account?.address;
|
|
1736
|
-
if (!user) {
|
|
1737
|
-
throw new Error("User address required");
|
|
1738
|
-
}
|
|
1739
|
-
const [deposited, lockResult, vaultAccess, unlockedBalance] = await Promise.all([
|
|
1740
|
-
this.publicClient.readContract({
|
|
1741
|
-
address: this.address,
|
|
1742
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1743
|
-
functionName: "depositedAmount",
|
|
1744
|
-
args: [user]
|
|
1745
|
-
}),
|
|
1746
|
-
this.publicClient.readContract({
|
|
1747
|
-
address: this.address,
|
|
1748
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1749
|
-
functionName: "locks",
|
|
1750
|
-
args: [user]
|
|
1751
|
-
}),
|
|
1752
|
-
this.publicClient.readContract({
|
|
1753
|
-
address: this.address,
|
|
1754
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1755
|
-
functionName: "hasVaultAccess",
|
|
1756
|
-
args: [user]
|
|
1757
|
-
}),
|
|
1758
|
-
this.publicClient.readContract({
|
|
1759
|
-
address: this.address,
|
|
1760
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1761
|
-
functionName: "getUnlockedBalance",
|
|
1762
|
-
args: [user]
|
|
1763
|
-
})
|
|
1764
|
-
]);
|
|
1765
|
-
const lockData = lockResult;
|
|
1766
|
-
return {
|
|
1767
|
-
deposited,
|
|
1768
|
-
locked: lockData[0],
|
|
1769
|
-
unlocked: unlockedBalance,
|
|
1770
|
-
hasVaultAccess: vaultAccess
|
|
1771
|
-
};
|
|
1772
|
-
}
|
|
1773
|
-
/**
|
|
1774
|
-
* Get current vEXA balance (with time decay applied)
|
|
1775
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1776
|
-
* @returns Current vEXA balance
|
|
1777
|
-
*/
|
|
1778
|
-
async getVeEXABalance(userAddress) {
|
|
1779
|
-
const user = userAddress ?? this.account?.address;
|
|
1780
|
-
if (!user) {
|
|
1781
|
-
throw new Error("User address required");
|
|
1782
|
-
}
|
|
1783
|
-
return this.publicClient.readContract({
|
|
1784
|
-
address: this.address,
|
|
1785
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1786
|
-
functionName: "getVeEXABalance",
|
|
1787
|
-
args: [user]
|
|
1788
|
-
});
|
|
1789
|
-
}
|
|
1790
|
-
/**
|
|
1791
|
-
* Get effective vEXA (with tier multiplier applied)
|
|
1792
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1793
|
-
* @returns Effective vEXA balance
|
|
1794
|
-
*/
|
|
1795
|
-
async getEffectiveVeEXA(userAddress) {
|
|
1796
|
-
const user = userAddress ?? this.account?.address;
|
|
1797
|
-
if (!user) {
|
|
1798
|
-
throw new Error("User address required");
|
|
1799
|
-
}
|
|
1800
|
-
return this.publicClient.readContract({
|
|
1801
|
-
address: this.address,
|
|
1802
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1803
|
-
functionName: "getEffectiveVeEXA",
|
|
1804
|
-
args: [user]
|
|
1805
|
-
});
|
|
1806
|
-
}
|
|
1807
|
-
/**
|
|
1808
|
-
* Check if user has vault access (meets deposit threshold)
|
|
1809
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1810
|
-
* @returns True if user can access vaults
|
|
1811
|
-
*/
|
|
1812
|
-
async hasVaultAccess(userAddress) {
|
|
1813
|
-
const user = userAddress ?? this.account?.address;
|
|
1814
|
-
if (!user) {
|
|
1815
|
-
throw new Error("User address required");
|
|
1816
|
-
}
|
|
1817
|
-
return this.publicClient.readContract({
|
|
1818
|
-
address: this.address,
|
|
1819
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1820
|
-
functionName: "hasVaultAccess",
|
|
1821
|
-
args: [user]
|
|
1822
|
-
});
|
|
1823
|
-
}
|
|
1824
|
-
/**
|
|
1825
|
-
* Get earnings tier for a user (Bronze/Silver/Gold/Platinum/Diamond)
|
|
1826
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1827
|
-
* @returns Tier info with multiplier and name
|
|
1828
|
-
*/
|
|
1829
|
-
async getEarningsTier(userAddress) {
|
|
1830
|
-
const user = userAddress ?? this.account?.address;
|
|
1831
|
-
if (!user) {
|
|
1832
|
-
throw new Error("User address required");
|
|
1833
|
-
}
|
|
1834
|
-
const result = await this.publicClient.readContract({
|
|
1835
|
-
address: this.address,
|
|
1836
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1837
|
-
functionName: "getEarningsTier",
|
|
1838
|
-
args: [user]
|
|
1839
|
-
});
|
|
1840
|
-
return {
|
|
1841
|
-
multiplierBps: result[0],
|
|
1842
|
-
tierName: result[1]
|
|
1843
|
-
};
|
|
1844
|
-
}
|
|
1845
|
-
/**
|
|
1846
|
-
* Get current emergency withdrawal penalty for a user
|
|
1847
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1848
|
-
* @returns Penalty in basis points (5000 = 50% at lock start, ramps to 2000 over first 25% of lock, then flat 2000)
|
|
1849
|
-
*/
|
|
1850
|
-
async getEmergencyWithdrawPenalty(userAddress) {
|
|
1851
|
-
const user = userAddress ?? this.account?.address;
|
|
1852
|
-
if (!user) {
|
|
1853
|
-
throw new Error("User address required");
|
|
1854
|
-
}
|
|
1855
|
-
return this.publicClient.readContract({
|
|
1856
|
-
address: this.address,
|
|
1857
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1858
|
-
functionName: "getEmergencyWithdrawPenalty",
|
|
1859
|
-
args: [user]
|
|
1860
|
-
});
|
|
1861
|
-
}
|
|
1862
|
-
/**
|
|
1863
|
-
* Get pending EXA rewards for a user
|
|
1864
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1865
|
-
* @returns Pending reward amount in wei
|
|
1866
|
-
*/
|
|
1867
|
-
async pendingRewards(userAddress) {
|
|
1868
|
-
const user = userAddress ?? this.account?.address;
|
|
1869
|
-
if (!user) {
|
|
1870
|
-
throw new Error("User address required");
|
|
1871
|
-
}
|
|
1872
|
-
return this.publicClient.readContract({
|
|
1873
|
-
address: this.address,
|
|
1874
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1875
|
-
functionName: "pendingRewards",
|
|
1876
|
-
args: [user]
|
|
1877
|
-
});
|
|
1878
|
-
}
|
|
1879
|
-
/**
|
|
1880
|
-
* Get pending rewards for a specific token
|
|
1881
|
-
* @param token The reward token address
|
|
1882
|
-
* @param userAddress Address to check (defaults to connected wallet)
|
|
1883
|
-
* @returns Pending reward amount in wei
|
|
1884
|
-
*/
|
|
1885
|
-
async pendingRewardsMulti(token, userAddress) {
|
|
1886
|
-
const user = userAddress ?? this.account?.address;
|
|
1887
|
-
if (!user) {
|
|
1888
|
-
throw new Error("User address required");
|
|
1889
|
-
}
|
|
1890
|
-
return this.publicClient.readContract({
|
|
1891
|
-
address: this.address,
|
|
1892
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1893
|
-
functionName: "pendingRewardsForToken",
|
|
1894
|
-
args: [user, token]
|
|
1895
|
-
});
|
|
1896
|
-
}
|
|
1897
|
-
/**
|
|
1898
|
-
* Get list of whitelisted reward tokens
|
|
1899
|
-
* @returns Array of reward token addresses
|
|
1900
|
-
*/
|
|
1901
|
-
async getRewardTokens() {
|
|
1902
|
-
return this.publicClient.readContract({
|
|
1903
|
-
address: this.address,
|
|
1904
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1905
|
-
functionName: "getRewardTokens"
|
|
1906
|
-
});
|
|
1907
|
-
}
|
|
1908
|
-
/**
|
|
1909
|
-
* Check if a token is whitelisted for rewards
|
|
1910
|
-
* @param token The token address to check
|
|
1911
|
-
* @returns True if token is whitelisted
|
|
1912
|
-
*/
|
|
1913
|
-
async isRewardToken(token) {
|
|
1914
|
-
return this.publicClient.readContract({
|
|
1915
|
-
address: this.address,
|
|
1916
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1917
|
-
functionName: "isRewardToken",
|
|
1918
|
-
args: [token]
|
|
1919
|
-
});
|
|
1920
|
-
}
|
|
1921
|
-
/**
|
|
1922
|
-
* Get total EXA deposited across all users
|
|
1923
|
-
* @returns Total deposited amount in wei
|
|
1924
|
-
*/
|
|
1925
|
-
async getTotalDeposited() {
|
|
1926
|
-
return this.publicClient.readContract({
|
|
1927
|
-
address: this.address,
|
|
1928
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1929
|
-
functionName: "totalDeposited"
|
|
1930
|
-
});
|
|
1931
|
-
}
|
|
1932
|
-
/**
|
|
1933
|
-
* Get total EXA locked across all users
|
|
1934
|
-
* @returns Total locked amount in wei
|
|
1935
|
-
*/
|
|
1936
|
-
async getTotalLocked() {
|
|
1937
|
-
return this.publicClient.readContract({
|
|
1938
|
-
address: this.address,
|
|
1939
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1940
|
-
functionName: "totalLocked"
|
|
1941
|
-
});
|
|
1942
|
-
}
|
|
1943
|
-
/**
|
|
1944
|
-
* Get total vEXA supply across all users
|
|
1945
|
-
* @returns Total vEXA supply
|
|
1946
|
-
*/
|
|
1947
|
-
async getTotalVeEXA() {
|
|
1948
|
-
return this.publicClient.readContract({
|
|
1949
|
-
address: this.address,
|
|
1950
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1951
|
-
functionName: "totalVeEXA"
|
|
1952
|
-
});
|
|
1953
|
-
}
|
|
1954
|
-
/**
|
|
1955
|
-
* Calculate vEXA balance for a given lock (preview)
|
|
1956
|
-
* @param amount Amount of EXA to lock
|
|
1957
|
-
* @param lockDuration Lock duration in seconds
|
|
1958
|
-
* @returns Expected vEXA balance
|
|
1959
|
-
*/
|
|
1960
|
-
async calculateVeEXA(amount, lockDuration) {
|
|
1961
|
-
return this.publicClient.readContract({
|
|
1962
|
-
address: this.address,
|
|
1963
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1964
|
-
functionName: "calculateVeEXA",
|
|
1965
|
-
args: [amount, lockDuration]
|
|
1966
|
-
});
|
|
1967
|
-
}
|
|
1968
|
-
/**
|
|
1969
|
-
* Get the EXA token address
|
|
1970
|
-
* @returns EXA token contract address
|
|
1971
|
-
*/
|
|
1972
|
-
async getExaTokenAddress() {
|
|
1973
|
-
return this.publicClient.readContract({
|
|
1974
|
-
address: this.address,
|
|
1975
|
-
abi: EXAGENT_STAKING_ABI,
|
|
1976
|
-
functionName: "exaToken"
|
|
1977
|
-
});
|
|
1978
|
-
}
|
|
1979
|
-
// ============ Helper Functions ============
|
|
1980
|
-
/**
|
|
1981
|
-
* Approve EXA token spending for deposits
|
|
1982
|
-
* @param amount Amount to approve
|
|
1983
|
-
* @returns Transaction hash
|
|
1984
|
-
*/
|
|
1985
|
-
async approveExa(amount) {
|
|
1986
|
-
if (!this.walletClient || !this.account) {
|
|
1987
|
-
throw new Error("Wallet client required for write operations");
|
|
1988
|
-
}
|
|
1989
|
-
const exaToken = await this.getExaTokenAddress();
|
|
1990
|
-
const hash = await this.walletClient.writeContract({
|
|
1991
|
-
address: exaToken,
|
|
1992
|
-
abi: ERC20_APPROVE_ABI2,
|
|
1993
|
-
functionName: "approve",
|
|
1994
|
-
args: [this.address, amount],
|
|
1995
|
-
account: this.account,
|
|
1996
|
-
chain: this.chain
|
|
1997
|
-
});
|
|
1998
|
-
return hash;
|
|
1999
|
-
}
|
|
2000
|
-
// ============ Lock Duration Constants ============
|
|
2001
|
-
/** Minimum lock duration: 30 days in seconds */
|
|
2002
|
-
static MIN_LOCK_DURATION = 30n * 24n * 60n * 60n;
|
|
2003
|
-
/** Maximum lock duration: 2 years in seconds */
|
|
2004
|
-
static MAX_LOCK_DURATION = 730n * 24n * 60n * 60n;
|
|
2005
|
-
/** 1 month lock duration in seconds */
|
|
2006
|
-
static LOCK_1_MONTH = 30n * 24n * 60n * 60n;
|
|
2007
|
-
/** 3 months lock duration in seconds */
|
|
2008
|
-
static LOCK_3_MONTHS = 90n * 24n * 60n * 60n;
|
|
2009
|
-
/** 6 months lock duration in seconds */
|
|
2010
|
-
static LOCK_6_MONTHS = 180n * 24n * 60n * 60n;
|
|
2011
|
-
/** 1 year lock duration in seconds */
|
|
2012
|
-
static LOCK_1_YEAR = 365n * 24n * 60n * 60n;
|
|
2013
|
-
/** 2 years lock duration in seconds */
|
|
2014
|
-
static LOCK_2_YEARS = 730n * 24n * 60n * 60n;
|
|
2015
|
-
};
|
|
2016
|
-
|
|
2017
1200
|
// src/constants.ts
|
|
2018
1201
|
var import_chains = require("viem/chains");
|
|
2019
1202
|
var SDK_VERSION = "0.1.14";
|
|
@@ -2030,12 +1213,9 @@ var CHAIN_CONFIG = {
|
|
|
2030
1213
|
var CONTRACT_ADDRESSES = {
|
|
2031
1214
|
mainnet: {
|
|
2032
1215
|
agentRegistry: "0x2261706C751F8ac5cdDb481B7b56EA2137d4A723",
|
|
2033
|
-
exaToken: "0x13403Fb738C97cF7564F279288468c140AaEd05c",
|
|
2034
|
-
staking: "0xe925727B21f1B86008f291E8f3102345A57B6c17",
|
|
2035
1216
|
router: "0x1BCFa13f677fDCf697D8b7d5120f544817F1de1A",
|
|
2036
|
-
vaultFactory: "
|
|
2037
|
-
feeCollector: "
|
|
2038
|
-
buyback: "0x39967532b640B2f735548c7a5b46d8D890A0B2f2",
|
|
1217
|
+
vaultFactory: "0x1E0e4E445A9fda2e7aBBfFEcA80392ABb0921554",
|
|
1218
|
+
feeCollector: "0x00Ab9847049b5496619dFDd1A7bd36FA49eB7195",
|
|
2039
1219
|
serviceEscrow: "0x63A4d1dA774422EFC2cc57d71F948231BD812516"
|
|
2040
1220
|
}
|
|
2041
1221
|
};
|
|
@@ -2059,19 +1239,12 @@ var EXAGENT_API_CONFIG = {
|
|
|
2059
1239
|
mainnet: "https://exagent-api.onrender.com"
|
|
2060
1240
|
};
|
|
2061
1241
|
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
2062
|
-
var PHASE_1_CONTRACTS = /* @__PURE__ */ new Set([
|
|
2063
|
-
"agentRegistry",
|
|
2064
|
-
"exaToken",
|
|
2065
|
-
"staking",
|
|
2066
|
-
"router",
|
|
2067
|
-
"feeCollector"
|
|
2068
|
-
]);
|
|
2069
1242
|
function validateContractAddresses(network) {
|
|
2070
1243
|
const addresses = CONTRACT_ADDRESSES[network];
|
|
2071
|
-
const
|
|
2072
|
-
if (
|
|
1244
|
+
const missing = Object.entries(addresses).filter(([, addr]) => addr === ZERO_ADDRESS).map(([name]) => name);
|
|
1245
|
+
if (missing.length > 0) {
|
|
2073
1246
|
throw new Error(
|
|
2074
|
-
`
|
|
1247
|
+
`Contract addresses not deployed on ${network}. Missing: ${missing.join(", ")}. Update @exagent/sdk to the latest version.`
|
|
2075
1248
|
);
|
|
2076
1249
|
}
|
|
2077
1250
|
}
|
|
@@ -2103,7 +1276,6 @@ var ExagentClient = class {
|
|
|
2103
1276
|
apiKey;
|
|
2104
1277
|
// Contract interfaces
|
|
2105
1278
|
registry;
|
|
2106
|
-
staking;
|
|
2107
1279
|
// Cached agent ID
|
|
2108
1280
|
_agentId;
|
|
2109
1281
|
constructor(config) {
|
|
@@ -2138,13 +1310,6 @@ var ExagentClient = class {
|
|
|
2138
1310
|
chain,
|
|
2139
1311
|
this.account
|
|
2140
1312
|
);
|
|
2141
|
-
this.staking = new ExagentStaking(
|
|
2142
|
-
addresses.staking,
|
|
2143
|
-
this.publicClient,
|
|
2144
|
-
this.walletClient,
|
|
2145
|
-
chain,
|
|
2146
|
-
this.account
|
|
2147
|
-
);
|
|
2148
1313
|
}
|
|
2149
1314
|
/** Standard headers for all API requests (includes SDK version for gating) */
|
|
2150
1315
|
apiHeaders(contentType) {
|
|
@@ -2293,7 +1458,7 @@ var ExagentClient = class {
|
|
|
2293
1458
|
await this.approveToken(
|
|
2294
1459
|
approval.token,
|
|
2295
1460
|
approval.spender,
|
|
2296
|
-
|
|
1461
|
+
import_viem2.maxUint256
|
|
2297
1462
|
);
|
|
2298
1463
|
}
|
|
2299
1464
|
const txParams = {
|
|
@@ -2314,6 +1479,7 @@ var ExagentClient = class {
|
|
|
2314
1479
|
} catch (err) {
|
|
2315
1480
|
const errorData = err?.data;
|
|
2316
1481
|
if (errorData && errorData.length > 2) {
|
|
1482
|
+
console.error(`Gas estimation revert data: ${errorData}`);
|
|
2317
1483
|
try {
|
|
2318
1484
|
const decoded = (0, import_viem2.decodeErrorResult)({
|
|
2319
1485
|
abi: [...EXAGENT_ROUTER_ABI, ...EXAGENT_REGISTRY_ABI],
|
|
@@ -2322,6 +1488,7 @@ var ExagentClient = class {
|
|
|
2322
1488
|
throw new Error(`Trade will revert: ${decoded.errorName}${decoded.args ? ` (${decoded.args.join(", ")})` : ""}`);
|
|
2323
1489
|
} catch (decodeErr) {
|
|
2324
1490
|
if (decodeErr instanceof Error && decodeErr.message.startsWith("Trade will revert:")) throw decodeErr;
|
|
1491
|
+
throw new Error(`Trade will revert: unknown error selector ${errorData.slice(0, 10)} (raw: ${errorData.slice(0, 66)})`);
|
|
2325
1492
|
}
|
|
2326
1493
|
}
|
|
2327
1494
|
throw new Error(`Trade will revert: gas estimation failed. ${err?.message || "Unknown reason"}`);
|
|
@@ -2386,7 +1553,9 @@ var ExagentClient = class {
|
|
|
2386
1553
|
}
|
|
2387
1554
|
}
|
|
2388
1555
|
/**
|
|
2389
|
-
* Approve token spending for router
|
|
1556
|
+
* Approve token spending for router.
|
|
1557
|
+
* Verifies the approval receipt succeeded — previous version silently continued
|
|
1558
|
+
* on reverted approvals, causing downstream "transfer amount exceeds allowance" errors.
|
|
2390
1559
|
*/
|
|
2391
1560
|
async approveToken(token, spender, amount) {
|
|
2392
1561
|
const approveData = this.encodeApprove(spender, amount);
|
|
@@ -2396,7 +1565,12 @@ var ExagentClient = class {
|
|
|
2396
1565
|
to: token,
|
|
2397
1566
|
data: approveData
|
|
2398
1567
|
});
|
|
2399
|
-
await this.publicClient.waitForTransactionReceipt({ hash });
|
|
1568
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
|
|
1569
|
+
if (receipt.status === "reverted") {
|
|
1570
|
+
throw new Error(
|
|
1571
|
+
`Token approval reverted: approve(${spender}, ${amount}) on ${token}. The token may have non-standard approval behavior.`
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
2400
1574
|
return hash;
|
|
2401
1575
|
}
|
|
2402
1576
|
/**
|
|
@@ -2557,113 +1731,6 @@ var ExagentClient = class {
|
|
|
2557
1731
|
const vault = this.getVault(vaultAddress);
|
|
2558
1732
|
return vault.redeem(shares);
|
|
2559
1733
|
}
|
|
2560
|
-
// ============ Staking Functions ============
|
|
2561
|
-
/**
|
|
2562
|
-
* Deposit EXA tokens for vault access (no lock required)
|
|
2563
|
-
* @param amount Amount of EXA to deposit (in wei)
|
|
2564
|
-
* @returns Transaction hash
|
|
2565
|
-
*
|
|
2566
|
-
* @example
|
|
2567
|
-
* ```typescript
|
|
2568
|
-
* // Deposit 1000 EXA to unlock vault access
|
|
2569
|
-
* const tx = await exagent.depositExa(parseEther('1000'));
|
|
2570
|
-
* ```
|
|
2571
|
-
*/
|
|
2572
|
-
async depositExa(amount) {
|
|
2573
|
-
await this.staking.approveExa(amount);
|
|
2574
|
-
return this.staking.deposit(amount);
|
|
2575
|
-
}
|
|
2576
|
-
/**
|
|
2577
|
-
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
2578
|
-
* @param amount Amount of EXA to withdraw (in wei)
|
|
2579
|
-
* @returns Transaction hash
|
|
2580
|
-
*/
|
|
2581
|
-
async withdrawExa(amount) {
|
|
2582
|
-
return this.staking.withdraw(amount);
|
|
2583
|
-
}
|
|
2584
|
-
/**
|
|
2585
|
-
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
2586
|
-
* @param amount Amount of deposited EXA to lock (in wei)
|
|
2587
|
-
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
2588
|
-
* @returns Transaction hash
|
|
2589
|
-
*
|
|
2590
|
-
* @example
|
|
2591
|
-
* ```typescript
|
|
2592
|
-
* // Lock 1000 EXA for 6 months
|
|
2593
|
-
* const tx = await exagent.lockExa(
|
|
2594
|
-
* parseEther('1000'),
|
|
2595
|
-
* ExagentStaking.LOCK_6_MONTHS
|
|
2596
|
-
* );
|
|
2597
|
-
* ```
|
|
2598
|
-
*/
|
|
2599
|
-
async lockExa(amount, lockDuration) {
|
|
2600
|
-
return this.staking.lock(amount, lockDuration);
|
|
2601
|
-
}
|
|
2602
|
-
/**
|
|
2603
|
-
* Unlock EXA after lock expires (no penalty)
|
|
2604
|
-
* @returns Transaction hash
|
|
2605
|
-
*/
|
|
2606
|
-
async unlockExa() {
|
|
2607
|
-
return this.staking.unlock();
|
|
2608
|
-
}
|
|
2609
|
-
/**
|
|
2610
|
-
* Emergency withdrawal from active lock (graduated 50%→20% penalty)
|
|
2611
|
-
* @returns Transaction hash
|
|
2612
|
-
*/
|
|
2613
|
-
async emergencyWithdrawExa() {
|
|
2614
|
-
return this.staking.emergencyWithdraw();
|
|
2615
|
-
}
|
|
2616
|
-
/**
|
|
2617
|
-
* Get comprehensive staking info (deposit + lock) for the connected wallet
|
|
2618
|
-
* @returns Staking info including deposit status and lock status
|
|
2619
|
-
*/
|
|
2620
|
-
async getStakingInfo() {
|
|
2621
|
-
return this.staking.getStakingInfo();
|
|
2622
|
-
}
|
|
2623
|
-
/**
|
|
2624
|
-
* Get deposit info for the connected wallet
|
|
2625
|
-
* @returns Deposit info (deposited, locked, unlocked, vault access)
|
|
2626
|
-
*/
|
|
2627
|
-
async getDepositInfo() {
|
|
2628
|
-
return this.staking.getDepositInfo();
|
|
2629
|
-
}
|
|
2630
|
-
/**
|
|
2631
|
-
* Get current vEXA balance for the connected wallet
|
|
2632
|
-
* @returns Current vEXA balance (with time decay applied)
|
|
2633
|
-
*/
|
|
2634
|
-
async getVeEXABalance() {
|
|
2635
|
-
return this.staking.getVeEXABalance();
|
|
2636
|
-
}
|
|
2637
|
-
/**
|
|
2638
|
-
* Check if connected wallet has vault access (meets deposit threshold)
|
|
2639
|
-
* @returns True if user can access vaults
|
|
2640
|
-
*/
|
|
2641
|
-
async hasVaultAccess() {
|
|
2642
|
-
return this.staking.hasVaultAccess();
|
|
2643
|
-
}
|
|
2644
|
-
/**
|
|
2645
|
-
* Get earnings tier for the connected wallet
|
|
2646
|
-
* @returns Tier info with multiplier and name
|
|
2647
|
-
*/
|
|
2648
|
-
async getEarningsTier() {
|
|
2649
|
-
return this.staking.getEarningsTier();
|
|
2650
|
-
}
|
|
2651
|
-
/**
|
|
2652
|
-
* Get emergency withdrawal penalty for the connected wallet
|
|
2653
|
-
* @returns Penalty in basis points (5000 = 50% at start, 2000 = 20% near expiry)
|
|
2654
|
-
*/
|
|
2655
|
-
async getEmergencyWithdrawPenalty() {
|
|
2656
|
-
return this.staking.getEmergencyWithdrawPenalty();
|
|
2657
|
-
}
|
|
2658
|
-
/**
|
|
2659
|
-
* Claim all pending staking rewards (EXA + multi-token)
|
|
2660
|
-
* @returns Transaction hashes for EXA and multi-token claims
|
|
2661
|
-
*/
|
|
2662
|
-
async claimAllRewards() {
|
|
2663
|
-
const exaRewards = await this.staking.claimRewards();
|
|
2664
|
-
const multiTokenRewards = await this.staking.claimRewardsMulti();
|
|
2665
|
-
return { exaRewards, multiTokenRewards };
|
|
2666
|
-
}
|
|
2667
1734
|
// ============ ERC-8004 Global Agent Identity ============
|
|
2668
1735
|
/**
|
|
2669
1736
|
* Get the ERC-8004 global agent identifier for the current agent
|
|
@@ -2760,20 +1827,9 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2760
1827
|
{ type: "function", name: "allowedAssets", inputs: [{ name: "asset", type: "address" }], outputs: [{ type: "bool" }], stateMutability: "view" },
|
|
2761
1828
|
{ type: "function", name: "vaults", inputs: [{ name: "agentId", type: "uint256" }, { name: "asset", type: "address" }], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2762
1829
|
{ type: "function", name: "agentVaultCount", inputs: [{ name: "agentId", type: "uint256" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
inputs: [{ name: "creator", type: "address" }],
|
|
2767
|
-
outputs: [{ name: "canCreate", type: "bool" }, { name: "reason", type: "string" }],
|
|
2768
|
-
stateMutability: "view"
|
|
2769
|
-
},
|
|
2770
|
-
{
|
|
2771
|
-
type: "function",
|
|
2772
|
-
name: "canCreateVerifiedVault",
|
|
2773
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
2774
|
-
outputs: [{ name: "isVerified", type: "bool" }, { name: "reason", type: "string" }],
|
|
2775
|
-
stateMutability: "view"
|
|
2776
|
-
},
|
|
1830
|
+
// NOTE: canCreateVault() and canCreateVerifiedVault() do not exist on the
|
|
1831
|
+
// deployed ExagentVaultFactoryV2 contract. SDK methods that called these
|
|
1832
|
+
// now use inline validation (allowedAssets, vaults, MIN_SEED_AMOUNT) instead.
|
|
2777
1833
|
// Write functions
|
|
2778
1834
|
{
|
|
2779
1835
|
type: "function",
|
|
@@ -2834,12 +1890,7 @@ var ExagentVaultFactory = class {
|
|
|
2834
1890
|
* Get vault creation requirements (mainnet: seed-based, no burn fee)
|
|
2835
1891
|
*/
|
|
2836
1892
|
async getRequirements() {
|
|
2837
|
-
const [
|
|
2838
|
-
this.publicClient.readContract({
|
|
2839
|
-
address: this.address,
|
|
2840
|
-
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2841
|
-
functionName: "VERIFIED_VEXA_REQUIREMENT"
|
|
2842
|
-
}),
|
|
1893
|
+
const [minSeedAmount, unverifiedCapMultiplier, verifiedCapMultiplier] = await Promise.all([
|
|
2843
1894
|
this.publicClient.readContract({
|
|
2844
1895
|
address: this.address,
|
|
2845
1896
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
@@ -2854,52 +1905,29 @@ var ExagentVaultFactory = class {
|
|
|
2854
1905
|
address: this.address,
|
|
2855
1906
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2856
1907
|
functionName: "VERIFIED_CAP_MULTIPLIER"
|
|
2857
|
-
}),
|
|
2858
|
-
this.publicClient.readContract({
|
|
2859
|
-
address: this.address,
|
|
2860
|
-
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2861
|
-
functionName: "stakingContract"
|
|
2862
1908
|
})
|
|
2863
1909
|
]);
|
|
2864
1910
|
return {
|
|
2865
|
-
veXARequired,
|
|
2866
1911
|
minSeedAmount,
|
|
2867
1912
|
unverifiedCapMultiplier,
|
|
2868
|
-
verifiedCapMultiplier
|
|
2869
|
-
stakingContract
|
|
1913
|
+
verifiedCapMultiplier
|
|
2870
1914
|
};
|
|
2871
1915
|
}
|
|
2872
1916
|
/**
|
|
2873
|
-
* Check if an address can create a vault
|
|
1917
|
+
* Check if an address can create a vault.
|
|
1918
|
+
* Performs inline validation since the on-chain contract does not expose
|
|
1919
|
+
* a canCreateVault() view function.
|
|
2874
1920
|
* @param creator Address to check
|
|
2875
1921
|
*/
|
|
2876
1922
|
async canCreateVault(creator) {
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
reason: result[1]
|
|
2886
|
-
};
|
|
2887
|
-
}
|
|
2888
|
-
/**
|
|
2889
|
-
* Check if an agent can create a verified vault (higher deposit cap)
|
|
2890
|
-
* @param agentId Agent ID to check
|
|
2891
|
-
*/
|
|
2892
|
-
async canCreateVerifiedVault(agentId) {
|
|
2893
|
-
const result = await this.publicClient.readContract({
|
|
2894
|
-
address: this.address,
|
|
2895
|
-
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2896
|
-
functionName: "canCreateVerifiedVault",
|
|
2897
|
-
args: [agentId]
|
|
2898
|
-
});
|
|
2899
|
-
return {
|
|
2900
|
-
isVerified: result[0],
|
|
2901
|
-
reason: result[1]
|
|
2902
|
-
};
|
|
1923
|
+
try {
|
|
1924
|
+
const isUsdcAllowed = await this.isAssetAllowed("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913");
|
|
1925
|
+
if (!isUsdcAllowed) {
|
|
1926
|
+
return { canCreate: false, reason: "USDC is not an allowed asset" };
|
|
1927
|
+
}
|
|
1928
|
+
} catch {
|
|
1929
|
+
}
|
|
1930
|
+
return { canCreate: true, reason: "" };
|
|
2903
1931
|
}
|
|
2904
1932
|
/**
|
|
2905
1933
|
* Check if an asset is whitelisted for vault creation
|
|
@@ -3052,11 +2080,9 @@ var ExagentVaultFactory = class {
|
|
|
3052
2080
|
EXAGENT_API_CONFIG,
|
|
3053
2081
|
EXAGENT_REGISTRY_ABI,
|
|
3054
2082
|
EXAGENT_ROUTER_ABI,
|
|
3055
|
-
EXAGENT_STAKING_ABI,
|
|
3056
2083
|
EXAGENT_VAULT_FACTORY_ABI,
|
|
3057
2084
|
ExagentClient,
|
|
3058
2085
|
ExagentRegistry,
|
|
3059
|
-
ExagentStaking,
|
|
3060
2086
|
ExagentVault,
|
|
3061
2087
|
ExagentVaultFactory,
|
|
3062
2088
|
SDK_VERSION,
|