@t2000/cli 0.14.1 → 0.15.1
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
|
@@ -278,7 +278,17 @@ function registerBalance(program2) {
|
|
|
278
278
|
const pnlColor = bal.investmentPnL >= 0 ? pc3.green : pc3.red;
|
|
279
279
|
const pnlSign = bal.investmentPnL >= 0 ? "+" : "";
|
|
280
280
|
const pnlPct = bal.investment > 0 ? bal.investmentPnL / (bal.investment - bal.investmentPnL) * 100 : 0;
|
|
281
|
-
|
|
281
|
+
let earningInfo = "";
|
|
282
|
+
try {
|
|
283
|
+
const portfolio = await agent.getPortfolio();
|
|
284
|
+
const earningPositions = portfolio.positions.filter((p) => p.earning && p.earningApy);
|
|
285
|
+
if (earningPositions.length > 0) {
|
|
286
|
+
const avgApy = earningPositions.reduce((s, p) => s + (p.earningApy ?? 0) * p.currentValue, 0) / earningPositions.reduce((s, p) => s + p.currentValue, 0);
|
|
287
|
+
earningInfo = `, earning ${avgApy.toFixed(1)}% APY`;
|
|
288
|
+
}
|
|
289
|
+
} catch {
|
|
290
|
+
}
|
|
291
|
+
printKeyValue("Investment", `${formatUsd2(bal.investment)} ${pnlColor(`(${pnlSign}${pnlPct.toFixed(1)}%${earningInfo})`)}`);
|
|
282
292
|
} else {
|
|
283
293
|
printKeyValue("Investment", pc3.dim("\u2014"));
|
|
284
294
|
}
|
|
@@ -297,7 +307,17 @@ function registerBalance(program2) {
|
|
|
297
307
|
const pnlColor = bal.investmentPnL >= 0 ? pc3.green : pc3.red;
|
|
298
308
|
const pnlSign = bal.investmentPnL >= 0 ? "+" : "";
|
|
299
309
|
const pnlPct = bal.investment > 0 ? bal.investmentPnL / (bal.investment - bal.investmentPnL) * 100 : 0;
|
|
300
|
-
|
|
310
|
+
let earningInfo = "";
|
|
311
|
+
try {
|
|
312
|
+
const portfolio = await agent.getPortfolio();
|
|
313
|
+
const earningPositions = portfolio.positions.filter((p) => p.earning && p.earningApy);
|
|
314
|
+
if (earningPositions.length > 0) {
|
|
315
|
+
const avgApy = earningPositions.reduce((s, p) => s + (p.earningApy ?? 0) * p.currentValue, 0) / earningPositions.reduce((s, p) => s + p.currentValue, 0);
|
|
316
|
+
earningInfo = `, earning ${avgApy.toFixed(1)}% APY`;
|
|
317
|
+
}
|
|
318
|
+
} catch {
|
|
319
|
+
}
|
|
320
|
+
printKeyValue("Investment", `${formatUsd2(bal.investment)} ${pnlColor(`(${pnlSign}${pnlPct.toFixed(1)}%${earningInfo})`)}`);
|
|
301
321
|
} else {
|
|
302
322
|
printKeyValue("Investment", pc3.dim("\u2014"));
|
|
303
323
|
}
|
|
@@ -659,7 +679,8 @@ function registerHealth(program2) {
|
|
|
659
679
|
// src/commands/rates.ts
|
|
660
680
|
import pc5 from "picocolors";
|
|
661
681
|
import { T2000 as T200014, SUPPORTED_ASSETS } from "@t2000/sdk";
|
|
662
|
-
var STABLE_ASSETS = Object.keys(SUPPORTED_ASSETS).filter((k) =>
|
|
682
|
+
var STABLE_ASSETS = Object.keys(SUPPORTED_ASSETS).filter((k) => !["SUI", "BTC", "ETH"].includes(k));
|
|
683
|
+
var INVEST_ASSETS = ["SUI", "ETH", "BTC"];
|
|
663
684
|
function registerRates(program2) {
|
|
664
685
|
program2.command("rates").description("Show current APY rates across protocols and stablecoins").option("--key <path>", "Key file path").action(async (opts) => {
|
|
665
686
|
try {
|
|
@@ -688,6 +709,20 @@ function registerRates(program2) {
|
|
|
688
709
|
}
|
|
689
710
|
printBlank();
|
|
690
711
|
}
|
|
712
|
+
const investRates = allRates.filter((r) => INVEST_ASSETS.includes(r.asset));
|
|
713
|
+
if (investRates.length > 0) {
|
|
714
|
+
printLine(pc5.bold("Investment Assets"));
|
|
715
|
+
printDivider();
|
|
716
|
+
for (const asset of INVEST_ASSETS) {
|
|
717
|
+
const assetRates = investRates.filter((r) => r.asset === asset);
|
|
718
|
+
if (assetRates.length === 0) continue;
|
|
719
|
+
const display = SUPPORTED_ASSETS[asset]?.displayName ?? asset;
|
|
720
|
+
for (const entry of assetRates) {
|
|
721
|
+
printKeyValue(`${display} (${entry.protocol})`, `Lend ${entry.rates.saveApy.toFixed(2)}%`);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
printBlank();
|
|
725
|
+
}
|
|
691
726
|
if (allRates.length === 0) {
|
|
692
727
|
printInfo("No protocol rates available");
|
|
693
728
|
printBlank();
|
|
@@ -1787,7 +1822,7 @@ function registerMcp(program2) {
|
|
|
1787
1822
|
mcp.command("start", { isDefault: true }).description("Start MCP server (stdio transport)").option("--key <path>", "Key file path").action(async (opts) => {
|
|
1788
1823
|
let mod;
|
|
1789
1824
|
try {
|
|
1790
|
-
mod = await import("./dist-
|
|
1825
|
+
mod = await import("./dist-TXXQC3NH.js");
|
|
1791
1826
|
} catch {
|
|
1792
1827
|
console.error(
|
|
1793
1828
|
"MCP server not installed. Run:\n npm install -g @t2000/mcp"
|
|
@@ -2014,6 +2049,50 @@ function registerInvest(program2) {
|
|
|
2014
2049
|
handleError(error);
|
|
2015
2050
|
}
|
|
2016
2051
|
});
|
|
2052
|
+
investCmd.command("earn <asset>").description("Deposit invested asset into best-rate lending protocol").option("--key <path>", "Key file path").action(async (asset, opts) => {
|
|
2053
|
+
try {
|
|
2054
|
+
const pin = await resolvePin();
|
|
2055
|
+
const agent = await T200024.create({ pin, keyPath: opts.key });
|
|
2056
|
+
const result = await agent.investEarn({
|
|
2057
|
+
asset: asset.toUpperCase()
|
|
2058
|
+
});
|
|
2059
|
+
if (isJsonMode()) {
|
|
2060
|
+
printJson(result);
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
printBlank();
|
|
2064
|
+
const sym = asset.toUpperCase();
|
|
2065
|
+
printSuccess(`${sym} deposited into ${result.protocol} (${result.apy.toFixed(1)}% APY)`);
|
|
2066
|
+
printKeyValue("Amount", `${formatAssetAmount(result.amount, sym)} ${sym}`);
|
|
2067
|
+
printKeyValue("Protocol", result.protocol);
|
|
2068
|
+
printKeyValue("APY", `${result.apy.toFixed(2)}%`);
|
|
2069
|
+
printKeyValue("Tx", explorerUrl(result.tx));
|
|
2070
|
+
printBlank();
|
|
2071
|
+
} catch (error) {
|
|
2072
|
+
handleError(error);
|
|
2073
|
+
}
|
|
2074
|
+
});
|
|
2075
|
+
investCmd.command("unearn <asset>").description("Withdraw invested asset from lending (keeps in portfolio)").option("--key <path>", "Key file path").action(async (asset, opts) => {
|
|
2076
|
+
try {
|
|
2077
|
+
const pin = await resolvePin();
|
|
2078
|
+
const agent = await T200024.create({ pin, keyPath: opts.key });
|
|
2079
|
+
const result = await agent.investUnearn({
|
|
2080
|
+
asset: asset.toUpperCase()
|
|
2081
|
+
});
|
|
2082
|
+
if (isJsonMode()) {
|
|
2083
|
+
printJson(result);
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2086
|
+
printBlank();
|
|
2087
|
+
const sym = asset.toUpperCase();
|
|
2088
|
+
printSuccess(`Withdrew ${formatAssetAmount(result.amount, sym)} ${sym} from ${result.protocol}`);
|
|
2089
|
+
printKeyValue("Status", `${sym} remains in investment portfolio (locked)`);
|
|
2090
|
+
printKeyValue("Tx", explorerUrl(result.tx));
|
|
2091
|
+
printBlank();
|
|
2092
|
+
} catch (error) {
|
|
2093
|
+
handleError(error);
|
|
2094
|
+
}
|
|
2095
|
+
});
|
|
2017
2096
|
}
|
|
2018
2097
|
|
|
2019
2098
|
// src/commands/portfolio.ts
|
|
@@ -2046,9 +2125,10 @@ function registerPortfolio(program2) {
|
|
|
2046
2125
|
} else {
|
|
2047
2126
|
const pnlColor = pos.unrealizedPnL >= 0 ? pc14.green : pc14.red;
|
|
2048
2127
|
const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
|
|
2128
|
+
const yieldSuffix = pos.earning && pos.earningApy ? ` ${pc14.cyan(`${pos.earningApy.toFixed(1)}% APY (${pos.earningProtocol})`)}` : "";
|
|
2049
2129
|
printKeyValue(
|
|
2050
2130
|
pos.asset,
|
|
2051
|
-
`${formatAssetAmount2(pos.totalAmount, pos.asset)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${formatUsd16(pos.currentPrice)} ${pnlColor(`${pnlSign}${formatUsd16(pos.unrealizedPnL)} (${pnlSign}${pos.unrealizedPnLPct.toFixed(1)}%)`)}`
|
|
2131
|
+
`${formatAssetAmount2(pos.totalAmount, pos.asset)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${formatUsd16(pos.currentPrice)} ${pnlColor(`${pnlSign}${formatUsd16(pos.unrealizedPnL)} (${pnlSign}${pos.unrealizedPnLPct.toFixed(1)}%)`)}${yieldSuffix}`
|
|
2052
2132
|
);
|
|
2053
2133
|
}
|
|
2054
2134
|
}
|