@agether/agether 2.0.1 → 2.1.0

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 (2) hide show
  1. package/package.json +2 -2
  2. package/src/index.ts +167 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agether/agether",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "OpenClaw plugin for Agether — onchain credit for AI agents",
5
5
  "main": "src/index.ts",
6
6
  "openclaw": {
@@ -9,7 +9,7 @@
9
9
  ]
10
10
  },
11
11
  "dependencies": {
12
- "@agether/sdk": "^2.3.4",
12
+ "@agether/sdk": "^2.4.0",
13
13
  "axios": "^1.6.0",
14
14
  "ethers": "^6.9.0"
15
15
  },
package/src/index.ts CHANGED
@@ -536,6 +536,173 @@ export default function register(api: any) {
536
536
  },
537
537
  });
538
538
 
539
+ // ═══════════════════════════════════════════════════════
540
+ // TOOL: morpho_supply (lender-side — earn yield)
541
+ // ═══════════════════════════════════════════════════════
542
+ api.registerTool({
543
+ name: "morpho_supply",
544
+ description:
545
+ "Supply USDC to a Morpho Blue market as a LENDER to earn yield. " +
546
+ "This is the lending side — your USDC earns interest from borrowers. " +
547
+ "Unlike morpho_deposit (collateral for borrowing), this puts USDC to work earning APY.",
548
+ parameters: {
549
+ type: "object",
550
+ properties: {
551
+ amount: { type: "string", description: "USDC amount to supply (e.g. '500')" },
552
+ market: {
553
+ type: "string",
554
+ enum: ["WETH", "wstETH", "cbETH"],
555
+ description: "Which market to supply to, identified by collateral token (optional — auto-picks highest APY)",
556
+ },
557
+ },
558
+ required: ["amount"],
559
+ },
560
+ async execute(_id: string, params: { amount: string; market?: string }) {
561
+ try {
562
+ const cfg = getConfig(api);
563
+ const client = createClient(cfg);
564
+ const result = await client.supplyAsset(params.amount, params.market);
565
+ return ok(JSON.stringify({
566
+ status: "supplied",
567
+ amount: `$${params.amount} USDC`,
568
+ market: result.collateralToken,
569
+ agentAccount: result.agentAccount,
570
+ note: "USDC is now earning yield from borrowers in this market",
571
+ tx: txLink(result.tx),
572
+ }));
573
+ } catch (e) { return fail(e); }
574
+ },
575
+ });
576
+
577
+ // ═══════════════════════════════════════════════════════
578
+ // TOOL: morpho_supply_status (supply positions + yield)
579
+ // ═══════════════════════════════════════════════════════
580
+ api.registerTool({
581
+ name: "morpho_supply_status",
582
+ description:
583
+ "Show all supply (lending) positions with earned yield. " +
584
+ "Tracks yield WITHOUT any database — reads Morpho events directly from blockchain. " +
585
+ "Shows: current position value, net deposited, earned yield, and current APY.",
586
+ parameters: {
587
+ type: "object",
588
+ properties: {
589
+ market: {
590
+ type: "string",
591
+ enum: ["WETH", "wstETH", "cbETH"],
592
+ description: "Filter by market collateral token (optional)",
593
+ },
594
+ },
595
+ required: [],
596
+ },
597
+ async execute(_id: string, params: { market?: string }) {
598
+ try {
599
+ const cfg = getConfig(api);
600
+ const client = createClient(cfg);
601
+ const positions = await client.getSupplyPositions(params.market);
602
+
603
+ if (positions.length === 0) {
604
+ return ok("No active supply positions. Use morpho_supply to start earning yield.");
605
+ }
606
+
607
+ const formatted = positions.map((p: any) => ({
608
+ market: `${p.collateralToken}/${p.loanToken}`,
609
+ suppliedAssets: `$${p.suppliedAssets} USDC`,
610
+ netDeposited: `$${p.netDeposited} USDC`,
611
+ earnedYield: `$${p.earnedYield} USDC`,
612
+ supplyApy: `${(p.supplyApy * 100).toFixed(2)}%`,
613
+ marketId: p.marketId.slice(0, 18) + "…",
614
+ }));
615
+
616
+ const totalYield = positions.reduce((s: number, p: any) => s + parseFloat(p.earnedYield), 0);
617
+ const totalSupplied = positions.reduce((s: number, p: any) => s + parseFloat(p.suppliedAssets), 0);
618
+
619
+ return ok(JSON.stringify({
620
+ positions: formatted,
621
+ totals: {
622
+ totalSupplied: `$${totalSupplied.toFixed(2)} USDC`,
623
+ totalYield: `$${totalYield.toFixed(6)} USDC`,
624
+ },
625
+ }, null, 2));
626
+ } catch (e) { return fail(e); }
627
+ },
628
+ });
629
+
630
+ // ═══════════════════════════════════════════════════════
631
+ // TOOL: morpho_withdraw_supply (withdraw lent USDC)
632
+ // ═══════════════════════════════════════════════════════
633
+ api.registerTool({
634
+ name: "morpho_withdraw_supply",
635
+ description:
636
+ "Withdraw supplied USDC (principal + earned interest) from a Morpho Blue lending position. " +
637
+ "Use amount 'all' to withdraw the full position. Different from morpho_withdraw which withdraws collateral.",
638
+ parameters: {
639
+ type: "object",
640
+ properties: {
641
+ amount: { type: "string", description: "USDC amount to withdraw (e.g. '100' or 'all')" },
642
+ market: {
643
+ type: "string",
644
+ enum: ["WETH", "wstETH", "cbETH"],
645
+ description: "Market collateral token (optional — auto-detects)",
646
+ },
647
+ },
648
+ required: ["amount"],
649
+ },
650
+ async execute(_id: string, params: { amount: string; market?: string }) {
651
+ try {
652
+ const cfg = getConfig(api);
653
+ const client = createClient(cfg);
654
+ const result = await client.withdrawSupply(params.amount, params.market);
655
+ return ok(JSON.stringify({
656
+ status: "withdrawn",
657
+ amount: params.amount === "all" ? "all (full position)" : `$${params.amount} USDC`,
658
+ remainingSupply: `$${result.remainingSupply} USDC`,
659
+ destination: result.destination,
660
+ tx: txLink(result.tx),
661
+ }));
662
+ } catch (e) { return fail(e); }
663
+ },
664
+ });
665
+
666
+ // ═══════════════════════════════════════════════════════
667
+ // TOOL: morpho_pay_from_yield (pay using only earned yield)
668
+ // ═══════════════════════════════════════════════════════
669
+ api.registerTool({
670
+ name: "morpho_pay_from_yield",
671
+ description:
672
+ "Pay a recipient using ONLY earned yield from a supply position. " +
673
+ "Your principal stays untouched — only the interest earned gets withdrawn and sent. " +
674
+ "Fails if requested amount exceeds available yield.",
675
+ parameters: {
676
+ type: "object",
677
+ properties: {
678
+ recipient: { type: "string", description: "Recipient address (0x...)" },
679
+ amount: { type: "string", description: "USDC amount to pay from yield (e.g. '2.50')" },
680
+ market: {
681
+ type: "string",
682
+ enum: ["WETH", "wstETH", "cbETH"],
683
+ description: "Which supply position to use (optional — auto-picks highest yield)",
684
+ },
685
+ },
686
+ required: ["recipient", "amount"],
687
+ },
688
+ async execute(_id: string, params: { recipient: string; amount: string; market?: string }) {
689
+ try {
690
+ const cfg = getConfig(api);
691
+ const client = createClient(cfg);
692
+ const result = await client.payFromYield(params.recipient, params.amount, params.market);
693
+ return ok(JSON.stringify({
694
+ status: "paid_from_yield",
695
+ amount: `$${params.amount} USDC`,
696
+ recipient: params.recipient,
697
+ remainingYield: `$${result.remainingYield} USDC`,
698
+ remainingSupply: `$${result.remainingSupply} USDC`,
699
+ note: "Paid from earned interest only — principal untouched",
700
+ tx: txLink(result.tx),
701
+ }));
702
+ } catch (e) { return fail(e); }
703
+ },
704
+ });
705
+
539
706
  // ═══════════════════════════════════════════════════════
540
707
  // TOOL: morpho_markets (Morpho GraphQL API — no backend)
541
708
  // ═══════════════════════════════════════════════════════