@t2000/engine 0.49.0 → 0.50.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.
- package/dist/index.d.ts +3 -0
- package/dist/index.js +304 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1962,6 +1962,9 @@ declare const balanceCheckTool: Tool<{
|
|
|
1962
1962
|
debt: number;
|
|
1963
1963
|
pendingRewards: number;
|
|
1964
1964
|
gasReserve: number;
|
|
1965
|
+
defi: number;
|
|
1966
|
+
defiByProtocol: Partial<Record<"cetus" | "suilend" | "scallop" | "bluefin" | "aftermath" | "haedal", number>>;
|
|
1967
|
+
defiSource: "blockvision" | "partial" | "degraded";
|
|
1965
1968
|
total: number;
|
|
1966
1969
|
stables: number;
|
|
1967
1970
|
holdings: any[];
|
package/dist/index.js
CHANGED
|
@@ -711,6 +711,262 @@ function parseNumberOrNull(input) {
|
|
|
711
711
|
const n = Number(input);
|
|
712
712
|
return Number.isFinite(n) ? n : null;
|
|
713
713
|
}
|
|
714
|
+
var DEFI_PORTFOLIO_TIMEOUT_MS = 4e3;
|
|
715
|
+
var DEFI_CACHE_TTL_MS = 6e4;
|
|
716
|
+
var DEFI_PROTOCOLS = [
|
|
717
|
+
"cetus",
|
|
718
|
+
"suilend",
|
|
719
|
+
"scallop",
|
|
720
|
+
"bluefin",
|
|
721
|
+
"aftermath",
|
|
722
|
+
"haedal"
|
|
723
|
+
];
|
|
724
|
+
var defiCache = /* @__PURE__ */ new Map();
|
|
725
|
+
var defiInflight = /* @__PURE__ */ new Map();
|
|
726
|
+
async function fetchAddressDefiPortfolio(address, apiKey, priceHints = {}) {
|
|
727
|
+
if (!apiKey || apiKey.trim().length === 0) {
|
|
728
|
+
return { totalUsd: 0, perProtocol: {}, pricedAt: Date.now(), source: "degraded" };
|
|
729
|
+
}
|
|
730
|
+
const now = Date.now();
|
|
731
|
+
const cached = defiCache.get(address);
|
|
732
|
+
if (cached && now - cached.ts < DEFI_CACHE_TTL_MS) return cached.data;
|
|
733
|
+
let inflight = defiInflight.get(address);
|
|
734
|
+
if (inflight) return inflight;
|
|
735
|
+
inflight = (async () => {
|
|
736
|
+
try {
|
|
737
|
+
const settled = await Promise.allSettled(
|
|
738
|
+
DEFI_PROTOCOLS.map((p) => fetchOneDefiProtocol(address, p, apiKey))
|
|
739
|
+
);
|
|
740
|
+
const seen = /* @__PURE__ */ new Set();
|
|
741
|
+
for (const s of settled) {
|
|
742
|
+
if (s.status === "fulfilled" && s.value) collectCoinTypes(s.value, seen);
|
|
743
|
+
}
|
|
744
|
+
const normalizedHints = {};
|
|
745
|
+
for (const [k, v] of Object.entries(priceHints)) {
|
|
746
|
+
normalizedHints[normalizeCoinType(k)] = v;
|
|
747
|
+
}
|
|
748
|
+
const missing = Array.from(seen).filter((ct) => {
|
|
749
|
+
const norm = normalizeCoinType(ct);
|
|
750
|
+
return !normalizedHints[norm] && !STABLE_USD_PRICES[norm];
|
|
751
|
+
});
|
|
752
|
+
let fetchedPrices = {};
|
|
753
|
+
if (missing.length > 0) {
|
|
754
|
+
try {
|
|
755
|
+
fetchedPrices = await fetchTokenPrices(missing, apiKey);
|
|
756
|
+
} catch (err) {
|
|
757
|
+
console.warn("[defi] fill-missing-prices failed:", err);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
const prices = { ...normalizedHints };
|
|
761
|
+
for (const [ct, v] of Object.entries(fetchedPrices)) {
|
|
762
|
+
prices[normalizeCoinType(ct)] ??= v.price;
|
|
763
|
+
}
|
|
764
|
+
for (const [ct, p] of Object.entries(STABLE_USD_PRICES)) {
|
|
765
|
+
prices[normalizeCoinType(ct)] ??= p;
|
|
766
|
+
}
|
|
767
|
+
let totalUsd = 0;
|
|
768
|
+
let failures = 0;
|
|
769
|
+
const perProtocol = {};
|
|
770
|
+
for (let i = 0; i < DEFI_PROTOCOLS.length; i++) {
|
|
771
|
+
const proto = DEFI_PROTOCOLS[i];
|
|
772
|
+
const s = settled[i];
|
|
773
|
+
if (s.status !== "fulfilled" || !s.value) {
|
|
774
|
+
failures++;
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
try {
|
|
778
|
+
const usd = NORMALIZERS[proto](s.value, prices);
|
|
779
|
+
if (Number.isFinite(usd) && usd !== 0) {
|
|
780
|
+
perProtocol[proto] = usd;
|
|
781
|
+
totalUsd += usd;
|
|
782
|
+
}
|
|
783
|
+
} catch (err) {
|
|
784
|
+
console.warn(`[defi] ${proto} normaliser threw:`, err);
|
|
785
|
+
failures++;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
if (totalUsd < 0) totalUsd = 0;
|
|
789
|
+
const summary = {
|
|
790
|
+
totalUsd,
|
|
791
|
+
perProtocol,
|
|
792
|
+
pricedAt: Date.now(),
|
|
793
|
+
source: failures === DEFI_PROTOCOLS.length ? "degraded" : failures > 0 ? "partial" : "blockvision"
|
|
794
|
+
};
|
|
795
|
+
defiCache.set(address, { data: summary, ts: Date.now() });
|
|
796
|
+
return summary;
|
|
797
|
+
} finally {
|
|
798
|
+
defiInflight.delete(address);
|
|
799
|
+
}
|
|
800
|
+
})();
|
|
801
|
+
defiInflight.set(address, inflight);
|
|
802
|
+
return inflight;
|
|
803
|
+
}
|
|
804
|
+
async function fetchOneDefiProtocol(address, protocol, apiKey) {
|
|
805
|
+
const url = `${BLOCKVISION_BASE}/account/defiPortfolio?address=${encodeURIComponent(address)}&protocol=${protocol}`;
|
|
806
|
+
let res;
|
|
807
|
+
try {
|
|
808
|
+
res = await fetch(url, {
|
|
809
|
+
headers: { "x-api-key": apiKey, accept: "application/json" },
|
|
810
|
+
signal: AbortSignal.timeout(DEFI_PORTFOLIO_TIMEOUT_MS)
|
|
811
|
+
});
|
|
812
|
+
} catch (err) {
|
|
813
|
+
console.warn(`[defi] ${protocol} fetch threw:`, err);
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
if (!res.ok) {
|
|
817
|
+
console.warn(`[defi] ${protocol} HTTP ${res.status}`);
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
let json;
|
|
821
|
+
try {
|
|
822
|
+
json = await res.json();
|
|
823
|
+
} catch (err) {
|
|
824
|
+
console.warn(`[defi] ${protocol} JSON parse failed:`, err);
|
|
825
|
+
return null;
|
|
826
|
+
}
|
|
827
|
+
if (json.code !== 200 || !json.result) return null;
|
|
828
|
+
return json.result;
|
|
829
|
+
}
|
|
830
|
+
function collectCoinTypes(obj, out) {
|
|
831
|
+
if (!obj || typeof obj !== "object") return;
|
|
832
|
+
if (Array.isArray(obj)) {
|
|
833
|
+
for (const x of obj) collectCoinTypes(x, out);
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
837
|
+
if (typeof v === "string" && v.startsWith("0x") && v.includes("::")) {
|
|
838
|
+
const lk = k.toLowerCase();
|
|
839
|
+
if (lk.includes("cointype") || lk === "cointypea" || lk === "cointypeb" || lk === "tokenxtype" || lk === "tokenytype" || lk === "coinaddress" || lk === "phantomtype" || lk === "typename") {
|
|
840
|
+
out.add(v);
|
|
841
|
+
}
|
|
842
|
+
} else if (typeof v === "object" && v !== null) {
|
|
843
|
+
collectCoinTypes(v, out);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
function priceFor(coinType, prices) {
|
|
848
|
+
const norm = normalizeCoinType(coinType);
|
|
849
|
+
return prices[norm] ?? prices[coinType] ?? STABLE_USD_PRICES[norm] ?? 0;
|
|
850
|
+
}
|
|
851
|
+
function rawToUsd(coinType, raw, decimalsHint, prices) {
|
|
852
|
+
if (raw == null) return 0;
|
|
853
|
+
const decimals = typeof decimalsHint === "number" ? decimalsHint : getDecimalsForCoinType(coinType);
|
|
854
|
+
const amount = Number(raw) / 10 ** decimals;
|
|
855
|
+
if (!Number.isFinite(amount)) return 0;
|
|
856
|
+
return amount * priceFor(coinType, prices);
|
|
857
|
+
}
|
|
858
|
+
var NORMALIZERS = {
|
|
859
|
+
cetus: normalizeCetus,
|
|
860
|
+
suilend: normalizeSuilend,
|
|
861
|
+
scallop: normalizeScallop,
|
|
862
|
+
bluefin: normalizeBluefin,
|
|
863
|
+
aftermath: normalizeAftermath,
|
|
864
|
+
haedal: normalizeHaedal
|
|
865
|
+
};
|
|
866
|
+
function normalizeCetus(result, prices) {
|
|
867
|
+
const data = result.cetus ?? {};
|
|
868
|
+
let total = 0;
|
|
869
|
+
const sumPair = (item, aField, bField) => {
|
|
870
|
+
if (item.coinTypeA && item[aField] != null) {
|
|
871
|
+
const dec = item.coinTypeADecimals ?? item.coinA?.decimals;
|
|
872
|
+
total += rawToUsd(item.coinTypeA, item[aField], dec, prices);
|
|
873
|
+
}
|
|
874
|
+
if (item.coinTypeB && item[bField] != null) {
|
|
875
|
+
const dec = item.coinTypeBDecimals ?? item.coinB?.decimals;
|
|
876
|
+
total += rawToUsd(item.coinTypeB, item[bField], dec, prices);
|
|
877
|
+
}
|
|
878
|
+
};
|
|
879
|
+
for (const lp of data.lps ?? []) sumPair(lp, "balanceA", "balanceB");
|
|
880
|
+
for (const farm of data.farms ?? []) sumPair(farm, "balanceA", "balanceB");
|
|
881
|
+
for (const vault of data.vaults ?? []) sumPair(vault, "coinAAmount", "coinBAmount");
|
|
882
|
+
return total;
|
|
883
|
+
}
|
|
884
|
+
function normalizeSuilend(result, prices) {
|
|
885
|
+
const data = result.suilend ?? {};
|
|
886
|
+
let total = 0;
|
|
887
|
+
for (const d of data.deposits ?? []) {
|
|
888
|
+
if (d.coinType && d.amount != null) total += rawToUsd(d.coinType, d.amount, d.decimals, prices);
|
|
889
|
+
}
|
|
890
|
+
for (const b of data.borrows ?? []) {
|
|
891
|
+
if (b.coinType && b.amount != null) total -= rawToUsd(b.coinType, b.amount, b.decimals, prices);
|
|
892
|
+
}
|
|
893
|
+
for (const s of data.strategies ?? []) {
|
|
894
|
+
if (s.coinType && s.amount != null) total += rawToUsd(s.coinType, s.amount, s.decimals, prices);
|
|
895
|
+
}
|
|
896
|
+
return total;
|
|
897
|
+
}
|
|
898
|
+
function normalizeScallop(result, _prices) {
|
|
899
|
+
const s = result.scallop;
|
|
900
|
+
if (!s) return 0;
|
|
901
|
+
const supply = Number(s.totalSupplyValue ?? 0);
|
|
902
|
+
const collateral = Number(s.totalCollateralValue ?? 0);
|
|
903
|
+
const locked = Number(s.totalLockedScaValue ?? 0);
|
|
904
|
+
const debt = Number(s.totalDebtValue ?? 0);
|
|
905
|
+
const net = (Number.isFinite(supply) ? supply : 0) + (Number.isFinite(collateral) ? collateral : 0) + (Number.isFinite(locked) ? locked : 0) - (Number.isFinite(debt) ? debt : 0);
|
|
906
|
+
return net;
|
|
907
|
+
}
|
|
908
|
+
function normalizeBluefin(result, prices) {
|
|
909
|
+
const data = result.bluefin ?? {};
|
|
910
|
+
let total = 0;
|
|
911
|
+
for (const lp of data.lps ?? []) {
|
|
912
|
+
if (lp.coinTypeA && lp.coinAmountA != null) {
|
|
913
|
+
total += rawToUsd(lp.coinTypeA, lp.coinAmountA, void 0, prices);
|
|
914
|
+
}
|
|
915
|
+
if (lp.coinTypeB && lp.coinAmountB != null) {
|
|
916
|
+
total += rawToUsd(lp.coinTypeB, lp.coinAmountB, void 0, prices);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if (data.usdcVault?.amount != null) {
|
|
920
|
+
total += rawToUsd(
|
|
921
|
+
"0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
|
|
922
|
+
data.usdcVault.amount,
|
|
923
|
+
6,
|
|
924
|
+
prices
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
if (data.blueVault?.amount != null) {
|
|
928
|
+
total += rawToUsd(
|
|
929
|
+
"0xe1b45a0e641b9955a20aa0ad1c1f4ad86aad8afb07296d4085e349a50e90bdca::blue::BLUE",
|
|
930
|
+
data.blueVault.amount,
|
|
931
|
+
9,
|
|
932
|
+
prices
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
return total;
|
|
936
|
+
}
|
|
937
|
+
function normalizeAftermath(result, prices) {
|
|
938
|
+
const data = result.aftermath ?? {};
|
|
939
|
+
let total = 0;
|
|
940
|
+
const positions = [...data.lpPositions ?? [], ...data.farmPositions ?? []];
|
|
941
|
+
for (const pos of positions) {
|
|
942
|
+
for (const c of pos.coins ?? []) {
|
|
943
|
+
if (c.coinType && c.amount != null) {
|
|
944
|
+
total += rawToUsd(c.coinType, c.amount, void 0, prices);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
return total;
|
|
949
|
+
}
|
|
950
|
+
function normalizeHaedal(result, prices) {
|
|
951
|
+
const SUI_TYPE_FULL = "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI";
|
|
952
|
+
const data = result.haedal ?? {};
|
|
953
|
+
let total = 0;
|
|
954
|
+
for (const lp of data.lps ?? []) {
|
|
955
|
+
const item = lp;
|
|
956
|
+
if (item.coinTypeA && item.balanceA != null) {
|
|
957
|
+
total += rawToUsd(item.coinTypeA, item.balanceA, void 0, prices);
|
|
958
|
+
}
|
|
959
|
+
if (item.coinTypeB && item.balanceB != null) {
|
|
960
|
+
total += rawToUsd(item.coinTypeB, item.balanceB, void 0, prices);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
for (const stake of data.stakings ?? []) {
|
|
964
|
+
if (stake.sui_amount != null) {
|
|
965
|
+
total += rawToUsd(SUI_TYPE_FULL, stake.sui_amount, 9, prices);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
return total;
|
|
969
|
+
}
|
|
714
970
|
function clearPortfolioCache() {
|
|
715
971
|
portfolioCache.clear();
|
|
716
972
|
portfolioInflight.clear();
|
|
@@ -808,7 +1064,7 @@ var balanceCheckTool = buildTool({
|
|
|
808
1064
|
const address = targetAddress;
|
|
809
1065
|
const mgr = getMcpManager(context);
|
|
810
1066
|
const hasPositionFetcher = !!context.positionFetcher;
|
|
811
|
-
const [portfolio, positions, rewards, serverPositions] = await Promise.all([
|
|
1067
|
+
const [portfolio, positions, rewards, serverPositions, defiPortfolio] = await Promise.all([
|
|
812
1068
|
loadPortfolio(
|
|
813
1069
|
address,
|
|
814
1070
|
context.blockvisionApiKey,
|
|
@@ -839,7 +1095,22 @@ var balanceCheckTool = buildTool({
|
|
|
839
1095
|
hasPositionFetcher ? context.positionFetcher(address).catch((err) => {
|
|
840
1096
|
console.warn("[balance_check] positionFetcher failed:", err);
|
|
841
1097
|
return null;
|
|
842
|
-
}) : Promise.resolve(null)
|
|
1098
|
+
}) : Promise.resolve(null),
|
|
1099
|
+
// [v0.50] DeFi leg — independent of NAVI (excluded) and the wallet
|
|
1100
|
+
// portfolio (which only has coin holdings). Failure here surfaces
|
|
1101
|
+
// as defi.totalUsd === 0 and `source: 'degraded'`, leaving the
|
|
1102
|
+
// rest of balance_check unaffected. The fetcher fills its own
|
|
1103
|
+
// prices via fetchTokenPrices for any coin types it discovers.
|
|
1104
|
+
fetchAddressDefiPortfolio(address, context.blockvisionApiKey).catch((err) => {
|
|
1105
|
+
console.warn("[balance_check] defi fetch failed:", err);
|
|
1106
|
+
const fallback = {
|
|
1107
|
+
totalUsd: 0,
|
|
1108
|
+
perProtocol: {},
|
|
1109
|
+
pricedAt: Date.now(),
|
|
1110
|
+
source: "degraded"
|
|
1111
|
+
};
|
|
1112
|
+
return fallback;
|
|
1113
|
+
})
|
|
843
1114
|
]);
|
|
844
1115
|
await applyVsuiPriceFallback(portfolio);
|
|
845
1116
|
let availableUsd = 0;
|
|
@@ -886,13 +1157,17 @@ var balanceCheckTool = buildTool({
|
|
|
886
1157
|
const visibleHoldings = holdings.filter((h) => h.usdValue >= 0.01).sort((a, b) => b.usdValue - a.usdValue);
|
|
887
1158
|
const usdcHolding2 = holdings.find((h) => h.symbol === "USDC");
|
|
888
1159
|
const saveableUsdc = usdcHolding2 ? usdcHolding2.balance : 0;
|
|
1160
|
+
const defi2 = defiPortfolio;
|
|
889
1161
|
const bal = {
|
|
890
1162
|
available: availableUsd,
|
|
891
1163
|
savings,
|
|
892
1164
|
debt,
|
|
893
1165
|
pendingRewards: pendingRewardsUsd,
|
|
894
1166
|
gasReserve: gasReserveUsd2,
|
|
895
|
-
|
|
1167
|
+
defi: defi2.totalUsd,
|
|
1168
|
+
defiByProtocol: defi2.perProtocol,
|
|
1169
|
+
defiSource: defi2.source,
|
|
1170
|
+
total: availableUsd + savings + gasReserveUsd2 + pendingRewardsUsd + defi2.totalUsd - debt,
|
|
896
1171
|
stables: stablesUsd,
|
|
897
1172
|
holdings: visibleHoldings,
|
|
898
1173
|
saveableUsdc,
|
|
@@ -902,9 +1177,10 @@ var balanceCheckTool = buildTool({
|
|
|
902
1177
|
};
|
|
903
1178
|
const holdingsList = visibleHoldings.map((h) => `${h.symbol}: ${h.balance < 1 ? h.balance.toFixed(6) : h.balance.toFixed(2)} ($${h.usdValue.toFixed(2)})`).join(", ");
|
|
904
1179
|
const subjectPrefix = isSelfQuery ? "Balance" : `Balance for ${address.slice(0, 6)}\u2026${address.slice(-4)}`;
|
|
1180
|
+
const defiSummaryText = defi2.totalUsd > 0 ? ` Other DeFi positions (LPs/staking/lending across ${Object.keys(defi2.perProtocol).join("/")}): $${defi2.totalUsd.toFixed(2)}.` : "";
|
|
905
1181
|
return {
|
|
906
1182
|
data: bal,
|
|
907
|
-
displayText: `${subjectPrefix}: $${bal.total.toFixed(2)} total. Wallet holdings (NOT savings): ${holdingsList || "none"}. NAVI savings deposits: $${bal.savings.toFixed(2)}
|
|
1183
|
+
displayText: `${subjectPrefix}: $${bal.total.toFixed(2)} total. Wallet holdings (NOT savings): ${holdingsList || "none"}. NAVI savings deposits: $${bal.savings.toFixed(2)}.${defiSummaryText} Saveable USDC (only USDC can be saved): ${saveableUsdc.toFixed(2)} USDC.`
|
|
908
1184
|
};
|
|
909
1185
|
}
|
|
910
1186
|
if (input.address && context.walletAddress && input.address.toLowerCase() !== context.walletAddress.toLowerCase()) {
|
|
@@ -913,13 +1189,28 @@ var balanceCheckTool = buildTool({
|
|
|
913
1189
|
);
|
|
914
1190
|
}
|
|
915
1191
|
const agent = requireAgent(context);
|
|
916
|
-
const
|
|
1192
|
+
const fetchAddress = targetAddress ?? context.walletAddress;
|
|
1193
|
+
const [balance, defi] = await Promise.all([
|
|
1194
|
+
agent.balance(),
|
|
1195
|
+
fetchAddressDefiPortfolio(fetchAddress, context.blockvisionApiKey).catch((err) => {
|
|
1196
|
+
console.warn("[balance_check] sdk-path defi fetch failed:", err);
|
|
1197
|
+
const fallback = {
|
|
1198
|
+
totalUsd: 0,
|
|
1199
|
+
perProtocol: {},
|
|
1200
|
+
pricedAt: Date.now(),
|
|
1201
|
+
source: "degraded"
|
|
1202
|
+
};
|
|
1203
|
+
return fallback;
|
|
1204
|
+
})
|
|
1205
|
+
]);
|
|
917
1206
|
const gasReserveUsd = typeof balance.gasReserve === "number" ? balance.gasReserve : balance.gasReserve.usdEquiv ?? 0;
|
|
918
1207
|
const stablesTotal = typeof balance.stables === "number" ? balance.stables : Object.values(balance.stables).reduce((a, b) => a + b, 0);
|
|
919
1208
|
const sdkHoldings = balance.holdings;
|
|
920
1209
|
const holdingsArr = Array.isArray(sdkHoldings) ? sdkHoldings : [];
|
|
921
1210
|
const usdcHolding = holdingsArr.find((h) => h.symbol === "USDC");
|
|
922
1211
|
const sdkSaveableUsdc = usdcHolding ? usdcHolding.balance ?? 0 : 0;
|
|
1212
|
+
const sdkDefiSummaryText = defi.totalUsd > 0 ? ` Other DeFi positions (LPs/staking/lending across ${Object.keys(defi.perProtocol).join("/")}): $${defi.totalUsd.toFixed(2)}.` : "";
|
|
1213
|
+
const sdkTotal = balance.total + defi.totalUsd;
|
|
923
1214
|
return {
|
|
924
1215
|
data: {
|
|
925
1216
|
available: balance.available,
|
|
@@ -927,14 +1218,17 @@ var balanceCheckTool = buildTool({
|
|
|
927
1218
|
debt: balance.debt,
|
|
928
1219
|
pendingRewards: balance.pendingRewards,
|
|
929
1220
|
gasReserve: gasReserveUsd,
|
|
930
|
-
|
|
1221
|
+
defi: defi.totalUsd,
|
|
1222
|
+
defiByProtocol: defi.perProtocol,
|
|
1223
|
+
defiSource: defi.source,
|
|
1224
|
+
total: sdkTotal,
|
|
931
1225
|
stables: stablesTotal,
|
|
932
1226
|
holdings: holdingsArr,
|
|
933
1227
|
saveableUsdc: sdkSaveableUsdc,
|
|
934
1228
|
address: targetAddress ?? "",
|
|
935
1229
|
isSelfQuery: true
|
|
936
1230
|
},
|
|
937
|
-
displayText: `Balance: $${
|
|
1231
|
+
displayText: `Balance: $${sdkTotal.toFixed(2)} total. Wallet: $${balance.available.toFixed(2)} available. NAVI savings deposits: $${balance.savings.toFixed(2)}.${sdkDefiSummaryText} Saveable USDC (only USDC can be saved): ${sdkSaveableUsdc.toFixed(2)} USDC.`
|
|
938
1232
|
};
|
|
939
1233
|
}
|
|
940
1234
|
});
|
|
@@ -1576,7 +1870,7 @@ var transactionHistoryTool = buildTool({
|
|
|
1576
1870
|
const targetAddress = input.address ?? context.walletAddress;
|
|
1577
1871
|
const isSelfQuery = !!targetAddress && !!context.walletAddress && targetAddress.toLowerCase() === context.walletAddress.toLowerCase();
|
|
1578
1872
|
const prices = context.tokenPrices;
|
|
1579
|
-
const
|
|
1873
|
+
const priceFor2 = (sym) => {
|
|
1580
1874
|
if (!sym || !prices) return void 0;
|
|
1581
1875
|
return prices[sym.toUpperCase()] ?? prices[sym.toLowerCase()] ?? prices[sym];
|
|
1582
1876
|
};
|
|
@@ -1597,8 +1891,8 @@ var transactionHistoryTool = buildTool({
|
|
|
1597
1891
|
if (r.amount == null) return false;
|
|
1598
1892
|
const sym = r.asset?.toUpperCase() ?? "";
|
|
1599
1893
|
const isStableLike = sym === "USDC" || sym === "USDT" || sym === "WUSDC" || sym === "WUSDT" || sym === "SUIUSDT" || sym === "USDY" || sym === "USDSUI" || sym === "USDE" || sym === "AUSD" || sym === "FDUSD" || sym === "BUCK";
|
|
1600
|
-
const usd = isStableLike ? r.amount : (
|
|
1601
|
-
if (!isStableLike &&
|
|
1894
|
+
const usd = isStableLike ? r.amount : (priceFor2(sym) ?? 0) * r.amount;
|
|
1895
|
+
if (!isStableLike && priceFor2(sym) == null) return true;
|
|
1602
1896
|
return usd >= minUsd;
|
|
1603
1897
|
});
|
|
1604
1898
|
}
|