@t2000/engine 0.7.1 → 0.7.2

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
@@ -701,9 +701,10 @@ async function fetchProtocolStats(manager, opts) {
701
701
  }
702
702
 
703
703
  // src/tools/savings.ts
704
+ var DUST_THRESHOLD_USD = 0.01;
704
705
  function buildSavingsFromPositions(sp) {
705
706
  const positions = [
706
- ...sp.supplies.map((s) => ({
707
+ ...sp.supplies.filter((s) => s.amountUsd >= DUST_THRESHOLD_USD).map((s) => ({
707
708
  protocol: s.protocol,
708
709
  type: "supply",
709
710
  symbol: s.asset,
@@ -712,7 +713,7 @@ function buildSavingsFromPositions(sp) {
712
713
  apy: s.apy,
713
714
  liquidationThreshold: 0
714
715
  })),
715
- ...sp.borrows_detail.map((b) => ({
716
+ ...sp.borrows_detail.filter((b) => b.amountUsd >= DUST_THRESHOLD_USD).map((b) => ({
716
717
  protocol: b.protocol,
717
718
  type: "borrow",
718
719
  symbol: b.asset,
@@ -742,6 +743,27 @@ function buildSavingsFromPositions(sp) {
742
743
  }
743
744
  };
744
745
  }
746
+ function formatSavingsDisplay(result) {
747
+ const { positions, earnings, fundStatus } = result;
748
+ const supplies = positions.filter((p) => p.type === "supply");
749
+ const borrows = positions.filter((p) => p.type === "borrow");
750
+ const lines = [];
751
+ if (supplies.length > 0) {
752
+ lines.push(`Savings: $${fundStatus.supplied.toFixed(2)} at ${(earnings.currentApy * 100).toFixed(2)}% blended APY`);
753
+ for (const s of supplies) {
754
+ lines.push(` ${s.symbol}: ${s.amount.toFixed(s.amount < 1 ? 6 : 2)} ($${s.valueUsd.toFixed(2)}) at ${(s.apy * 100).toFixed(2)}% APY`);
755
+ }
756
+ } else {
757
+ lines.push("No savings positions.");
758
+ }
759
+ if (borrows.length > 0) {
760
+ const totalDebt = borrows.reduce((s, b) => s + b.valueUsd, 0);
761
+ lines.push(`Debt: $${totalDebt.toFixed(2)}`);
762
+ }
763
+ lines.push(`Daily earnings: $${fundStatus.earnedToday.toFixed(4)}`);
764
+ lines.push(`Monthly projected: $${fundStatus.projectedMonthly.toFixed(4)}`);
765
+ return lines.join("\n");
766
+ }
745
767
  var savingsInfoTool = buildTool({
746
768
  name: "savings_info",
747
769
  description: "Get detailed savings positions and earnings: current deposits by protocol, APY, total yield earned, daily earning rate, and projected monthly returns.",
@@ -751,14 +773,16 @@ var savingsInfoTool = buildTool({
751
773
  async call(_input, context) {
752
774
  if (context.positionFetcher && context.walletAddress) {
753
775
  const sp = await context.positionFetcher(context.walletAddress);
754
- return { data: buildSavingsFromPositions(sp) };
776
+ const result2 = buildSavingsFromPositions(sp);
777
+ return { data: result2, displayText: formatSavingsDisplay(result2) };
755
778
  }
756
779
  if (hasNaviMcp(context)) {
757
780
  const savings = await fetchSavings(
758
781
  getMcpManager(context),
759
782
  getWalletAddress(context)
760
783
  );
761
- return { data: savings };
784
+ savings.positions = savings.positions.filter((p) => p.valueUsd >= DUST_THRESHOLD_USD);
785
+ return { data: savings, displayText: formatSavingsDisplay(savings) };
762
786
  }
763
787
  const agent = requireAgent(context);
764
788
  const [posResult, earnings, fundStatus] = await Promise.all([
@@ -774,25 +798,24 @@ var savingsInfoTool = buildTool({
774
798
  valueUsd: p.amountUsd ?? p.valueUsd ?? 0,
775
799
  apy: p.apy ?? 0,
776
800
  liquidationThreshold: p.liquidationThreshold ?? 0
777
- }));
778
- return {
779
- data: {
780
- positions,
781
- earnings: {
782
- totalYieldEarned: earnings.totalYieldEarned,
783
- currentApy: earnings.currentApy,
784
- dailyEarning: earnings.dailyEarning,
785
- supplied: earnings.supplied
786
- },
787
- fundStatus: {
788
- supplied: fundStatus.supplied,
789
- apy: fundStatus.apy,
790
- earnedToday: fundStatus.earnedToday,
791
- earnedAllTime: fundStatus.earnedAllTime,
792
- projectedMonthly: fundStatus.projectedMonthly
793
- }
801
+ })).filter((p) => p.valueUsd >= DUST_THRESHOLD_USD);
802
+ const result = {
803
+ positions,
804
+ earnings: {
805
+ totalYieldEarned: earnings.totalYieldEarned,
806
+ currentApy: earnings.currentApy,
807
+ dailyEarning: earnings.dailyEarning,
808
+ supplied: earnings.supplied
809
+ },
810
+ fundStatus: {
811
+ supplied: fundStatus.supplied,
812
+ apy: fundStatus.apy,
813
+ earnedToday: fundStatus.earnedToday,
814
+ earnedAllTime: fundStatus.earnedAllTime,
815
+ projectedMonthly: fundStatus.projectedMonthly
794
816
  }
795
817
  };
818
+ return { data: result, displayText: formatSavingsDisplay(result) };
796
819
  }
797
820
  });
798
821
  function hfStatus(hf) {
@@ -1729,18 +1752,20 @@ var portfolioAnalysisTool = buildTool({
1729
1752
  throw new Error("No wallet address provided. Sign in first.");
1730
1753
  }
1731
1754
  const rpcUrl = context.suiRpcUrl ?? "https://fullnode.mainnet.sui.io:443";
1755
+ const DUST_USD = 0.01;
1732
1756
  const coins = await fetchWalletCoins(address, rpcUrl);
1733
1757
  const nonZero = coins.filter((c) => Number(c.totalBalance) > 0);
1734
1758
  const prices = await fetchTokenPrices(nonZero.map((c) => c.coinType)).catch(() => ({}));
1735
1759
  let walletValue = 0;
1736
- const allocations = [];
1760
+ const allAllocations = [];
1737
1761
  for (const coin of nonZero) {
1738
1762
  const amount = Number(coin.totalBalance) / 10 ** coin.decimals;
1739
1763
  const price = prices[coin.coinType] ?? 0;
1740
1764
  const usdValue = amount * price;
1741
1765
  walletValue += usdValue;
1742
- allocations.push({ symbol: coin.symbol, amount, usdValue, percentage: 0 });
1766
+ allAllocations.push({ symbol: coin.symbol, amount, usdValue, percentage: 0 });
1743
1767
  }
1768
+ const allocations = allAllocations.filter((a) => a.usdValue >= DUST_USD);
1744
1769
  let savingsValue = 0;
1745
1770
  let debtValue = 0;
1746
1771
  let healthFactor = null;