@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.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: "0x5b90C7F9F02F9130a92481360E9aa5Be4fcc9500",
2037
- feeCollector: "0xe66328a964AF93bEF2eDB226D039C35aE6e66De1",
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 missingPhase1 = Object.entries(addresses).filter(([name, addr]) => PHASE_1_CONTRACTS.has(name) && addr === ZERO_ADDRESS).map(([name]) => name);
2072
- if (missingPhase1.length > 0) {
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
- `Mainnet Phase 1 contracts not deployed. Missing: ${missingPhase1.join(", ")}. Update @exagent/sdk to the latest version.`
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
- amount
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
- type: "function",
2765
- name: "canCreateVault",
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 [veXARequired, minSeedAmount, unverifiedCapMultiplier, verifiedCapMultiplier, stakingContract] = await Promise.all([
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
- const result = await this.publicClient.readContract({
2878
- address: this.address,
2879
- abi: EXAGENT_VAULT_FACTORY_ABI,
2880
- functionName: "canCreateVault",
2881
- args: [creator]
2882
- });
2883
- return {
2884
- canCreate: result[0],
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,