@t2000/engine 0.7.0 → 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/README.md CHANGED
@@ -87,7 +87,7 @@ QueryEngine.submitMessage()
87
87
 
88
88
  ## Built-in Tools
89
89
 
90
- ### Read Tools (16 — parallel, auto-approved)
90
+ ### Read Tools (19 — parallel, auto-approved)
91
91
 
92
92
  | Tool | Description |
93
93
  |------|-------------|
@@ -100,6 +100,9 @@ QueryEngine.submitMessage()
100
100
  | `web_search` | Web search via Brave Search API |
101
101
  | `swap_quote` | Preview swap route, output amount, and price impact (no execution) |
102
102
  | `volo_stats` | VOLO liquid staking stats — vSUI/SUI rate, APY, TVL |
103
+ | `portfolio_analysis` | Portfolio breakdown with diversification insights |
104
+ | `protocol_deep_dive` | Deep protocol analysis — TVL, yields, risks, alternatives |
105
+ | `mpp_services` | Browse available MPP gateway services and endpoints |
103
106
  | `defillama_yield_pools` | Top yield pools by APY, filterable by chain |
104
107
  | `defillama_protocol_info` | Protocol TVL, category, chains |
105
108
  | `defillama_token_prices` | Current USD prices for Sui tokens |
@@ -108,7 +111,7 @@ QueryEngine.submitMessage()
108
111
  | `defillama_protocol_fees` | Protocol fees/revenue rankings |
109
112
  | `defillama_sui_protocols` | Sui ecosystem protocols — TVL, category, changes |
110
113
 
111
- ### Write Tools (10 — serial, confirmation required)
114
+ ### Write Tools (11 — serial, confirmation required)
112
115
 
113
116
  | Tool | Description |
114
117
  |------|-------------|
@@ -122,6 +125,7 @@ QueryEngine.submitMessage()
122
125
  | `swap_execute` | Swap any token pair via Cetus Aggregator (20+ DEXs) |
123
126
  | `volo_stake` | Stake SUI for vSUI (VOLO liquid staking) |
124
127
  | `volo_unstake` | Unstake vSUI back to SUI |
128
+ | `save_contact` | Save a contact name + address for quick sends |
125
129
 
126
130
  ## Configuration
127
131
 
package/dist/index.js CHANGED
@@ -336,11 +336,10 @@ function transformRewards(raw) {
336
336
  var STABLECOIN_SYMBOLS = /* @__PURE__ */ new Set([
337
337
  "USDC",
338
338
  "USDT",
339
+ "USDe",
340
+ "USDsui",
339
341
  "wUSDC",
340
342
  "wUSDT",
341
- "FDUSD",
342
- "AUSD",
343
- "BUCK",
344
343
  "suiUSDe",
345
344
  "USDSUI"
346
345
  ]);
@@ -539,7 +538,7 @@ var balanceCheckTool = buildTool({
539
538
  let availableUsd = 0;
540
539
  let stablesUsd = 0;
541
540
  let gasReserveUsd2 = 0;
542
- const STABLE_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USDT", "wUSDC", "wUSDT", "FDUSD", "AUSD", "BUCK"]);
541
+ const STABLE_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USDT", "USDe", "USDsui", "wUSDC", "wUSDT"]);
543
542
  const holdings = [];
544
543
  for (const coin of coins) {
545
544
  const balance2 = Number(coin.totalBalance) / 10 ** coin.decimals;
@@ -578,6 +577,7 @@ var balanceCheckTool = buildTool({
578
577
  debt = posEntries.filter((p) => p.type === "borrow").reduce((sum, p) => sum + p.valueUsd, 0);
579
578
  pendingRewardsUsd = rewardEntries.reduce((sum, r) => sum + r.valueUsd, 0);
580
579
  }
580
+ const visibleHoldings = holdings.filter((h) => h.usdValue >= 0.01).sort((a, b) => b.usdValue - a.usdValue);
581
581
  const bal = {
582
582
  available: availableUsd,
583
583
  savings,
@@ -586,7 +586,7 @@ var balanceCheckTool = buildTool({
586
586
  gasReserve: gasReserveUsd2,
587
587
  total: availableUsd + savings + gasReserveUsd2 + pendingRewardsUsd - debt,
588
588
  stables: stablesUsd,
589
- holdings: holdings.sort((a, b) => b.usdValue - a.usdValue)
589
+ holdings: visibleHoldings
590
590
  };
591
591
  return {
592
592
  data: bal,
@@ -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) {
@@ -1710,7 +1733,7 @@ ${summary}`
1710
1733
  var inputSchema3 = z.object({
1711
1734
  address: z.string().optional().describe("Sui address to analyze (defaults to connected wallet)")
1712
1735
  });
1713
- var STABLECOINS = /* @__PURE__ */ new Set(["USDC", "USDT", "USDe", "USDsui", "DAI", "BUCK"]);
1736
+ var STABLECOINS = /* @__PURE__ */ new Set(["USDC", "USDT", "USDe", "USDsui"]);
1714
1737
  var portfolioAnalysisTool = buildTool({
1715
1738
  name: "portfolio_analysis",
1716
1739
  description: "Analyze portfolio allocation, risk exposure, and yield optimization. Shows asset breakdown, diversification score, health factor assessment, and actionable suggestions.",
@@ -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;