@t2000/engine 0.6.1 → 0.6.3

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.d.ts CHANGED
@@ -1050,7 +1050,8 @@ interface ProtocolProfile {
1050
1050
  mcap: number | null;
1051
1051
  fees24h: number | null;
1052
1052
  revenue24h: number | null;
1053
- audits: string[];
1053
+ auditCount: number;
1054
+ auditLinks: string[];
1054
1055
  url: string;
1055
1056
  twitter: string | null;
1056
1057
  riskFactors: string[];
@@ -1063,6 +1064,8 @@ declare const protocolDeepDiveTool: Tool<{
1063
1064
  declare const defillamaYieldPoolsTool: Tool<{
1064
1065
  limit?: number | undefined;
1065
1066
  chain?: string | undefined;
1067
+ project?: string | undefined;
1068
+ minTvl?: number | undefined;
1066
1069
  }, {
1067
1070
  pool: string;
1068
1071
  protocol: string;
package/dist/index.js CHANGED
@@ -245,6 +245,9 @@ var NaviTools = {
245
245
  };
246
246
 
247
247
  // src/tools/utils.ts
248
+ function hasAgent(context) {
249
+ return !!context.agent;
250
+ }
248
251
  function requireAgent(context) {
249
252
  if (!context.agent) {
250
253
  throw new Error(
@@ -845,29 +848,43 @@ var healthCheckTool = buildTool({
845
848
  };
846
849
  }
847
850
  });
851
+ var YIELDS_API = "https://yields.llama.fi";
848
852
  function formatRatesSummary(rates) {
849
853
  return Object.entries(rates).map(([asset, r]) => `${asset}: Save ${(r.saveApy * 100).toFixed(2)}% / Borrow ${(r.borrowApy * 100).toFixed(2)}%`).join(", ");
850
854
  }
855
+ async function fetchRatesFromDefiLlama() {
856
+ const res = await fetch(`${YIELDS_API}/pools`, { signal: AbortSignal.timeout(15e3) });
857
+ if (!res.ok) throw new Error(`DefiLlama API error: HTTP ${res.status}`);
858
+ const data = await res.json();
859
+ const naviPools = (data.data ?? []).filter(
860
+ (p) => p.chain === "Sui" && p.project === "navi-lending" && p.tvlUsd > 1e4
861
+ );
862
+ const result = {};
863
+ for (const pool of naviPools) {
864
+ const saveApy = (pool.apy ?? 0) / 100;
865
+ const borrowApy = pool.apyBorrow != null ? Math.abs(pool.apyBorrow) / 100 : 0;
866
+ result[pool.symbol] = { saveApy, borrowApy };
867
+ }
868
+ return result;
869
+ }
851
870
  var ratesInfoTool = buildTool({
852
871
  name: "rates_info",
853
- description: "Get current lending/borrowing interest rates (APY) for all supported assets. Returns save APY and borrow APY per asset.",
872
+ description: "Get current NAVI Protocol lending/savings rates (APY) for supported assets on Sui. Returns save APY and borrow APY per asset.",
854
873
  inputSchema: z.object({}),
855
874
  jsonSchema: { type: "object", properties: {}, required: [] },
856
875
  isReadOnly: true,
857
876
  async call(_input, context) {
858
877
  if (hasNaviMcp(context)) {
859
878
  const rates2 = await fetchRates(getMcpManager(context));
860
- return {
861
- data: rates2,
862
- displayText: formatRatesSummary(rates2)
863
- };
879
+ return { data: rates2, displayText: formatRatesSummary(rates2) };
864
880
  }
865
- const agent = requireAgent(context);
866
- const rates = await agent.rates();
867
- return {
868
- data: rates,
869
- displayText: formatRatesSummary(rates)
870
- };
881
+ if (hasAgent(context)) {
882
+ const agent = requireAgent(context);
883
+ const rates2 = await agent.rates();
884
+ return { data: rates2, displayText: formatRatesSummary(rates2) };
885
+ }
886
+ const rates = await fetchRatesFromDefiLlama();
887
+ return { data: rates, displayText: formatRatesSummary(rates) };
871
888
  }
872
889
  });
873
890
  var SUI_TYPE = "0x2::sui::SUI";
@@ -1784,9 +1801,32 @@ ${insightLines}`
1784
1801
  }
1785
1802
  });
1786
1803
  var LLAMA_API = "https://api.llama.fi";
1804
+ var SLUG_ALIASES = {
1805
+ "navi": "navi-lending",
1806
+ "navi-protocol": "navi-lending",
1807
+ "scallop": "scallop-lend"
1808
+ };
1787
1809
  var inputSchema4 = z.object({
1788
- protocol: z.string().describe('Protocol slug (e.g. "navi-protocol", "cetus", "scallop-lend")')
1810
+ protocol: z.string().describe('Protocol slug (e.g. "navi-lending", "cetus", "scallop-lend")')
1789
1811
  });
1812
+ function extractCurrentTvl(proto) {
1813
+ const chainTvls = proto.currentChainTvls;
1814
+ if (chainTvls && typeof chainTvls === "object") {
1815
+ return Object.values(chainTvls).filter((v) => typeof v === "number" && v > 0).reduce((sum, v) => sum + v, 0);
1816
+ }
1817
+ if (Array.isArray(proto.tvl) && proto.tvl.length > 0) {
1818
+ const last = proto.tvl[proto.tvl.length - 1];
1819
+ return last.totalLiquidityUSD ?? 0;
1820
+ }
1821
+ if (typeof proto.tvl === "number") return proto.tvl;
1822
+ return 0;
1823
+ }
1824
+ function fmtTvl(tvl) {
1825
+ if (tvl >= 1e9) return `$${(tvl / 1e9).toFixed(2)}B`;
1826
+ if (tvl >= 1e6) return `$${(tvl / 1e6).toFixed(1)}M`;
1827
+ if (tvl >= 1e3) return `$${(tvl / 1e3).toFixed(0)}K`;
1828
+ return `$${tvl.toFixed(0)}`;
1829
+ }
1790
1830
  var protocolDeepDiveTool = buildTool({
1791
1831
  name: "protocol_deep_dive",
1792
1832
  description: 'Get a comprehensive safety and financial profile of a DeFi protocol. Includes TVL trends, revenue, audit status, and risk assessment. Use when users ask "is X safe?" or "tell me about protocol Y".',
@@ -1794,13 +1834,14 @@ var protocolDeepDiveTool = buildTool({
1794
1834
  jsonSchema: {
1795
1835
  type: "object",
1796
1836
  properties: {
1797
- protocol: { type: "string", description: 'Protocol slug (e.g. "navi-protocol", "cetus")' }
1837
+ protocol: { type: "string", description: 'Protocol slug (e.g. "navi-lending", "cetus")' }
1798
1838
  },
1799
1839
  required: ["protocol"]
1800
1840
  },
1801
1841
  isReadOnly: true,
1802
1842
  async call(input) {
1803
- const slug = input.protocol.toLowerCase().replace(/\s+/g, "-");
1843
+ let slug = input.protocol.toLowerCase().replace(/\s+/g, "-");
1844
+ slug = SLUG_ALIASES[slug] ?? slug;
1804
1845
  const [protocolRes, feesRes] = await Promise.allSettled([
1805
1846
  fetch(`${LLAMA_API}/protocol/${slug}`, { signal: AbortSignal.timeout(1e4) }).then((r) => {
1806
1847
  if (!r.ok) throw new Error(`HTTP ${r.status}`);
@@ -1815,14 +1856,15 @@ var protocolDeepDiveTool = buildTool({
1815
1856
  throw new Error(`Protocol "${slug}" not found on DefiLlama.`);
1816
1857
  }
1817
1858
  const proto = protocolRes.value;
1818
- const tvl = Number(proto.tvl ?? 0);
1859
+ const tvl = extractCurrentTvl(proto);
1819
1860
  const tvlChange1d = Number(proto.change_1d ?? 0);
1820
1861
  const tvlChange7d = Number(proto.change_7d ?? 0);
1821
1862
  const tvlChange30d = Number(proto.change_1m ?? 0);
1822
- const chains = proto.chains ?? [];
1863
+ const chains = Array.isArray(proto.chains) ? proto.chains : [];
1823
1864
  const category = proto.category ?? "Unknown";
1824
- const audits = proto.audits ?? proto.audit_links ?? [];
1825
- const auditNote = proto.audit_note ?? proto.audits;
1865
+ const auditCount = Number(proto.audits) || 0;
1866
+ const auditLinks = Array.isArray(proto.audit_links) ? proto.audit_links : [];
1867
+ const hasAudits = auditCount > 0 || auditLinks.length > 0;
1826
1868
  let fees24h = null;
1827
1869
  let revenue24h = null;
1828
1870
  if (feesRes.status === "fulfilled" && feesRes.value) {
@@ -1832,13 +1874,13 @@ var protocolDeepDiveTool = buildTool({
1832
1874
  }
1833
1875
  const riskFactors = [];
1834
1876
  if (tvl < 1e6) riskFactors.push("TVL under $1M \u2014 low liquidity risk");
1835
- if (tvl < 1e7) riskFactors.push("TVL under $10M \u2014 moderate liquidity");
1877
+ else if (tvl < 1e7) riskFactors.push("TVL under $10M \u2014 moderate liquidity");
1836
1878
  if (tvlChange7d < -15) riskFactors.push(`TVL dropped ${tvlChange7d.toFixed(1)}% in 7 days`);
1837
1879
  if (chains.length === 1) riskFactors.push("Single-chain deployment");
1838
- if (!audits.length && !auditNote) riskFactors.push("No published audits found");
1839
- if (audits.length > 0) riskFactors.push(`${audits.length} audit(s) on file`);
1880
+ if (!hasAudits) riskFactors.push("No published audits found");
1881
+ else riskFactors.push(`${auditCount || auditLinks.length} audit(s) on file`);
1840
1882
  let safetyScore;
1841
- if (tvl > 1e8 && audits.length > 0 && tvlChange7d > -10) {
1883
+ if (tvl > 1e8 && hasAudits && tvlChange7d > -10) {
1842
1884
  safetyScore = "High \u2014 established protocol with audits and significant TVL";
1843
1885
  } else if (tvl > 1e7 && tvlChange7d > -20) {
1844
1886
  safetyScore = "Moderate \u2014 decent TVL, use with caution";
@@ -1857,18 +1899,18 @@ var protocolDeepDiveTool = buildTool({
1857
1899
  mcap: proto.mcap ? Number(proto.mcap) : null,
1858
1900
  fees24h,
1859
1901
  revenue24h,
1860
- audits: typeof auditNote === "string" ? [auditNote] : audits.map(String),
1902
+ auditCount,
1903
+ auditLinks,
1861
1904
  url: proto.url ?? "",
1862
1905
  twitter: proto.twitter ?? null,
1863
1906
  riskFactors,
1864
1907
  safetyScore
1865
1908
  };
1866
- const tvlStr = tvl > 1e9 ? `$${(tvl / 1e9).toFixed(2)}B` : `$${(tvl / 1e6).toFixed(1)}M`;
1867
1909
  const feesStr = fees24h != null ? ` | Fees 24h: $${fees24h.toLocaleString()}` : "";
1868
1910
  return {
1869
1911
  data: result,
1870
1912
  displayText: `**${result.name}** (${category})
1871
- TVL: ${tvlStr} (7d: ${tvlChange7d > 0 ? "+" : ""}${tvlChange7d.toFixed(1)}%)${feesStr}
1913
+ TVL: ${fmtTvl(tvl)} (7d: ${tvlChange7d > 0 ? "+" : ""}${tvlChange7d.toFixed(1)}%)${feesStr}
1872
1914
  Chains: ${chains.join(", ")}
1873
1915
  Safety: ${safetyScore}
1874
1916
  Risks: ${riskFactors.join("; ")}`
@@ -1876,7 +1918,7 @@ Risks: ${riskFactors.join("; ")}`
1876
1918
  }
1877
1919
  });
1878
1920
  var LLAMA_API2 = "https://api.llama.fi";
1879
- var YIELDS_API = "https://yields.llama.fi";
1921
+ var YIELDS_API2 = "https://yields.llama.fi";
1880
1922
  var COINS_API = "https://coins.llama.fi";
1881
1923
  var CACHE_TTL3 = 6e4;
1882
1924
  var apiCache = /* @__PURE__ */ new Map();
@@ -1889,29 +1931,45 @@ async function cachedFetch(url) {
1889
1931
  apiCache.set(url, { data, ts: Date.now() });
1890
1932
  return data;
1891
1933
  }
1934
+ function fmtToolTvl(tvl) {
1935
+ if (tvl >= 1e9) return `$${(tvl / 1e9).toFixed(1)}B`;
1936
+ if (tvl >= 1e6) return `$${(tvl / 1e6).toFixed(1)}M`;
1937
+ if (tvl >= 1e3) return `$${(tvl / 1e3).toFixed(0)}K`;
1938
+ return `$${tvl}`;
1939
+ }
1892
1940
  var defillamaYieldPoolsTool = buildTool({
1893
1941
  name: "defillama_yield_pools",
1894
- description: 'Get top DeFi yield pools across all protocols. Filter by chain (e.g. "Sui") and sort by APY. Shows pool name, protocol, TVL, and APY breakdown.',
1942
+ description: 'Get top DeFi yield pools across protocols. Filter by chain (e.g. "Sui"), project (e.g. "navi-lending"), and minimum TVL. For NAVI lending rates, use project "navi-lending".',
1895
1943
  inputSchema: z.object({
1896
1944
  chain: z.string().optional().describe('Filter by chain name (e.g. "Sui", "Ethereum")'),
1897
- limit: z.number().min(1).max(20).optional().describe("Max results (default 5)")
1945
+ project: z.string().optional().describe('Filter by protocol project name (e.g. "navi-lending", "cetus-clmm")'),
1946
+ limit: z.number().min(1).max(20).optional().describe("Max results (default 5)"),
1947
+ minTvl: z.number().optional().describe("Minimum TVL in USD to filter out small/risky pools (default 100000)")
1898
1948
  }),
1899
1949
  jsonSchema: {
1900
1950
  type: "object",
1901
1951
  properties: {
1902
1952
  chain: { type: "string", description: "Filter by chain name" },
1903
- limit: { type: "number", description: "Max results (default 5)" }
1953
+ project: { type: "string", description: 'Filter by protocol project name (e.g. "navi-lending")' },
1954
+ limit: { type: "number", description: "Max results (default 5)" },
1955
+ minTvl: { type: "number", description: "Minimum TVL in USD (default 100000)" }
1904
1956
  },
1905
1957
  required: []
1906
1958
  },
1907
1959
  isReadOnly: true,
1908
1960
  async call(input) {
1909
- const data = await cachedFetch(`${YIELDS_API}/pools`);
1961
+ const data = await cachedFetch(`${YIELDS_API2}/pools`);
1910
1962
  let pools = data.data ?? [];
1911
1963
  if (input.chain) {
1912
1964
  const chain = input.chain.toLowerCase();
1913
1965
  pools = pools.filter((p) => p.chain.toLowerCase() === chain);
1914
1966
  }
1967
+ if (input.project) {
1968
+ const project = input.project.toLowerCase();
1969
+ pools = pools.filter((p) => p.project.toLowerCase() === project);
1970
+ }
1971
+ const minTvl = input.minTvl ?? 1e5;
1972
+ pools = pools.filter((p) => p.tvlUsd >= minTvl);
1915
1973
  pools.sort((a, b) => b.apy - a.apy);
1916
1974
  const limit = input.limit ?? 5;
1917
1975
  const top = pools.slice(0, limit);
@@ -1926,7 +1984,7 @@ var defillamaYieldPoolsTool = buildTool({
1926
1984
  }));
1927
1985
  return {
1928
1986
  data: results,
1929
- displayText: results.map((r) => `${r.pool} (${r.protocol}): ${r.apy}% APY, $${(r.tvl / 1e6).toFixed(1)}M TVL`).join("\n")
1987
+ displayText: results.map((r) => `${r.pool} (${r.protocol}): ${r.apy}% APY, ${fmtToolTvl(r.tvl)} TVL`).join("\n")
1930
1988
  };
1931
1989
  }
1932
1990
  });
@@ -1958,7 +2016,7 @@ var defillamaProtocolInfoTool = buildTool({
1958
2016
  };
1959
2017
  return {
1960
2018
  data: result,
1961
- displayText: `${result.name}: $${(result.tvl / 1e6).toFixed(1)}M TVL (${result.category}) on ${result.chains.join(", ")}`
2019
+ displayText: `${result.name}: ${fmtToolTvl(result.tvl)} TVL (${result.category}) on ${result.chains.join(", ")}`
1962
2020
  };
1963
2021
  }
1964
2022
  });
@@ -2136,7 +2194,7 @@ var defillamaSuiProtocolsTool = buildTool({
2136
2194
  }));
2137
2195
  return {
2138
2196
  data: results,
2139
- displayText: results.map((r, i) => `${i + 1}. ${r.name} ($${(r.tvl / 1e6).toFixed(1)}M TVL, ${r.category})`).join("\n")
2197
+ displayText: results.map((r, i) => `${i + 1}. ${r.name} (${fmtToolTvl(r.tvl)} TVL, ${r.category})`).join("\n")
2140
2198
  };
2141
2199
  }
2142
2200
  });