@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
- printKeyValue("Investment", `${formatUsd2(bal.investment)} ${pnlColor(`(${pnlSign}${pnlPct.toFixed(1)}%)`)}`);
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
- printKeyValue("Investment", `${formatUsd2(bal.investment)} ${pnlColor(`(${pnlSign}${pnlPct.toFixed(1)}%)`)}`);
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) => k !== "SUI");
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-4YM7JZSI.js");
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
  }