@agether/sdk 1.2.0 → 1.2.1

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.
Files changed (41) hide show
  1. package/dist/cli.js +295 -5
  2. package/dist/index.d.mts +194 -1
  3. package/dist/index.d.ts +194 -1
  4. package/dist/index.js +429 -17
  5. package/dist/index.mjs +427 -16
  6. package/package.json +1 -1
  7. package/dist/cli.d.mts +0 -2
  8. package/dist/cli.d.ts +0 -19
  9. package/dist/cli.d.ts.map +0 -1
  10. package/dist/cli.mjs +0 -0
  11. package/dist/clients/AgentIdentityClient.d.ts +0 -163
  12. package/dist/clients/AgentIdentityClient.d.ts.map +0 -1
  13. package/dist/clients/AgentIdentityClient.js +0 -293
  14. package/dist/clients/AgetherClient.d.ts +0 -101
  15. package/dist/clients/AgetherClient.d.ts.map +0 -1
  16. package/dist/clients/AgetherClient.js +0 -272
  17. package/dist/clients/ScoringClient.d.ts +0 -138
  18. package/dist/clients/ScoringClient.d.ts.map +0 -1
  19. package/dist/clients/ScoringClient.js +0 -135
  20. package/dist/clients/VaultClient.d.ts +0 -62
  21. package/dist/clients/VaultClient.d.ts.map +0 -1
  22. package/dist/clients/VaultClient.js +0 -157
  23. package/dist/clients/WalletClient.d.ts +0 -73
  24. package/dist/clients/WalletClient.d.ts.map +0 -1
  25. package/dist/clients/WalletClient.js +0 -174
  26. package/dist/clients/X402Client.d.ts +0 -61
  27. package/dist/clients/X402Client.d.ts.map +0 -1
  28. package/dist/clients/X402Client.js +0 -303
  29. package/dist/index.d.ts.map +0 -1
  30. package/dist/types/index.d.ts +0 -220
  31. package/dist/types/index.d.ts.map +0 -1
  32. package/dist/types/index.js +0 -52
  33. package/dist/utils/abis.d.ts +0 -21
  34. package/dist/utils/abis.d.ts.map +0 -1
  35. package/dist/utils/abis.js +0 -134
  36. package/dist/utils/config.d.ts +0 -31
  37. package/dist/utils/config.d.ts.map +0 -1
  38. package/dist/utils/config.js +0 -117
  39. package/dist/utils/format.d.ts +0 -44
  40. package/dist/utils/format.d.ts.map +0 -1
  41. package/dist/utils/format.js +0 -75
