@exagent/sdk 0.1.14 → 0.1.16

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) {
@@ -2280,6 +1445,10 @@ var ExagentClient = class {
2280
1445
  const key = `${approval.token.toLowerCase()}:${approval.spender.toLowerCase()}`;
2281
1446
  if (seen.has(key)) continue;
2282
1447
  seen.add(key);
1448
+ if (!approval.amount) {
1449
+ console.warn(`Skipping approval with missing amount for token ${approval.token} \u2014 0x did not return expected allowance`);
1450
+ continue;
1451
+ }
2283
1452
  const amount = BigInt(approval.amount);
2284
1453
  const existing = await this.getAllowance(
2285
1454
  approval.token,
@@ -2289,7 +1458,7 @@ var ExagentClient = class {
2289
1458
  await this.approveToken(
2290
1459
  approval.token,
2291
1460
  approval.spender,
2292
- amount
1461
+ import_viem2.maxUint256
2293
1462
  );
2294
1463
  }
2295
1464
  const txParams = {
@@ -2382,7 +1551,9 @@ var ExagentClient = class {
2382
1551
  }
2383
1552
  }
2384
1553
  /**
2385
- * Approve token spending for router
1554
+ * Approve token spending for router.
1555
+ * Verifies the approval receipt succeeded — previous version silently continued
1556
+ * on reverted approvals, causing downstream "transfer amount exceeds allowance" errors.
2386
1557
  */
2387
1558
  async approveToken(token, spender, amount) {
2388
1559
  const approveData = this.encodeApprove(spender, amount);
@@ -2392,7 +1563,12 @@ var ExagentClient = class {
2392
1563
  to: token,
2393
1564
  data: approveData
2394
1565
  });
2395
- await this.publicClient.waitForTransactionReceipt({ hash });
1566
+ const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
1567
+ if (receipt.status === "reverted") {
1568
+ throw new Error(
1569
+ `Token approval reverted: approve(${spender}, ${amount}) on ${token}. The token may have non-standard approval behavior.`
1570
+ );
1571
+ }
2396
1572
  return hash;
2397
1573
  }
2398
1574
  /**
@@ -2553,113 +1729,6 @@ var ExagentClient = class {
2553
1729
  const vault = this.getVault(vaultAddress);
2554
1730
  return vault.redeem(shares);
2555
1731
  }
2556
- // ============ Staking Functions ============
2557
- /**
2558
- * Deposit EXA tokens for vault access (no lock required)
2559
- * @param amount Amount of EXA to deposit (in wei)
2560
- * @returns Transaction hash
2561
- *
2562
- * @example
2563
- * ```typescript
2564
- * // Deposit 1000 EXA to unlock vault access
2565
- * const tx = await exagent.depositExa(parseEther('1000'));
2566
- * ```
2567
- */
2568
- async depositExa(amount) {
2569
- await this.staking.approveExa(amount);
2570
- return this.staking.deposit(amount);
2571
- }
2572
- /**
2573
- * Withdraw unlocked EXA tokens (instant, no penalty)
2574
- * @param amount Amount of EXA to withdraw (in wei)
2575
- * @returns Transaction hash
2576
- */
2577
- async withdrawExa(amount) {
2578
- return this.staking.withdraw(amount);
2579
- }
2580
- /**
2581
- * Lock deposited EXA to receive vEXA voting power and earn rewards
2582
- * @param amount Amount of deposited EXA to lock (in wei)
2583
- * @param lockDuration Lock duration in seconds (30 days to 2 years)
2584
- * @returns Transaction hash
2585
- *
2586
- * @example
2587
- * ```typescript
2588
- * // Lock 1000 EXA for 6 months
2589
- * const tx = await exagent.lockExa(
2590
- * parseEther('1000'),
2591
- * ExagentStaking.LOCK_6_MONTHS
2592
- * );
2593
- * ```
2594
- */
2595
- async lockExa(amount, lockDuration) {
2596
- return this.staking.lock(amount, lockDuration);
2597
- }
2598
- /**
2599
- * Unlock EXA after lock expires (no penalty)
2600
- * @returns Transaction hash
2601
- */
2602
- async unlockExa() {
2603
- return this.staking.unlock();
2604
- }
2605
- /**
2606
- * Emergency withdrawal from active lock (graduated 50%→20% penalty)
2607
- * @returns Transaction hash
2608
- */
2609
- async emergencyWithdrawExa() {
2610
- return this.staking.emergencyWithdraw();
2611
- }
2612
- /**
2613
- * Get comprehensive staking info (deposit + lock) for the connected wallet
2614
- * @returns Staking info including deposit status and lock status
2615
- */
2616
- async getStakingInfo() {
2617
- return this.staking.getStakingInfo();
2618
- }
2619
- /**
2620
- * Get deposit info for the connected wallet
2621
- * @returns Deposit info (deposited, locked, unlocked, vault access)
2622
- */
2623
- async getDepositInfo() {
2624
- return this.staking.getDepositInfo();
2625
- }
2626
- /**
2627
- * Get current vEXA balance for the connected wallet
2628
- * @returns Current vEXA balance (with time decay applied)
2629
- */
2630
- async getVeEXABalance() {
2631
- return this.staking.getVeEXABalance();
2632
- }
2633
- /**
2634
- * Check if connected wallet has vault access (meets deposit threshold)
2635
- * @returns True if user can access vaults
2636
- */
2637
- async hasVaultAccess() {
2638
- return this.staking.hasVaultAccess();
2639
- }
2640
- /**
2641
- * Get earnings tier for the connected wallet
2642
- * @returns Tier info with multiplier and name
2643
- */
2644
- async getEarningsTier() {
2645
- return this.staking.getEarningsTier();
2646
- }
2647
- /**
2648
- * Get emergency withdrawal penalty for the connected wallet
2649
- * @returns Penalty in basis points (5000 = 50% at start, 2000 = 20% near expiry)
2650
- */
2651
- async getEmergencyWithdrawPenalty() {
2652
- return this.staking.getEmergencyWithdrawPenalty();
2653
- }
2654
- /**
2655
- * Claim all pending staking rewards (EXA + multi-token)
2656
- * @returns Transaction hashes for EXA and multi-token claims
2657
- */
2658
- async claimAllRewards() {
2659
- const exaRewards = await this.staking.claimRewards();
2660
- const multiTokenRewards = await this.staking.claimRewardsMulti();
2661
- return { exaRewards, multiTokenRewards };
2662
- }
2663
1732
  // ============ ERC-8004 Global Agent Identity ============
2664
1733
  /**
2665
1734
  * Get the ERC-8004 global agent identifier for the current agent
@@ -2830,12 +1899,7 @@ var ExagentVaultFactory = class {
2830
1899
  * Get vault creation requirements (mainnet: seed-based, no burn fee)
2831
1900
  */
2832
1901
  async getRequirements() {
2833
- const [veXARequired, minSeedAmount, unverifiedCapMultiplier, verifiedCapMultiplier, stakingContract] = await Promise.all([
2834
- this.publicClient.readContract({
2835
- address: this.address,
2836
- abi: EXAGENT_VAULT_FACTORY_ABI,
2837
- functionName: "VERIFIED_VEXA_REQUIREMENT"
2838
- }),
1902
+ const [minSeedAmount, unverifiedCapMultiplier, verifiedCapMultiplier] = await Promise.all([
2839
1903
  this.publicClient.readContract({
2840
1904
  address: this.address,
2841
1905
  abi: EXAGENT_VAULT_FACTORY_ABI,
@@ -2850,19 +1914,12 @@ var ExagentVaultFactory = class {
2850
1914
  address: this.address,
2851
1915
  abi: EXAGENT_VAULT_FACTORY_ABI,
2852
1916
  functionName: "VERIFIED_CAP_MULTIPLIER"
2853
- }),
2854
- this.publicClient.readContract({
2855
- address: this.address,
2856
- abi: EXAGENT_VAULT_FACTORY_ABI,
2857
- functionName: "stakingContract"
2858
1917
  })
2859
1918
  ]);
2860
1919
  return {
2861
- veXARequired,
2862
1920
  minSeedAmount,
2863
1921
  unverifiedCapMultiplier,
2864
- verifiedCapMultiplier,
2865
- stakingContract
1922
+ verifiedCapMultiplier
2866
1923
  };
2867
1924
  }
2868
1925
  /**
@@ -3048,11 +2105,9 @@ var ExagentVaultFactory = class {
3048
2105
  EXAGENT_API_CONFIG,
3049
2106
  EXAGENT_REGISTRY_ABI,
3050
2107
  EXAGENT_ROUTER_ABI,
3051
- EXAGENT_STAKING_ABI,
3052
2108
  EXAGENT_VAULT_FACTORY_ABI,
3053
2109
  ExagentClient,
3054
2110
  ExagentRegistry,
3055
- ExagentStaking,
3056
2111
  ExagentVault,
3057
2112
  ExagentVaultFactory,
3058
2113
  SDK_VERSION,