@t2000/engine 0.7.1 → 0.7.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 +2 -0
- package/dist/index.js +69 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -823,6 +823,7 @@ declare const transactionHistoryTool: Tool<{
|
|
|
823
823
|
|
|
824
824
|
declare const saveDepositTool: Tool<{
|
|
825
825
|
amount: number;
|
|
826
|
+
asset?: string | undefined;
|
|
826
827
|
}, {
|
|
827
828
|
success: boolean;
|
|
828
829
|
tx: string;
|
|
@@ -861,6 +862,7 @@ declare const sendTransferTool: Tool<{
|
|
|
861
862
|
|
|
862
863
|
declare const borrowTool: Tool<{
|
|
863
864
|
amount: number;
|
|
865
|
+
asset?: string | undefined;
|
|
864
866
|
}, {
|
|
865
867
|
success: boolean;
|
|
866
868
|
tx: string;
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
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) {
|
|
@@ -1020,15 +1043,20 @@ var transactionHistoryTool = buildTool({
|
|
|
1020
1043
|
});
|
|
1021
1044
|
var saveDepositTool = buildTool({
|
|
1022
1045
|
name: "save_deposit",
|
|
1023
|
-
description: "Deposit USDC into NAVI
|
|
1046
|
+
description: "Deposit USDC into NAVI savings to earn yield. ONLY USDC is accepted \u2014 if the user asks to save any other token (USDT, SUI, USDe, etc.), do NOT call this tool. Instead tell them to swap to USDC first, then deposit.",
|
|
1024
1047
|
inputSchema: z.object({
|
|
1025
|
-
amount: z.number().positive()
|
|
1048
|
+
amount: z.number().positive(),
|
|
1049
|
+
asset: z.string().optional().describe("Must be USDC or omitted. Any other asset is rejected.")
|
|
1026
1050
|
}),
|
|
1027
1051
|
jsonSchema: {
|
|
1028
1052
|
type: "object",
|
|
1029
1053
|
properties: {
|
|
1030
1054
|
amount: {
|
|
1031
1055
|
description: "Exact amount of USDC to deposit"
|
|
1056
|
+
},
|
|
1057
|
+
asset: {
|
|
1058
|
+
type: "string",
|
|
1059
|
+
description: "Must be USDC or omitted. Any other asset is rejected."
|
|
1032
1060
|
}
|
|
1033
1061
|
},
|
|
1034
1062
|
required: ["amount"]
|
|
@@ -1036,6 +1064,9 @@ var saveDepositTool = buildTool({
|
|
|
1036
1064
|
isReadOnly: false,
|
|
1037
1065
|
permissionLevel: "confirm",
|
|
1038
1066
|
async call(input, context) {
|
|
1067
|
+
if (input.asset && input.asset.toUpperCase() !== "USDC") {
|
|
1068
|
+
throw new Error(`Only USDC deposits are supported. Cannot deposit ${input.asset}. Swap to USDC first, then deposit.`);
|
|
1069
|
+
}
|
|
1039
1070
|
const agent = requireAgent(context);
|
|
1040
1071
|
const result = await agent.save({ amount: input.amount });
|
|
1041
1072
|
return {
|
|
@@ -1137,16 +1168,21 @@ var sendTransferTool = buildTool({
|
|
|
1137
1168
|
});
|
|
1138
1169
|
var borrowTool = buildTool({
|
|
1139
1170
|
name: "borrow",
|
|
1140
|
-
description: "Borrow USDC against savings collateral. Requires existing savings deposits. Checks max safe borrow and health factor. Returns tx hash, fee, and post-borrow health factor.",
|
|
1171
|
+
description: "Borrow USDC against savings collateral. ONLY USDC borrows are supported. Requires existing savings deposits. Checks max safe borrow and health factor. Returns tx hash, fee, and post-borrow health factor.",
|
|
1141
1172
|
inputSchema: z.object({
|
|
1142
|
-
amount: z.number().positive()
|
|
1173
|
+
amount: z.number().positive(),
|
|
1174
|
+
asset: z.string().optional().describe("Must be USDC or omitted. Any other asset is rejected.")
|
|
1143
1175
|
}),
|
|
1144
1176
|
jsonSchema: {
|
|
1145
1177
|
type: "object",
|
|
1146
1178
|
properties: {
|
|
1147
1179
|
amount: {
|
|
1148
1180
|
type: "number",
|
|
1149
|
-
description: "Amount in
|
|
1181
|
+
description: "Amount in USDC to borrow"
|
|
1182
|
+
},
|
|
1183
|
+
asset: {
|
|
1184
|
+
type: "string",
|
|
1185
|
+
description: "Must be USDC or omitted. Any other asset is rejected."
|
|
1150
1186
|
}
|
|
1151
1187
|
},
|
|
1152
1188
|
required: ["amount"]
|
|
@@ -1154,6 +1190,9 @@ var borrowTool = buildTool({
|
|
|
1154
1190
|
isReadOnly: false,
|
|
1155
1191
|
permissionLevel: "confirm",
|
|
1156
1192
|
async call(input, context) {
|
|
1193
|
+
if (input.asset && input.asset.toUpperCase() !== "USDC") {
|
|
1194
|
+
throw new Error(`Only USDC borrows are supported. Cannot borrow ${input.asset}.`);
|
|
1195
|
+
}
|
|
1157
1196
|
const agent = requireAgent(context);
|
|
1158
1197
|
const result = await agent.borrow({ amount: input.amount });
|
|
1159
1198
|
return {
|
|
@@ -1729,18 +1768,20 @@ var portfolioAnalysisTool = buildTool({
|
|
|
1729
1768
|
throw new Error("No wallet address provided. Sign in first.");
|
|
1730
1769
|
}
|
|
1731
1770
|
const rpcUrl = context.suiRpcUrl ?? "https://fullnode.mainnet.sui.io:443";
|
|
1771
|
+
const DUST_USD = 0.01;
|
|
1732
1772
|
const coins = await fetchWalletCoins(address, rpcUrl);
|
|
1733
1773
|
const nonZero = coins.filter((c) => Number(c.totalBalance) > 0);
|
|
1734
1774
|
const prices = await fetchTokenPrices(nonZero.map((c) => c.coinType)).catch(() => ({}));
|
|
1735
1775
|
let walletValue = 0;
|
|
1736
|
-
const
|
|
1776
|
+
const allAllocations = [];
|
|
1737
1777
|
for (const coin of nonZero) {
|
|
1738
1778
|
const amount = Number(coin.totalBalance) / 10 ** coin.decimals;
|
|
1739
1779
|
const price = prices[coin.coinType] ?? 0;
|
|
1740
1780
|
const usdValue = amount * price;
|
|
1741
1781
|
walletValue += usdValue;
|
|
1742
|
-
|
|
1782
|
+
allAllocations.push({ symbol: coin.symbol, amount, usdValue, percentage: 0 });
|
|
1743
1783
|
}
|
|
1784
|
+
const allocations = allAllocations.filter((a) => a.usdValue >= DUST_USD);
|
|
1744
1785
|
let savingsValue = 0;
|
|
1745
1786
|
let debtValue = 0;
|
|
1746
1787
|
let healthFactor = null;
|