package/dist/index.js CHANGED
@@ -45,6 +45,7 @@ __export(index_exports, {
45
45
  InsufficientCreditError: () => InsufficientCreditError,
46
46
  LP_VAULT_ABI: () => LP_VAULT_ABI,
47
47
  MORPHO_CREDIT_ABI: () => MORPHO_CREDIT_ABI,
48
+ MorphoCreditClient: () => MorphoCreditClient,
48
49
  REPUTATION_CREDIT_ABI: () => REPUTATION_CREDIT_ABI,
49
50
  ScoringClient: () => ScoringClient,
50
51
  ScoringRejectedError: () => ScoringRejectedError,
@@ -1197,7 +1198,7 @@ function chainIdFromNetwork(network) {
1197
1198
  const m = network.match(/^eip155:(\d+)$/);
1198
1199
  return m ? Number(m[1]) : 1;
1199
1200
  }
1200
- var X402Client = class {
1201
+ var _X402Client = class _X402Client {
1201
1202
  constructor(config) {
1202
1203
  this.config = config;
1203
1204
  const provider = new import_ethers4.ethers.JsonRpcProvider(config.rpcUrl);
@@ -1246,6 +1247,9 @@ var X402Client = class {
1246
1247
  console.log(` amount : ${requirements.amount} (atomic)`);
1247
1248
  console.log(` asset : ${requirements.asset}`);
1248
1249
  console.log(` payTo : ${requirements.payTo}`);
1250
+ if (this.config.autoDraw && this.config.accountAddress && this.config.morphoCreditAddress) {
1251
+ await this.ensureBalance(BigInt(requirements.amount));
1252
+ }
1249
1253
  console.log(" [3/4] Signing EIP-3009 transferWithAuthorization\u2026");
1250
1254
  const paymentPayload = await this.buildPaymentPayload(requirements, resource, url);
1251
1255
  const paymentB64 = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
@@ -1406,6 +1410,43 @@ var X402Client = class {
1406
1410
  }
1407
1411
  };
1408
1412
  }
1413
+ async ensureBalance(requiredAmount) {
1414
+ const accountAddr = this.config.accountAddress;
1415
+ const morphoAddr = this.config.morphoCreditAddress;
1416
+ const provider = this.wallet.provider;
1417
+ const usdcAddr = USDC_DOMAINS["eip155:8453"]?.address || USDC_DOMAINS["eip155:1"].address;
1418
+ const usdc = new import_ethers4.ethers.Contract(usdcAddr, _X402Client.ERC20_BALANCE_ABI, provider);
1419
+ const balance = await usdc.balanceOf(accountAddr);
1420
+ const needed = requiredAmount + requiredAmount / 10n;
1421
+ if (balance >= needed) return;
1422
+ const deficit = needed - balance;
1423
+ const minDraw = import_ethers4.ethers.parseUnits("10", 6);
1424
+ const drawAmount = deficit > minDraw ? deficit : minDraw;
1425
+ console.log(` [auto-draw] USDC balance $${import_ethers4.ethers.formatUnits(balance, 6)} < needed $${import_ethers4.ethers.formatUnits(needed, 6)}`);
1426
+ const morpho = new import_ethers4.ethers.Contract(morphoAddr, _X402Client.MORPHO_DRAW_ABI, provider);
1427
+ let collateralAddr = null;
1428
+ for (const addr of _X402Client.AUTO_DRAW_COLLATERALS) {
1429
+ try {
1430
+ const pos = await morpho.getPosition(accountAddr, addr);
1431
+ if (pos.collateralAmount > 0n) {
1432
+ collateralAddr = addr;
1433
+ break;
1434
+ }
1435
+ } catch {
1436
+ continue;
1437
+ }
1438
+ }
1439
+ if (!collateralAddr) {
1440
+ throw new Error("autoDraw failed: no collateral deposited in Morpho. Deposit collateral first.");
1441
+ }
1442
+ const account = new import_ethers4.ethers.Contract(accountAddr, _X402Client.AGENT_ACCOUNT_EXEC_ABI, this.wallet);
1443
+ const morphoIface = new import_ethers4.ethers.Interface(_X402Client.MORPHO_DRAW_ABI);
1444
+ const calldata = morphoIface.encodeFunctionData("drawWithCollateral", [collateralAddr, drawAmount]);
1445
+ console.log(` [auto-draw] Borrowing $${import_ethers4.ethers.formatUnits(drawAmount, 6)} from Morpho...`);
1446
+ const tx = await account.execute(morphoAddr, 0, calldata);
1447
+ await tx.wait();
1448
+ console.log(` [auto-draw] \u2713 Borrowed (tx: ${tx.hash.slice(0, 14)}\u2026)`);
1449
+ }
1409
1450
  // ──────────── Risk check via our backend ────────────
1410
1451
  async riskCheck(paymentPayload, reqs) {
1411
1452
  try {
@@ -1437,17 +1478,387 @@ var X402Client = class {
1437
1478
  }
1438
1479
  }
1439
1480
  };
1481
+ // ──────────── Auto-draw (Flow 9) ────────────
1482
+ //
1483
+ // When autoDraw is enabled and the AgentAccount has insufficient USDC,
1484
+ // automatically borrow from Morpho credit line to cover the payment.
1485
+ _X402Client.MORPHO_DRAW_ABI = [
1486
+ "function drawWithCollateral(address collateralToken, uint256 amount)",
1487
+ "function getPosition(address account, address collateralToken) view returns (tuple(uint256 collateralAmount, uint256 borrowedAmount, uint256 borrowShares, bool isActive))"
1488
+ ];
1489
+ _X402Client.AGENT_ACCOUNT_EXEC_ABI = [
1490
+ "function execute(address target, uint256 value, bytes data) payable returns (bytes)"
1491
+ ];
1492
+ _X402Client.ERC20_BALANCE_ABI = [
1493
+ "function balanceOf(address) view returns (uint256)"
1494
+ ];
1495
+ _X402Client.AUTO_DRAW_COLLATERALS = [
1496
+ "0x4200000000000000000000000000000000000006",
1497
+ // WETH
1498
+ "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
1499
+ // wstETH
1500
+ "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22"
1501
+ // cbETH
1502
+ ];
1503
+ var X402Client = _X402Client;
1440
1504
 
1441
- // src/clients/WalletClient.ts
1505
+ // src/clients/MorphoCreditClient.ts
1442
1506
  var import_ethers5 = require("ethers");
1507
+ var BASE_COLLATERALS = {
1508
+ WETH: { symbol: "WETH", address: "0x4200000000000000000000000000000000000006", decimals: 18 },
1509
+ wstETH: { symbol: "wstETH", address: "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452", decimals: 18 },
1510
+ cbETH: { symbol: "cbETH", address: "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22", decimals: 18 }
1511
+ };
1512
+ var MorphoCreditClient = class {
1513
+ constructor(config, collaterals) {
1514
+ this.config = config;
1515
+ const provider = new import_ethers5.ethers.JsonRpcProvider(config.rpcUrl);
1516
+ this.signer = new import_ethers5.ethers.Wallet(config.privateKey, provider);
1517
+ this.morpho = new import_ethers5.Contract(config.contracts.morphoCredit, MORPHO_CREDIT_ABI, this.signer);
1518
+ this.factory = new import_ethers5.Contract(config.contracts.accountFactory, ACCOUNT_FACTORY_ABI, this.signer);
1519
+ this.collaterals = collaterals || BASE_COLLATERALS;
1520
+ }
1521
+ // ── Helpers ──
1522
+ resolveToken(tokenSymbol) {
1523
+ const token = this.collaterals[tokenSymbol];
1524
+ if (!token) {
1525
+ throw new Error(`Unsupported collateral token: ${tokenSymbol}. Supported: ${Object.keys(this.collaterals).join(", ")}`);
1526
+ }
1527
+ return token;
1528
+ }
1529
+ /**
1530
+ * Get the AgentAccount address for the configured agentId.
1531
+ */
1532
+ async getAccountAddress() {
1533
+ if (this.accountAddress) return this.accountAddress;
1534
+ const addr = await this.factory.getAccount(this.config.agentId.toString());
1535
+ if (addr === import_ethers5.ethers.ZeroAddress) {
1536
+ throw new Error("No AgentAccount found. Register first.");
1537
+ }
1538
+ this.accountAddress = addr;
1539
+ return addr;
1540
+ }
1541
+ /**
1542
+ * Get the AgentAccount address for any agentId.
1543
+ */
1544
+ async getAccountForAgent(agentId) {
1545
+ const addr = await this.factory.getAccount(agentId.toString());
1546
+ if (addr === import_ethers5.ethers.ZeroAddress) {
1547
+ throw new Error(`No AgentAccount for agent #${agentId}`);
1548
+ }
1549
+ return addr;
1550
+ }
1551
+ async ensureCreditProvider(accountAddr) {
1552
+ const account = new import_ethers5.Contract(accountAddr, AGENT_ACCOUNT_ABI, this.signer);
1553
+ try {
1554
+ const tx = await account.approveCreditProvider(this.config.contracts.morphoCredit);
1555
+ await tx.wait();
1556
+ } catch {
1557
+ }
1558
+ }
1559
+ async approveAndDeposit(accountAddr, tokenInfo, amount) {
1560
+ const token = new import_ethers5.Contract(tokenInfo.address, ERC20_ABI, this.signer);
1561
+ const balance = await token.balanceOf(this.signer.address);
1562
+ if (balance < amount) {
1563
+ throw new Error(
1564
+ `Insufficient ${tokenInfo.symbol}: have ${import_ethers5.ethers.formatUnits(balance, tokenInfo.decimals)}, need ${import_ethers5.ethers.formatUnits(amount, tokenInfo.decimals)}`
1565
+ );
1566
+ }
1567
+ const approveTx = await token.approve(this.config.contracts.morphoCredit, amount);
1568
+ await approveTx.wait();
1569
+ const depositTx = await this.morpho.depositCollateralFor(accountAddr, tokenInfo.address, amount);
1570
+ await depositTx.wait();
1571
+ return depositTx.hash;
1572
+ }
1573
+ async executeBorrow(accountAddr, collateralAddr, borrowAmount) {
1574
+ const account = new import_ethers5.Contract(accountAddr, AGENT_ACCOUNT_ABI, this.signer);
1575
+ const iface = new import_ethers5.ethers.Interface(MORPHO_CREDIT_ABI);
1576
+ const calldata = iface.encodeFunctionData("drawWithCollateral", [collateralAddr, borrowAmount]);
1577
+ const tx = await account.execute(this.config.contracts.morphoCredit, 0, calldata);
1578
+ await tx.wait();
1579
+ return tx.hash;
1580
+ }
1581
+ // ══════════════════════════════════════════
1582
+ // Flow 3: Deposit collateral only
1583
+ // ══════════════════════════════════════════
1584
+ /**
1585
+ * Deposit collateral from EOA into Morpho for own AgentAccount.
1586
+ * Does NOT borrow — use `borrow()` or `depositAndBorrow()` for that.
1587
+ *
1588
+ * @param tokenSymbol - Collateral token (WETH, wstETH, cbETH)
1589
+ * @param amount - Human-readable amount (e.g. "0.05")
1590
+ */
1591
+ async deposit(tokenSymbol, amount) {
1592
+ const tokenInfo = this.resolveToken(tokenSymbol);
1593
+ const amountWei = import_ethers5.ethers.parseUnits(amount, tokenInfo.decimals);
1594
+ const accountAddr = await this.getAccountAddress();
1595
+ const txHash = await this.approveAndDeposit(accountAddr, tokenInfo, amountWei);
1596
+ await this.ensureCreditProvider(accountAddr);
1597
+ const pos = await this.morpho.getPosition(accountAddr, tokenInfo.address);
1598
+ return {
1599
+ tx: txHash,
1600
+ amount: amountWei,
1601
+ token: tokenSymbol,
1602
+ agentAccount: accountAddr,
1603
+ totalCollateral: pos.collateralAmount
1604
+ };
1605
+ }
1606
+ // ══════════════════════════════════════════
1607
+ // Flow 2: Deposit + borrow in one call
1608
+ // ══════════════════════════════════════════
1609
+ /**
1610
+ * Deposit collateral AND borrow USDC in a single SDK call.
1611
+ * USDC lands in the AgentAccount.
1612
+ *
1613
+ * @param tokenSymbol - Collateral token (WETH, wstETH, cbETH)
1614
+ * @param collateralAmount - Human-readable collateral amount (e.g. "0.05")
1615
+ * @param borrowAmount - Human-readable USDC amount to borrow (e.g. "50")
1616
+ */
1617
+ async depositAndBorrow(tokenSymbol, collateralAmount, borrowAmount) {
1618
+ const tokenInfo = this.resolveToken(tokenSymbol);
1619
+ const collateralWei = import_ethers5.ethers.parseUnits(collateralAmount, tokenInfo.decimals);
1620
+ const borrowWei = import_ethers5.ethers.parseUnits(borrowAmount, 6);
1621
+ const accountAddr = await this.getAccountAddress();
1622
+ const depositTxHash = await this.approveAndDeposit(accountAddr, tokenInfo, collateralWei);
1623
+ await this.ensureCreditProvider(accountAddr);
1624
+ const borrowTxHash = await this.executeBorrow(accountAddr, tokenInfo.address, borrowWei);
1625
+ const totalDebt = await this.morpho.getTotalDebt(accountAddr);
1626
+ return {
1627
+ depositTx: depositTxHash,
1628
+ borrowTx: borrowTxHash,
1629
+ collateral: { amount: collateralWei, token: tokenSymbol },
1630
+ borrowed: borrowWei,
1631
+ agentAccount: accountAddr,
1632
+ totalDebt
1633
+ };
1634
+ }
1635
+ // ══════════════════════════════════════════
1636
+ // Flow 8: Borrow against existing collateral
1637
+ // ══════════════════════════════════════════
1638
+ /**
1639
+ * Borrow USDC against already-deposited collateral.
1640
+ * Auto-detects which collateral token has a position.
1641
+ * USDC lands in AgentAccount — ready for x402 payments.
1642
+ *
1643
+ * @param amount - Human-readable USDC amount (e.g. "100")
1644
+ */
1645
+ async borrow(amount) {
1646
+ const borrowWei = import_ethers5.ethers.parseUnits(amount, 6);
1647
+ const accountAddr = await this.getAccountAddress();
1648
+ let activeToken = null;
1649
+ for (const info of Object.values(this.collaterals)) {
1650
+ const pos = await this.morpho.getPosition(accountAddr, info.address);
1651
+ if (pos.collateralAmount > 0n) {
1652
+ activeToken = info;
1653
+ break;
1654
+ }
1655
+ }
1656
+ if (!activeToken) {
1657
+ throw new Error("No collateral deposited. Use deposit() or depositAndBorrow() first.");
1658
+ }
1659
+ const txHash = await this.executeBorrow(accountAddr, activeToken.address, borrowWei);
1660
+ const totalDebt = await this.morpho.getTotalDebt(accountAddr);
1661
+ return {
1662
+ tx: txHash,
1663
+ amount: borrowWei,
1664
+ agentAccount: accountAddr,
1665
+ totalDebt,
1666
+ collateralToken: activeToken.symbol
1667
+ };
1668
+ }
1669
+ // ══════════════════════════════════════════
1670
+ // Flows 4-7: Sponsor (deposit for another agent)
1671
+ // ══════════════════════════════════════════
1672
+ /**
1673
+ * Deposit collateral for another agent. Caller pays from their wallet.
1674
+ * Optionally borrow USDC for the agent (only works if caller owns the AgentAccount).
1675
+ *
1676
+ * Supports both agentId lookup and direct address.
1677
+ *
1678
+ * @param target - `{ agentId: "17676" }` or `{ address: "0x..." }`
1679
+ * @param tokenSymbol - Collateral token
1680
+ * @param amount - Human-readable collateral amount
1681
+ * @param borrowAmount - Optional: USDC to borrow (only if caller is owner)
1682
+ */
1683
+ async sponsor(target, tokenSymbol, amount, borrowAmount) {
1684
+ const tokenInfo = this.resolveToken(tokenSymbol);
1685
+ const collateralWei = import_ethers5.ethers.parseUnits(amount, tokenInfo.decimals);
1686
+ let accountAddr;
1687
+ let targetAgentId;
1688
+ if ("agentId" in target) {
1689
+ targetAgentId = target.agentId.toString();
1690
+ accountAddr = await this.getAccountForAgent(target.agentId);
1691
+ } else {
1692
+ accountAddr = target.address;
1693
+ }
1694
+ const depositTxHash = await this.approveAndDeposit(accountAddr, tokenInfo, collateralWei);
1695
+ const result = {
1696
+ depositTx: depositTxHash,
1697
+ targetAccount: accountAddr,
1698
+ targetAgentId,
1699
+ collateral: { amount: collateralWei, token: tokenSymbol },
1700
+ totalCollateral: 0n,
1701
+ totalDebt: 0n
1702
+ };
1703
+ if (borrowAmount) {
1704
+ const borrowWei = import_ethers5.ethers.parseUnits(borrowAmount, 6);
1705
+ try {
1706
+ await this.ensureCreditProvider(accountAddr);
1707
+ const borrowTxHash = await this.executeBorrow(accountAddr, tokenInfo.address, borrowWei);
1708
+ result.borrowTx = borrowTxHash;
1709
+ result.borrowed = borrowWei;
1710
+ } catch (e) {
1711
+ throw new Error(`Borrow failed (caller may not own this AgentAccount): ${e.message}`);
1712
+ }
1713
+ }
1714
+ const pos = await this.morpho.getPosition(accountAddr, tokenInfo.address);
1715
+ result.totalCollateral = pos.collateralAmount;
1716
+ result.totalDebt = pos.borrowedAmount;
1717
+ return result;
1718
+ }
1719
+ // ══════════════════════════════════════════
1720
+ // Repay & Withdraw
1721
+ // ══════════════════════════════════════════
1722
+ /**
1723
+ * Repay borrowed USDC from AgentAccount back to Morpho.
1724
+ *
1725
+ * @param amount - Human-readable USDC amount (e.g. "50")
1726
+ */
1727
+ async repay(amount) {
1728
+ const amountWei = import_ethers5.ethers.parseUnits(amount, 6);
1729
+ const accountAddr = await this.getAccountAddress();
1730
+ let collateralAddr = null;
1731
+ for (const info of Object.values(this.collaterals)) {
1732
+ const pos = await this.morpho.getPosition(accountAddr, info.address);
1733
+ if (pos.borrowedAmount > 0n) {
1734
+ collateralAddr = info.address;
1735
+ break;
1736
+ }
1737
+ }
1738
+ if (!collateralAddr) throw new Error("No Morpho debt to repay.");
1739
+ const usdc = new import_ethers5.Contract(this.config.contracts.usdc, ERC20_ABI, this.signer.provider);
1740
+ const balance = await usdc.balanceOf(accountAddr);
1741
+ if (balance < amountWei) {
1742
+ throw new Error(`Insufficient USDC in AgentAccount: $${import_ethers5.ethers.formatUnits(balance, 6)}`);
1743
+ }
1744
+ const account = new import_ethers5.Contract(accountAddr, AGENT_ACCOUNT_ABI, this.signer);
1745
+ const erc20Iface = new import_ethers5.ethers.Interface(ERC20_ABI);
1746
+ const morphoIface = new import_ethers5.ethers.Interface(MORPHO_CREDIT_ABI);
1747
+ const approveData = erc20Iface.encodeFunctionData("approve", [this.config.contracts.morphoCredit, amountWei]);
1748
+ const approveTx = await account.execute(this.config.contracts.usdc, 0, approveData);
1749
+ await approveTx.wait();
1750
+ const repayData = morphoIface.encodeFunctionData("repayWithCollateral", [collateralAddr, amountWei]);
1751
+ const tx = await account.execute(this.config.contracts.morphoCredit, 0, repayData);
1752
+ await tx.wait();
1753
+ const totalDebt = await this.morpho.getTotalDebt(accountAddr);
1754
+ return { tx: tx.hash, amount: amountWei, remainingDebt: totalDebt };
1755
+ }
1756
+ /**
1757
+ * Withdraw collateral from Morpho back to EOA.
1758
+ *
1759
+ * @param tokenSymbol - Collateral token
1760
+ * @param amount - Human-readable amount or "all"
1761
+ */
1762
+ async withdraw(tokenSymbol, amount) {
1763
+ const tokenInfo = this.resolveToken(tokenSymbol);
1764
+ const accountAddr = await this.getAccountAddress();
1765
+ const pos = await this.morpho.getPosition(accountAddr, tokenInfo.address);
1766
+ if (pos.collateralAmount === 0n) {
1767
+ throw new Error(`No ${tokenSymbol} collateral deposited.`);
1768
+ }
1769
+ const withdrawAmount = amount.toLowerCase() === "all" ? pos.collateralAmount : import_ethers5.ethers.parseUnits(amount, tokenInfo.decimals);
1770
+ if (withdrawAmount > pos.collateralAmount) {
1771
+ throw new Error(
1772
+ `Cannot withdraw more than deposited: max ${import_ethers5.ethers.formatUnits(pos.collateralAmount, tokenInfo.decimals)} ${tokenSymbol}`
1773
+ );
1774
+ }
1775
+ const account = new import_ethers5.Contract(accountAddr, AGENT_ACCOUNT_ABI, this.signer);
1776
+ const morphoIface = new import_ethers5.ethers.Interface(MORPHO_CREDIT_ABI);
1777
+ const withdrawData = morphoIface.encodeFunctionData("withdrawCollateral", [tokenInfo.address, withdrawAmount]);
1778
+ const tx1 = await account.execute(this.config.contracts.morphoCredit, 0, withdrawData);
1779
+ await tx1.wait();
1780
+ const erc20Iface = new import_ethers5.ethers.Interface(ERC20_ABI);
1781
+ const transferData = erc20Iface.encodeFunctionData("transfer", [this.signer.address, withdrawAmount]);
1782
+ const tx2 = await account.execute(tokenInfo.address, 0, transferData);
1783
+ await tx2.wait();
1784
+ const newPos = await this.morpho.getPosition(accountAddr, tokenInfo.address);
1785
+ return {
1786
+ tx: tx1.hash,
1787
+ amount: withdrawAmount,
1788
+ token: tokenSymbol,
1789
+ destination: this.signer.address,
1790
+ remainingCollateral: newPos.collateralAmount
1791
+ };
1792
+ }
1793
+ // ══════════════════════════════════════════
1794
+ // View methods
1795
+ // ══════════════════════════════════════════
1796
+ /**
1797
+ * Get position for a specific collateral token.
1798
+ */
1799
+ async getPosition(tokenSymbol) {
1800
+ const tokenInfo = this.resolveToken(tokenSymbol);
1801
+ const accountAddr = await this.getAccountAddress();
1802
+ const pos = await this.morpho.getPosition(accountAddr, tokenInfo.address);
1803
+ return {
1804
+ token: tokenSymbol,
1805
+ collateralAmount: pos.collateralAmount,
1806
+ borrowedAmount: pos.borrowedAmount,
1807
+ borrowShares: pos.borrowShares,
1808
+ isActive: pos.isActive
1809
+ };
1810
+ }
1811
+ /**
1812
+ * Get all active positions across all collateral tokens.
1813
+ */
1814
+ async getAllPositions() {
1815
+ const accountAddr = await this.getAccountAddress();
1816
+ const positions = [];
1817
+ for (const [symbol, info] of Object.entries(this.collaterals)) {
1818
+ const pos = await this.morpho.getPosition(accountAddr, info.address);
1819
+ if (pos.isActive || pos.collateralAmount > 0n || pos.borrowedAmount > 0n) {
1820
+ positions.push({
1821
+ token: symbol,
1822
+ collateralAmount: pos.collateralAmount,
1823
+ borrowedAmount: pos.borrowedAmount,
1824
+ borrowShares: pos.borrowShares,
1825
+ isActive: pos.isActive
1826
+ });
1827
+ }
1828
+ }
1829
+ return positions;
1830
+ }
1831
+ /**
1832
+ * Get total debt across all positions.
1833
+ */
1834
+ async getTotalDebt() {
1835
+ const accountAddr = await this.getAccountAddress();
1836
+ return this.morpho.getTotalDebt(accountAddr);
1837
+ }
1838
+ /**
1839
+ * Get USDC balance in the AgentAccount.
1840
+ */
1841
+ async getAccountUSDC() {
1842
+ const accountAddr = await this.getAccountAddress();
1843
+ const usdc = new import_ethers5.Contract(this.config.contracts.usdc, ERC20_ABI, this.signer.provider);
1844
+ return usdc.balanceOf(accountAddr);
1845
+ }
1846
+ /** Get the wallet (signer) address */
1847
+ getAddress() {
1848
+ return this.signer.address;
1849
+ }
1850
+ };
1851
+
1852
+ // src/clients/WalletClient.ts
1853
+ var import_ethers6 = require("ethers");
1443
1854
  var WalletClient = class {
1444
1855
  constructor(config) {
1445
1856
  this.privateKey = null;
1446
1857
  this.factoryAddress = config.factoryAddress;
1447
- this.usdcAddress = config.usdcAddress || import_ethers5.ethers.ZeroAddress;
1858
+ this.usdcAddress = config.usdcAddress || import_ethers6.ethers.ZeroAddress;
1448
1859
  this.chainId = config.chainId;
1449
1860
  this.rpcUrl = config.rpcUrl;
1450
- this.provider = new import_ethers5.ethers.JsonRpcProvider(config.rpcUrl);
1861
+ this.provider = new import_ethers6.ethers.JsonRpcProvider(config.rpcUrl);
1451
1862
  this.privateKey = config.privateKey || null;
1452
1863
  }
1453
1864
  /**
@@ -1457,20 +1868,20 @@ var WalletClient = class {
1457
1868
  if (!this.privateKey) {
1458
1869
  throw new Error("Signer not configured - provide privateKey");
1459
1870
  }
1460
- const freshProvider = new import_ethers5.ethers.JsonRpcProvider(this.rpcUrl);
1461
- return new import_ethers5.Wallet(this.privateKey, freshProvider);
1871
+ const freshProvider = new import_ethers6.ethers.JsonRpcProvider(this.rpcUrl);
1872
+ return new import_ethers6.Wallet(this.privateKey, freshProvider);
1462
1873
  }
1463
1874
  getFactoryContract() {
1464
1875
  if (this.privateKey) {
1465
- return new import_ethers5.Contract(this.factoryAddress, ACCOUNT_FACTORY_ABI, this.getFreshSigner());
1876
+ return new import_ethers6.Contract(this.factoryAddress, ACCOUNT_FACTORY_ABI, this.getFreshSigner());
1466
1877
  }
1467
- return new import_ethers5.Contract(this.factoryAddress, ACCOUNT_FACTORY_ABI, this.provider);
1878
+ return new import_ethers6.Contract(this.factoryAddress, ACCOUNT_FACTORY_ABI, this.provider);
1468
1879
  }
1469
1880
  getAccountContract(accountAddress) {
1470
1881
  if (this.privateKey) {
1471
- return new import_ethers5.Contract(accountAddress, AGENT_ACCOUNT_ABI, this.getFreshSigner());
1882
+ return new import_ethers6.Contract(accountAddress, AGENT_ACCOUNT_ABI, this.getFreshSigner());
1472
1883
  }
1473
- return new import_ethers5.Contract(accountAddress, AGENT_ACCOUNT_ABI, this.provider);
1884
+ return new import_ethers6.Contract(accountAddress, AGENT_ACCOUNT_ABI, this.provider);
1474
1885
  }
1475
1886
  getChainId() {
1476
1887
  return this.chainId;
@@ -1483,7 +1894,7 @@ var WalletClient = class {
1483
1894
  async getAccount(agentId) {
1484
1895
  const factory = this.getFactoryContract();
1485
1896
  const address = await factory.getAccount(agentId);
1486
- if (address === import_ethers5.ethers.ZeroAddress) {
1897
+ if (address === import_ethers6.ethers.ZeroAddress) {
1487
1898
  return null;
1488
1899
  }
1489
1900
  return address;
@@ -1518,7 +1929,7 @@ var WalletClient = class {
1518
1929
  account.ethBalance()
1519
1930
  ]);
1520
1931
  let usdcBalance = 0n;
1521
- if (this.usdcAddress !== import_ethers5.ethers.ZeroAddress) {
1932
+ if (this.usdcAddress !== import_ethers6.ethers.ZeroAddress) {
1522
1933
  usdcBalance = await account.balanceOf(this.usdcAddress);
1523
1934
  }
1524
1935
  return {
@@ -1530,7 +1941,7 @@ var WalletClient = class {
1530
1941
  };
1531
1942
  }
1532
1943
  async getProviderStatus(accountAddress, creditProvider) {
1533
- const provider = new import_ethers5.Contract(
1944
+ const provider = new import_ethers6.Contract(
1534
1945
  creditProvider,
1535
1946
  CREDIT_PROVIDER_ABI,
1536
1947
  this.provider
@@ -1553,11 +1964,11 @@ var WalletClient = class {
1553
1964
  throw new Error("Signer not configured");
1554
1965
  }
1555
1966
  const signer = this.getFreshSigner();
1556
- const token = new import_ethers5.Contract(tokenAddress, ERC20_ABI, signer);
1967
+ const token = new import_ethers6.Contract(tokenAddress, ERC20_ABI, signer);
1557
1968
  const approveTx = await token.approve(accountAddress, amount);
1558
1969
  await approveTx.wait();
1559
1970
  const signer2 = this.getFreshSigner();
1560
- const account = new import_ethers5.Contract(accountAddress, AGENT_ACCOUNT_ABI, signer2);
1971
+ const account = new import_ethers6.Contract(accountAddress, AGENT_ACCOUNT_ABI, signer2);
1561
1972
  const tx = await account.fund(tokenAddress, amount);
1562
1973
  const receipt = await tx.wait();
1563
1974
  return receipt.hash;
@@ -1603,8 +2014,8 @@ var WalletClient = class {
1603
2014
  }
1604
2015
  // ============ Utility ============
1605
2016
  generatePaymentMessageHash(accountAddress, recipient, amount, nonce, deadline, chainId) {
1606
- return import_ethers5.ethers.keccak256(
1607
- import_ethers5.ethers.AbiCoder.defaultAbiCoder().encode(
2017
+ return import_ethers6.ethers.keccak256(
2018
+ import_ethers6.ethers.AbiCoder.defaultAbiCoder().encode(
1608
2019
  ["address", "uint256", "uint256", "uint256", "uint256", "address"],
1609
2020
  [recipient, amount, nonce, deadline, chainId, accountAddress]
1610
2021
  )
@@ -1671,6 +2082,7 @@ function rateToBps(rate) {
1671
2082
  InsufficientCreditError,
1672
2083
  LP_VAULT_ABI,
1673
2084
  MORPHO_CREDIT_ABI,
2085
+ MorphoCreditClient,
1674
2086
  REPUTATION_CREDIT_ABI,
1675
2087
  ScoringClient,
1676
2088
  ScoringRejectedError,