@t2000/cli 0.13.0 → 0.14.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
@@ -186,16 +186,27 @@ function registerInit(program2) {
186
186
  // src/commands/send.ts
187
187
  import { T2000 as T20002 } from "@t2000/sdk";
188
188
  import { truncateAddress, formatUsd } from "@t2000/sdk";
189
+ var KNOWN_ASSETS = /* @__PURE__ */ new Set(["USDC", "USDT", "USDE", "USDSUI", "SUI"]);
190
+ function parseSendArgs(args) {
191
+ const filtered = args.filter((a) => a.toLowerCase() !== "to");
192
+ if (filtered.length >= 3 && KNOWN_ASSETS.has(filtered[1].toUpperCase())) {
193
+ return { amount: parseFloat(filtered[0]), asset: filtered[1].toUpperCase(), recipient: filtered[2] };
194
+ }
195
+ if (filtered.length >= 2) {
196
+ return { amount: parseFloat(filtered[0]), asset: "USDC", recipient: filtered[filtered.length - 1] };
197
+ }
198
+ throw new Error("Usage: t2000 send <amount> [asset] [to] <address_or_contact>");
199
+ }
189
200
  function registerSend(program2) {
190
- program2.command("send <amount> <asset> [to_keyword] <address>").description("Send USDC (or other asset) to an address").option("--key <path>", "Key file path").action(async (amount, asset, toOrAddress, address, opts) => {
201
+ program2.command("send").argument("<amount>", "Amount to send").argument("[args...]", 'Asset, "to" keyword, and recipient address or contact name').description("Send USDC (or other asset) to an address or contact name").option("--key <path>", "Key file path").action(async (amount, args, opts) => {
191
202
  try {
192
- const recipient = address ?? toOrAddress;
203
+ const { amount: parsedAmount, asset, recipient } = parseSendArgs([amount, ...args]);
193
204
  const pin = await resolvePin();
194
205
  const agent = await T20002.create({ pin, keyPath: opts.key });
195
206
  const result = await agent.send({
196
207
  to: recipient,
197
- amount: parseFloat(amount),
198
- asset: asset.toUpperCase()
208
+ amount: parsedAmount,
209
+ asset
199
210
  });
200
211
  if (isJsonMode()) {
201
212
  printJson(result);
@@ -263,6 +274,14 @@ function registerBalance(program2) {
263
274
  const borrowApy = borrows.length > 0 ? borrows.reduce((sum, p) => sum + p.amount * p.apy, 0) / borrows.reduce((sum, p) => sum + p.amount, 0) : 0;
264
275
  printKeyValue("Credit", `${pc3.red(`-${formatUsd2(bal.debt)}`)} ${pc3.dim(`(${borrowApy.toFixed(2)}% APY)`)}`);
265
276
  }
277
+ if (bal.investment > 0.01) {
278
+ const pnlColor = bal.investmentPnL >= 0 ? pc3.green : pc3.red;
279
+ const pnlSign = bal.investmentPnL >= 0 ? "+" : "";
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)}%)`)}`);
282
+ } else {
283
+ printKeyValue("Investment", pc3.dim("\u2014"));
284
+ }
266
285
  printKeyValue("Gas", `${bal.gasReserve.sui.toFixed(2)} SUI ${pc3.dim(`(~${formatUsd2(bal.gasReserve.usdEquiv)})`)}`);
267
286
  printSeparator();
268
287
  printKeyValue("Total", `${formatUsd2(bal.total)}`);
@@ -274,6 +293,14 @@ function registerBalance(program2) {
274
293
  printKeyValue("Credit", `${pc3.red(`-${formatUsd2(bal.debt)}`)}`);
275
294
  }
276
295
  printKeyValue("Savings", `${formatUsd2(bal.savings)}`);
296
+ if (bal.investment > 0.01) {
297
+ const pnlColor = bal.investmentPnL >= 0 ? pc3.green : pc3.red;
298
+ const pnlSign = bal.investmentPnL >= 0 ? "+" : "";
299
+ const pnlPct = bal.investment > 0 ? bal.investmentPnL / (bal.investment - bal.investmentPnL) * 100 : 0;
300
+ printKeyValue("Investment", `${formatUsd2(bal.investment)} ${pnlColor(`(${pnlSign}${pnlPct.toFixed(1)}%)`)}`);
301
+ } else {
302
+ printKeyValue("Investment", pc3.dim("\u2014"));
303
+ }
277
304
  printKeyValue("Gas", `${bal.gasReserve.sui.toFixed(2)} SUI ${pc3.dim(`(~${formatUsd2(bal.gasReserve.usdEquiv)})`)}`);
278
305
  printSeparator();
279
306
  printKeyValue("Total", `${formatUsd2(bal.total)}`);
@@ -803,7 +830,7 @@ import { homedir as homedir3 } from "os";
803
830
  import { SafeguardEnforcer } from "@t2000/sdk";
804
831
  var CONFIG_DIR = join(homedir3(), ".t2000");
805
832
  var CONFIG_PATH = join(CONFIG_DIR, "config.json");
806
- var SAFEGUARD_KEYS = /* @__PURE__ */ new Set(["locked", "maxPerTx", "maxDailySend", "dailyUsed", "dailyResetDate", "alertThreshold"]);
833
+ var SAFEGUARD_KEYS = /* @__PURE__ */ new Set(["locked", "maxPerTx", "maxDailySend", "dailyUsed", "dailyResetDate", "alertThreshold", "maxLeverage", "maxPositionSize"]);
807
834
  function loadConfig() {
808
835
  try {
809
836
  return JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
@@ -1332,8 +1359,8 @@ function registerLock(program2) {
1332
1359
  if (!pin) {
1333
1360
  throw new Error("PIN required to unlock agent");
1334
1361
  }
1335
- const { T2000: T200024 } = await import("@t2000/sdk");
1336
- await T200024.create({ pin });
1362
+ const { T2000: T200026 } = await import("@t2000/sdk");
1363
+ await T200026.create({ pin });
1337
1364
  const enforcer = new SafeguardEnforcer2(CONFIG_DIR3);
1338
1365
  enforcer.load();
1339
1366
  enforcer.unlock();
@@ -1760,7 +1787,7 @@ function registerMcp(program2) {
1760
1787
  mcp.command("start", { isDefault: true }).description("Start MCP server (stdio transport)").option("--key <path>", "Key file path").action(async (opts) => {
1761
1788
  let mod;
1762
1789
  try {
1763
- mod = await import("./dist-QGTOSQO3.js");
1790
+ mod = await import("./dist-4B5R5GWR.js");
1764
1791
  } catch {
1765
1792
  console.error(
1766
1793
  "MCP server not installed. Run:\n npm install -g @t2000/mcp"
@@ -1911,6 +1938,140 @@ function registerContacts(program2) {
1911
1938
  });
1912
1939
  }
1913
1940
 
1941
+ // src/commands/invest.ts
1942
+ import pc13 from "picocolors";
1943
+ import { T2000 as T200024, formatUsd as formatUsd15 } from "@t2000/sdk";
1944
+ function registerInvest(program2) {
1945
+ const investCmd = program2.command("invest").description("Buy or sell investment assets");
1946
+ 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) => {
1947
+ try {
1948
+ const parsed = parseFloat(amount);
1949
+ if (isNaN(parsed) || parsed <= 0 || !isFinite(parsed)) {
1950
+ console.error(pc13.red(" \u2717 Amount must be greater than $0"));
1951
+ process.exitCode = 1;
1952
+ return;
1953
+ }
1954
+ const pin = await resolvePin();
1955
+ const agent = await T200024.create({ pin, keyPath: opts.key });
1956
+ const result = await agent.investBuy({
1957
+ asset: asset.toUpperCase(),
1958
+ usdAmount: parsed,
1959
+ maxSlippage: parseFloat(opts.slippage) / 100
1960
+ });
1961
+ if (isJsonMode()) {
1962
+ printJson(result);
1963
+ return;
1964
+ }
1965
+ printBlank();
1966
+ printSuccess(`Bought ${result.amount.toFixed(4)} ${asset.toUpperCase()} at ${formatUsd15(result.price)}`);
1967
+ printKeyValue("Invested", formatUsd15(result.usdValue));
1968
+ printKeyValue("Portfolio", `${result.position.totalAmount.toFixed(4)} ${asset.toUpperCase()} (avg ${formatUsd15(result.position.avgPrice)})`);
1969
+ printKeyValue("Tx", explorerUrl(result.tx));
1970
+ printBlank();
1971
+ } catch (error) {
1972
+ handleError(error);
1973
+ }
1974
+ });
1975
+ investCmd.command("sell <amount> <asset>").description('Sell USD amount of an asset (or "all")').option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percent", "3").action(async (amount, asset, opts) => {
1976
+ try {
1977
+ const isAll = amount.toLowerCase() === "all";
1978
+ if (!isAll) {
1979
+ const parsed = parseFloat(amount);
1980
+ if (isNaN(parsed) || parsed <= 0 || !isFinite(parsed)) {
1981
+ console.error(pc13.red(" \u2717 Amount must be greater than $0"));
1982
+ process.exitCode = 1;
1983
+ return;
1984
+ }
1985
+ }
1986
+ const pin = await resolvePin();
1987
+ const agent = await T200024.create({ pin, keyPath: opts.key });
1988
+ const usdAmount = isAll ? "all" : parseFloat(amount);
1989
+ const result = await agent.investSell({
1990
+ asset: asset.toUpperCase(),
1991
+ usdAmount,
1992
+ maxSlippage: parseFloat(opts.slippage) / 100
1993
+ });
1994
+ if (isJsonMode()) {
1995
+ printJson(result);
1996
+ return;
1997
+ }
1998
+ printBlank();
1999
+ printSuccess(`Sold ${result.amount.toFixed(4)} ${asset.toUpperCase()} at ${formatUsd15(result.price)}`);
2000
+ printKeyValue("Proceeds", formatUsd15(result.usdValue));
2001
+ if (result.realizedPnL !== void 0) {
2002
+ const pnlColor = result.realizedPnL >= 0 ? pc13.green : pc13.red;
2003
+ const pnlSign = result.realizedPnL >= 0 ? "+" : "";
2004
+ printKeyValue("Realized P&L", pnlColor(`${pnlSign}${formatUsd15(result.realizedPnL)}`));
2005
+ }
2006
+ if (result.position.totalAmount > 0) {
2007
+ printKeyValue("Remaining", `${result.position.totalAmount.toFixed(4)} ${asset.toUpperCase()} (avg ${formatUsd15(result.position.avgPrice)})`);
2008
+ }
2009
+ printKeyValue("Tx", explorerUrl(result.tx));
2010
+ printBlank();
2011
+ } catch (error) {
2012
+ handleError(error);
2013
+ }
2014
+ });
2015
+ }
2016
+
2017
+ // src/commands/portfolio.ts
2018
+ import pc14 from "picocolors";
2019
+ import { T2000 as T200025, formatUsd as formatUsd16 } from "@t2000/sdk";
2020
+ function registerPortfolio(program2) {
2021
+ program2.command("portfolio").description("Show investment portfolio").option("--key <path>", "Key file path").action(async (opts) => {
2022
+ try {
2023
+ const pin = await resolvePin();
2024
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2025
+ const portfolio = await agent.getPortfolio();
2026
+ if (isJsonMode()) {
2027
+ printJson(portfolio);
2028
+ return;
2029
+ }
2030
+ printBlank();
2031
+ if (portfolio.positions.length === 0) {
2032
+ printInfo("No investments yet. Try: t2000 invest buy 100 SUI");
2033
+ printBlank();
2034
+ return;
2035
+ }
2036
+ printHeader("Investment Portfolio");
2037
+ printSeparator();
2038
+ for (const pos of portfolio.positions) {
2039
+ if (pos.currentPrice === 0 && pos.totalAmount > 0) {
2040
+ printKeyValue(
2041
+ pos.asset,
2042
+ `${pos.totalAmount.toFixed(4)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${pc14.yellow("unavailable")}`
2043
+ );
2044
+ } else {
2045
+ const pnlColor = pos.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2046
+ const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2047
+ printKeyValue(
2048
+ 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)}%)`)}`
2050
+ );
2051
+ }
2052
+ }
2053
+ printSeparator();
2054
+ const hasPriceUnavailable = portfolio.positions.some((p) => p.currentPrice === 0 && p.totalAmount > 0);
2055
+ if (hasPriceUnavailable) {
2056
+ printInfo(pc14.yellow("\u26A0 Price data unavailable for some assets. Values may be inaccurate."));
2057
+ }
2058
+ printKeyValue("Total invested", formatUsd16(portfolio.totalInvested));
2059
+ printKeyValue("Current value", formatUsd16(portfolio.totalValue));
2060
+ const upnlColor = portfolio.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2061
+ const upnlSign = portfolio.unrealizedPnL >= 0 ? "+" : "";
2062
+ printKeyValue("Unrealized P&L", upnlColor(`${upnlSign}${formatUsd16(portfolio.unrealizedPnL)} (${upnlSign}${portfolio.unrealizedPnLPct.toFixed(1)}%)`));
2063
+ if (portfolio.realizedPnL !== 0) {
2064
+ const rpnlColor = portfolio.realizedPnL >= 0 ? pc14.green : pc14.red;
2065
+ const rpnlSign = portfolio.realizedPnL >= 0 ? "+" : "";
2066
+ printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd16(portfolio.realizedPnL)}`));
2067
+ }
2068
+ printBlank();
2069
+ } catch (error) {
2070
+ handleError(error);
2071
+ }
2072
+ });
2073
+ }
2074
+
1914
2075
  // src/program.ts
1915
2076
  var require2 = createRequire(import.meta.url);
1916
2077
  var { version: CLI_VERSION } = require2("../package.json");
@@ -1947,6 +2108,8 @@ function createProgram() {
1947
2108
  registerExchange(program2);
1948
2109
  registerMcp(program2);
1949
2110
  registerContacts(program2);
2111
+ registerInvest(program2);
2112
+ registerPortfolio(program2);
1950
2113
  return program2;
1951
2114
  }
1952
2115