@t2000/cli 0.14.0 → 0.15.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.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-4B5R5GWR.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"
@@ -1940,7 +1975,7 @@ function registerContacts(program2) {
1940
1975
 
1941
1976
  // src/commands/invest.ts
1942
1977
  import pc13 from "picocolors";
1943
- import { T2000 as T200024, formatUsd as formatUsd15 } from "@t2000/sdk";
1978
+ import { T2000 as T200024, formatUsd as formatUsd15, formatAssetAmount } from "@t2000/sdk";
1944
1979
  function registerInvest(program2) {
1945
1980
  const investCmd = program2.command("invest").description("Buy or sell investment assets");
1946
1981
  investCmd.command("buy <amount> <asset>").description("Invest USD amount in an asset").option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percent", "3").action(async (amount, asset, opts) => {
@@ -1963,9 +1998,10 @@ function registerInvest(program2) {
1963
1998
  return;
1964
1999
  }
1965
2000
  printBlank();
1966
- printSuccess(`Bought ${result.amount.toFixed(4)} ${asset.toUpperCase()} at ${formatUsd15(result.price)}`);
2001
+ const sym = asset.toUpperCase();
2002
+ printSuccess(`Bought ${formatAssetAmount(result.amount, sym)} ${sym} at ${formatUsd15(result.price)}`);
1967
2003
  printKeyValue("Invested", formatUsd15(result.usdValue));
1968
- printKeyValue("Portfolio", `${result.position.totalAmount.toFixed(4)} ${asset.toUpperCase()} (avg ${formatUsd15(result.position.avgPrice)})`);
2004
+ printKeyValue("Portfolio", `${formatAssetAmount(result.position.totalAmount, sym)} ${sym} (avg ${formatUsd15(result.position.avgPrice)})`);
1969
2005
  printKeyValue("Tx", explorerUrl(result.tx));
1970
2006
  printBlank();
1971
2007
  } catch (error) {
@@ -1996,7 +2032,8 @@ function registerInvest(program2) {
1996
2032
  return;
1997
2033
  }
1998
2034
  printBlank();
1999
- printSuccess(`Sold ${result.amount.toFixed(4)} ${asset.toUpperCase()} at ${formatUsd15(result.price)}`);
2035
+ const sym = asset.toUpperCase();
2036
+ printSuccess(`Sold ${formatAssetAmount(result.amount, sym)} ${sym} at ${formatUsd15(result.price)}`);
2000
2037
  printKeyValue("Proceeds", formatUsd15(result.usdValue));
2001
2038
  if (result.realizedPnL !== void 0) {
2002
2039
  const pnlColor = result.realizedPnL >= 0 ? pc13.green : pc13.red;
@@ -2004,7 +2041,7 @@ function registerInvest(program2) {
2004
2041
  printKeyValue("Realized P&L", pnlColor(`${pnlSign}${formatUsd15(result.realizedPnL)}`));
2005
2042
  }
2006
2043
  if (result.position.totalAmount > 0) {
2007
- printKeyValue("Remaining", `${result.position.totalAmount.toFixed(4)} ${asset.toUpperCase()} (avg ${formatUsd15(result.position.avgPrice)})`);
2044
+ printKeyValue("Remaining", `${formatAssetAmount(result.position.totalAmount, sym)} ${sym} (avg ${formatUsd15(result.position.avgPrice)})`);
2008
2045
  }
2009
2046
  printKeyValue("Tx", explorerUrl(result.tx));
2010
2047
  printBlank();
@@ -2012,11 +2049,55 @@ function registerInvest(program2) {
2012
2049
  handleError(error);
2013
2050
  }
2014
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
+ });
2015
2096
  }
2016
2097
 
2017
2098
  // src/commands/portfolio.ts
2018
2099
  import pc14 from "picocolors";
2019
- import { T2000 as T200025, formatUsd as formatUsd16 } from "@t2000/sdk";
2100
+ import { T2000 as T200025, formatUsd as formatUsd16, formatAssetAmount as formatAssetAmount2 } from "@t2000/sdk";
2020
2101
  function registerPortfolio(program2) {
2021
2102
  program2.command("portfolio").description("Show investment portfolio").option("--key <path>", "Key file path").action(async (opts) => {
2022
2103
  try {
@@ -2039,14 +2120,15 @@ function registerPortfolio(program2) {
2039
2120
  if (pos.currentPrice === 0 && pos.totalAmount > 0) {
2040
2121
  printKeyValue(
2041
2122
  pos.asset,
2042
- `${pos.totalAmount.toFixed(4)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${pc14.yellow("unavailable")}`
2123
+ `${formatAssetAmount2(pos.totalAmount, pos.asset)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${pc14.yellow("unavailable")}`
2043
2124
  );
2044
2125
  } else {
2045
2126
  const pnlColor = pos.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2046
2127
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2128
+ const yieldSuffix = pos.earning && pos.earningApy ? ` ${pc14.cyan(`${pos.earningApy.toFixed(1)}% APY (${pos.earningProtocol})`)}` : "";
2047
2129
  printKeyValue(
2048
2130
  pos.asset,
2049
- `${pos.totalAmount.toFixed(4)} 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}`
2050
2132
  );
2051
2133
  }
2052
2134
  }