@t2000/cli 0.22.8 → 0.22.9

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
@@ -288,7 +288,7 @@ function registerInit(program2) {
288
288
  } else {
289
289
  console.log(` \u2502 Use the CLI directly: \u2502`);
290
290
  console.log(` \u2502 ${pc2.cyan("t2000 balance")} \u2502`);
291
- console.log(` \u2502 ${pc2.cyan("t2000 invest buy 100 SUI")} \u2502`);
291
+ console.log(` \u2502 ${pc2.cyan("t2000 buy 100 BTC")} \u2502`);
292
292
  console.log(` \u2502 \u2502`);
293
293
  }
294
294
  console.log(` \u2502 Deposit USDC to get started: \u2502`);
@@ -1605,7 +1605,7 @@ function registerLock(program2) {
1605
1605
  });
1606
1606
  program2.command("unlock").description("Unlock agent \u2014 resume operations").action(async () => {
1607
1607
  try {
1608
- const { T2000: T200028 } = await import("@t2000/sdk");
1608
+ const { T2000: T200029 } = await import("@t2000/sdk");
1609
1609
  const MAX_ATTEMPTS2 = 3;
1610
1610
  let pin;
1611
1611
  for (let attempt = 1; attempt <= MAX_ATTEMPTS2; attempt++) {
@@ -1614,7 +1614,7 @@ function registerLock(program2) {
1614
1614
  throw new Error("PIN required to unlock agent");
1615
1615
  }
1616
1616
  try {
1617
- await T200028.create({ pin });
1617
+ await T200029.create({ pin });
1618
1618
  break;
1619
1619
  } catch (error) {
1620
1620
  const msg = error instanceof Error ? error.message : "";
@@ -2034,7 +2034,8 @@ function displayAsset(asset) {
2034
2034
  }
2035
2035
 
2036
2036
  // src/commands/exchange.ts
2037
- import { T2000 as T200023, formatUsd as formatUsd14, SUPPORTED_ASSETS as SUPPORTED_ASSETS3 } from "@t2000/sdk";
2037
+ import { T2000 as T200023, SUPPORTED_ASSETS as SUPPORTED_ASSETS3 } from "@t2000/sdk";
2038
+ import pc14 from "picocolors";
2038
2039
  function resolveAssetName(input) {
2039
2040
  const upper = input.toUpperCase();
2040
2041
  for (const key of Object.keys(SUPPORTED_ASSETS3)) {
@@ -2043,19 +2044,16 @@ function resolveAssetName(input) {
2043
2044
  return input;
2044
2045
  }
2045
2046
  function registerExchange(program2) {
2046
- program2.command("exchange <amount> <from> <to>").description("Exchange between tokens (e.g. USDC \u21CC SUI) via Cetus DEX").option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percentage (default: 3)", "3").action(async (amount, from, to, opts) => {
2047
+ program2.command("exchange <amount> <from> <to>").description('[deprecated \u2014 use "swap" instead] Exchange between tokens').option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percentage (default: 3)", "3").action(async (amount, from, to, opts) => {
2047
2048
  try {
2049
+ console.error(pc14.yellow(' \u26A0 "exchange" is deprecated. Use "swap" instead: t2000 swap %s %s %s'), amount, from, to);
2048
2050
  const pin = await resolvePin();
2049
2051
  const agent = await T200023.create({ pin, keyPath: opts.key });
2050
- const fromAsset = resolveAssetName(from);
2051
- const toAsset = resolveAssetName(to);
2052
2052
  const parsedAmount = parseFloat(amount);
2053
- if (isNaN(parsedAmount) || parsedAmount <= 0) {
2054
- throw new Error("Amount must be a positive number");
2055
- }
2056
- const result = await agent.exchange({
2057
- from: fromAsset,
2058
- to: toAsset,
2053
+ if (isNaN(parsedAmount) || parsedAmount <= 0) throw new Error("Amount must be a positive number");
2054
+ const result = await agent.swap({
2055
+ from: resolveAssetName(from),
2056
+ to: resolveAssetName(to),
2059
2057
  amount: parsedAmount,
2060
2058
  maxSlippage: parseFloat(opts.slippage ?? "3") / 100
2061
2059
  });
@@ -2063,15 +2061,87 @@ function registerExchange(program2) {
2063
2061
  printJson(result);
2064
2062
  return;
2065
2063
  }
2066
- const fromDisplay = SUPPORTED_ASSETS3[fromAsset]?.displayName ?? fromAsset;
2067
- const toDisplay = SUPPORTED_ASSETS3[toAsset]?.displayName ?? toAsset;
2068
- const toDecimals = toAsset === "SUI" ? 4 : 2;
2069
- printBlank();
2070
- const fromStr = ["USDC", "USDT", "USDE"].includes(fromAsset) ? formatUsd14(parsedAmount) : parsedAmount.toFixed(4);
2071
- printSuccess(`Exchanged ${fromStr} ${fromDisplay} \u2192 ${result.toAmount.toFixed(toDecimals)} ${toDisplay}`);
2072
- printKeyValue("Tx", explorerUrl(result.tx));
2073
- printKeyValue("Gas", `${result.gasCost.toFixed(4)} SUI (${result.gasMethod})`);
2074
- printBlank();
2064
+ console.log(pc14.green(" \u2713 Swapped. Tx: %s"), result.tx);
2065
+ } catch (error) {
2066
+ handleError(error);
2067
+ }
2068
+ });
2069
+ }
2070
+
2071
+ // src/commands/swap.ts
2072
+ import { T2000 as T200024, formatUsd as formatUsd14, SUPPORTED_ASSETS as SUPPORTED_ASSETS4 } from "@t2000/sdk";
2073
+ function resolveAssetName2(input) {
2074
+ const upper = input.toUpperCase();
2075
+ for (const key of Object.keys(SUPPORTED_ASSETS4)) {
2076
+ if (key.toUpperCase() === upper) return key;
2077
+ }
2078
+ return input;
2079
+ }
2080
+ function fmtTokenAmount(amount, asset) {
2081
+ if (["USDC", "USDT", "USDE"].includes(asset)) return formatUsd14(amount);
2082
+ if (amount > 0 && amount < 1e-3) return amount.toFixed(8);
2083
+ if (amount > 0 && amount < 1) return amount.toFixed(6);
2084
+ return amount.toFixed(4);
2085
+ }
2086
+ async function executeSwap(from, to, amount, opts, label) {
2087
+ const pin = await resolvePin();
2088
+ const agent = await T200024.create({ pin, keyPath: opts.key });
2089
+ const fromAsset = resolveAssetName2(from);
2090
+ const toAsset = resolveAssetName2(to);
2091
+ const result = await agent.swap({
2092
+ from: fromAsset,
2093
+ to: toAsset,
2094
+ amount,
2095
+ maxSlippage: parseFloat(opts.slippage ?? "3") / 100
2096
+ });
2097
+ if (isJsonMode()) {
2098
+ printJson(result);
2099
+ return;
2100
+ }
2101
+ const fromDisplay = SUPPORTED_ASSETS4[fromAsset]?.displayName ?? fromAsset;
2102
+ const toDisplay = SUPPORTED_ASSETS4[toAsset]?.displayName ?? toAsset;
2103
+ printBlank();
2104
+ if (label === "Bought") {
2105
+ printSuccess(`Bought ${fmtTokenAmount(result.toAmount, toAsset)} ${toDisplay} for ${formatUsd14(amount)}`);
2106
+ } else if (label === "Sold") {
2107
+ printSuccess(`Sold ${fmtTokenAmount(amount, fromAsset)} ${fromDisplay} for ${formatUsd14(result.toAmount)}`);
2108
+ } else {
2109
+ printSuccess(`Swapped ${fmtTokenAmount(amount, fromAsset)} ${fromDisplay} \u2192 ${fmtTokenAmount(result.toAmount, toAsset)} ${toDisplay}`);
2110
+ }
2111
+ printKeyValue("Tx", explorerUrl(result.tx));
2112
+ printKeyValue("Gas", `${result.gasCost.toFixed(4)} SUI (${result.gasMethod})`);
2113
+ printBlank();
2114
+ }
2115
+ function registerSwap(program2) {
2116
+ program2.command("swap <amount> <from> <to>").description("Swap tokens (e.g. swap 100 USDC SUI)").option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percentage (default: 3)", "3").action(async (amount, from, to, opts) => {
2117
+ try {
2118
+ const parsedAmount = parseFloat(amount);
2119
+ if (isNaN(parsedAmount) || parsedAmount <= 0) {
2120
+ throw new Error("Amount must be a positive number");
2121
+ }
2122
+ await executeSwap(from, to, parsedAmount, opts, "Swapped");
2123
+ } catch (error) {
2124
+ handleError(error);
2125
+ }
2126
+ });
2127
+ program2.command("buy <amount> <asset>").description("Buy an asset with USDC (e.g. buy 100 BTC)").option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percentage (default: 3)", "3").action(async (amount, asset, opts) => {
2128
+ try {
2129
+ const parsedAmount = parseFloat(amount);
2130
+ if (isNaN(parsedAmount) || parsedAmount <= 0) {
2131
+ throw new Error("Amount must be a positive number");
2132
+ }
2133
+ await executeSwap("USDC", asset, parsedAmount, opts, "Bought");
2134
+ } catch (error) {
2135
+ handleError(error);
2136
+ }
2137
+ });
2138
+ program2.command("sell <amount> <asset>").description("Sell an asset for USDC (e.g. sell 0.001 BTC)").option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percentage (default: 3)", "3").action(async (amount, asset, opts) => {
2139
+ try {
2140
+ const parsedAmount = parseFloat(amount);
2141
+ if (isNaN(parsedAmount) || parsedAmount <= 0) {
2142
+ throw new Error("Amount must be a positive number");
2143
+ }
2144
+ await executeSwap(asset, "USDC", parsedAmount, opts, "Sold");
2075
2145
  } catch (error) {
2076
2146
  handleError(error);
2077
2147
  }
@@ -2124,7 +2194,7 @@ function registerMcp(program2) {
2124
2194
  mcp.command("start", { isDefault: true }).description("Start MCP server (stdio transport)").option("--key <path>", "Key file path").action(async (opts) => {
2125
2195
  let mod;
2126
2196
  try {
2127
- mod = await import("./dist-NXFA54RO.js");
2197
+ mod = await import("./dist-3RLXPNZ5.js");
2128
2198
  } catch {
2129
2199
  console.error(
2130
2200
  "MCP server not installed. Run:\n npm install -g @t2000/mcp"
@@ -2276,20 +2346,21 @@ function registerContacts(program2) {
2276
2346
  }
2277
2347
 
2278
2348
  // src/commands/invest.ts
2279
- import pc14 from "picocolors";
2280
- import { T2000 as T200024, formatUsd as formatUsd15, formatAssetAmount as formatAssetAmount4, INVESTMENT_ASSETS as INVESTMENT_ASSETS2 } from "@t2000/sdk";
2349
+ import pc15 from "picocolors";
2350
+ import { T2000 as T200025, formatUsd as formatUsd15, formatAssetAmount as formatAssetAmount4, INVESTMENT_ASSETS as INVESTMENT_ASSETS2 } from "@t2000/sdk";
2281
2351
  function registerInvest(program2) {
2282
- const investCmd = program2.command("invest").description("Buy or sell investment assets");
2283
- 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) => {
2352
+ const investCmd = program2.command("invest").description("Investment strategies, DCA, and yield earning");
2353
+ investCmd.command("buy <amount> <asset>").description('[deprecated \u2014 use "buy" instead] Buy an asset').option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percent", "3").action(async (amount, asset, opts) => {
2284
2354
  try {
2355
+ console.error(pc15.yellow(` \u26A0 "invest buy" is deprecated. Use: t2000 buy ${amount} ${asset}`));
2285
2356
  const parsed = parseFloat(amount);
2286
2357
  if (isNaN(parsed) || parsed <= 0 || !isFinite(parsed)) {
2287
- console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2358
+ console.error(pc15.red(" \u2717 Amount must be greater than $0"));
2288
2359
  process.exitCode = 1;
2289
2360
  return;
2290
2361
  }
2291
2362
  const pin = await resolvePin();
2292
- const agent = await T200024.create({ pin, keyPath: opts.key });
2363
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2293
2364
  const result = await agent.investBuy({
2294
2365
  asset: asset.toUpperCase(),
2295
2366
  usdAmount: parsed,
@@ -2303,33 +2374,27 @@ function registerInvest(program2) {
2303
2374
  const sym = asset.toUpperCase();
2304
2375
  printSuccess(`Bought ${formatAssetAmount4(result.amount, sym)} ${sym} at ${formatUsd15(result.price)}`);
2305
2376
  printKeyValue("Invested", formatUsd15(result.usdValue));
2306
- printKeyValue("Portfolio", `${formatAssetAmount4(result.position.totalAmount, sym)} ${sym} (avg ${formatUsd15(result.position.avgPrice)})`);
2307
2377
  printKeyValue("Tx", explorerUrl(result.tx));
2308
2378
  printBlank();
2309
2379
  } catch (error) {
2310
2380
  handleError(error);
2311
2381
  }
2312
2382
  });
2313
- 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) => {
2383
+ investCmd.command("sell <amount> <asset>").description('[deprecated \u2014 use "sell" instead] Sell an asset').option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percent", "3").action(async (amount, asset, opts) => {
2314
2384
  try {
2385
+ console.error(pc15.yellow(` \u26A0 "invest sell" is deprecated. Use: t2000 sell ${amount} ${asset}`));
2315
2386
  const isAll = amount.toLowerCase() === "all";
2316
2387
  if (!isAll) {
2317
2388
  const parsed = parseFloat(amount);
2318
2389
  if (isNaN(parsed) || parsed <= 0 || !isFinite(parsed)) {
2319
- console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2390
+ console.error(pc15.red(" \u2717 Amount must be greater than $0"));
2320
2391
  process.exitCode = 1;
2321
2392
  return;
2322
2393
  }
2323
2394
  }
2324
2395
  const pin = await resolvePin();
2325
- const agent = await T200024.create({ pin, keyPath: opts.key });
2396
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2326
2397
  const sym = asset.toUpperCase();
2327
- const strategyAmount = agent.portfolio.getStrategyAmountForAsset(sym);
2328
- const directAmount = agent.portfolio.getDirectAmount(sym);
2329
- if (isAll && strategyAmount > 0) {
2330
- console.log(pc14.yellow(` \u26A0 This will sell ALL ${sym} including ${formatAssetAmount4(strategyAmount, sym)} from strategies`));
2331
- console.log(pc14.dim(` To sell only strategy positions: t2000 invest strategy sell <strategy-name>`));
2332
- }
2333
2398
  const usdAmount = isAll ? "all" : parseFloat(amount);
2334
2399
  const result = await agent.investSell({
2335
2400
  asset: sym,
@@ -2344,84 +2409,20 @@ function registerInvest(program2) {
2344
2409
  printSuccess(`Sold ${formatAssetAmount4(result.amount, sym)} ${sym} at ${formatUsd15(result.price)}`);
2345
2410
  printKeyValue("Proceeds", formatUsd15(result.usdValue));
2346
2411
  if (result.realizedPnL !== void 0) {
2347
- const pnlColor = result.realizedPnL >= 0 ? pc14.green : pc14.red;
2412
+ const pnlColor = result.realizedPnL >= 0 ? pc15.green : pc15.red;
2348
2413
  const pnlSign = result.realizedPnL >= 0 ? "+" : "";
2349
2414
  printKeyValue("Realized P&L", pnlColor(`${pnlSign}${formatUsd15(result.realizedPnL)}`));
2350
2415
  }
2351
- if (result.position.totalAmount > 0) {
2352
- printKeyValue("Remaining", `${formatAssetAmount4(result.position.totalAmount, sym)} ${sym} (avg ${formatUsd15(result.position.avgPrice)})`);
2353
- }
2354
2416
  printKeyValue("Tx", explorerUrl(result.tx));
2355
2417
  printBlank();
2356
2418
  } catch (error) {
2357
2419
  handleError(error);
2358
2420
  }
2359
2421
  });
2360
- investCmd.command("sell-all").description("Sell ALL investment positions (direct + strategies)").option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percent", "3").action(async (opts) => {
2361
- try {
2362
- const pin = await resolvePin();
2363
- const agent = await T200024.create({ pin, keyPath: opts.key });
2364
- const positions = agent.portfolio.getPositions();
2365
- if (positions.length === 0) {
2366
- if (isJsonMode()) {
2367
- printJson({ sold: [] });
2368
- return;
2369
- }
2370
- printBlank();
2371
- printInfo("No investment positions to sell");
2372
- printBlank();
2373
- return;
2374
- }
2375
- if (isJsonMode()) {
2376
- const results = [];
2377
- for (const pos of positions) {
2378
- const result = await agent.investSell({
2379
- asset: pos.asset,
2380
- usdAmount: "all",
2381
- maxSlippage: parseFloat(opts.slippage) / 100
2382
- });
2383
- results.push(result);
2384
- }
2385
- printJson(results);
2386
- return;
2387
- }
2388
- printBlank();
2389
- printHeader("Selling all positions");
2390
- printSeparator();
2391
- let totalProceeds = 0;
2392
- let totalPnL = 0;
2393
- for (const pos of positions) {
2394
- try {
2395
- const result = await agent.investSell({
2396
- asset: pos.asset,
2397
- usdAmount: "all",
2398
- maxSlippage: parseFloat(opts.slippage) / 100
2399
- });
2400
- const pnl = result.realizedPnL ?? 0;
2401
- const pnlColor = pnl >= 0 ? pc14.green : pc14.red;
2402
- const pnlSign = pnl >= 0 ? "+" : "";
2403
- printKeyValue(pos.asset, `${formatUsd15(result.usdValue)} ${pnlColor(`${pnlSign}${formatUsd15(pnl)}`)}`);
2404
- totalProceeds += result.usdValue;
2405
- totalPnL += pnl;
2406
- } catch (err) {
2407
- const msg = err instanceof Error ? err.message : String(err);
2408
- console.error(pc14.yellow(` \u26A0 ${pos.asset}: ${msg}`));
2409
- }
2410
- }
2411
- printSeparator();
2412
- printKeyValue("Total proceeds", formatUsd15(totalProceeds));
2413
- const rpnlColor = totalPnL >= 0 ? pc14.green : pc14.red;
2414
- const rpnlSign = totalPnL >= 0 ? "+" : "";
2415
- printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd15(totalPnL)}`));
2416
- printBlank();
2417
- } catch (error) {
2418
- handleError(error);
2419
- }
2420
- });
2421
2422
  investCmd.command("earn <asset>").description("Deposit invested asset into best-rate lending protocol").option("--key <path>", "Key file path").option("--protocol <name>", "Force a specific protocol (navi, suilend)").action(async (asset, opts) => {
2422
2423
  try {
2423
2424
  const pin = await resolvePin();
2424
- const agent = await T200024.create({ pin, keyPath: opts.key });
2425
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2425
2426
  const result = await agent.investEarn({
2426
2427
  asset: asset.toUpperCase(),
2427
2428
  protocol: opts.protocol?.toLowerCase()
@@ -2449,7 +2450,7 @@ function registerInvest(program2) {
2449
2450
  investCmd.command("unearn <asset>").description("Withdraw invested asset from lending (keeps in portfolio)").option("--key <path>", "Key file path").action(async (asset, opts) => {
2450
2451
  try {
2451
2452
  const pin = await resolvePin();
2452
- const agent = await T200024.create({ pin, keyPath: opts.key });
2453
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2453
2454
  const result = await agent.investUnearn({
2454
2455
  asset: asset.toUpperCase()
2455
2456
  });
@@ -2460,7 +2461,7 @@ function registerInvest(program2) {
2460
2461
  printBlank();
2461
2462
  const sym = asset.toUpperCase();
2462
2463
  printSuccess(`Withdrew ${formatAssetAmount4(result.amount, sym)} ${sym} from ${result.protocol}`);
2463
- printKeyValue("Status", `${sym} remains in investment portfolio (locked)`);
2464
+ printKeyValue("Status", `${sym} withdrawn to wallet`);
2464
2465
  printKeyValue("Tx", explorerUrl(result.tx));
2465
2466
  printBlank();
2466
2467
  } catch (error) {
@@ -2470,7 +2471,7 @@ function registerInvest(program2) {
2470
2471
  investCmd.command("rebalance").description("Move earning positions to better-rate protocols").option("--key <path>", "Key file path").option("--dry-run", "Preview moves without executing").option("--min-diff <pct>", "Minimum APY difference to trigger move", "0.1").action(async (opts) => {
2471
2472
  try {
2472
2473
  const pin = await resolvePin();
2473
- const agent = await T200024.create({ pin, keyPath: opts.key });
2474
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2474
2475
  const result = await agent.investRebalance({
2475
2476
  dryRun: opts.dryRun,
2476
2477
  minYieldDiff: opts.minDiff ? parseFloat(opts.minDiff) : void 0
@@ -2525,7 +2526,7 @@ function registerInvest(program2) {
2525
2526
  strategyCmd.command("list").description("List available strategies").option("--key <path>", "Key file path").action(async (opts) => {
2526
2527
  try {
2527
2528
  const pin = await resolvePin();
2528
- const agent = await T200024.create({ pin, keyPath: opts.key });
2529
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2529
2530
  const all = agent.strategies.getAll();
2530
2531
  if (isJsonMode()) {
2531
2532
  printJson(all);
@@ -2536,9 +2537,9 @@ function registerInvest(program2) {
2536
2537
  printSeparator();
2537
2538
  for (const [key, def] of Object.entries(all)) {
2538
2539
  const allocs = Object.entries(def.allocations).map(([a, p]) => `${a} ${p}%`).join(", ");
2539
- const tag = def.custom ? pc14.dim(" (custom)") : "";
2540
+ const tag = def.custom ? pc15.dim(" (custom)") : "";
2540
2541
  printKeyValue(key, `${allocs}${tag}`);
2541
- printLine(` ${pc14.dim(def.description)}`);
2542
+ printLine(` ${pc15.dim(def.description)}`);
2542
2543
  }
2543
2544
  printSeparator();
2544
2545
  const hasPositions = Object.keys(all).some((k) => agent.portfolio.hasStrategyPositions(k));
@@ -2554,12 +2555,12 @@ function registerInvest(program2) {
2554
2555
  try {
2555
2556
  const parsed = parseFloat(amount);
2556
2557
  if (isNaN(parsed) || parsed <= 0) {
2557
- console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2558
+ console.error(pc15.red(" \u2717 Amount must be greater than $0"));
2558
2559
  process.exitCode = 1;
2559
2560
  return;
2560
2561
  }
2561
2562
  const pin = await resolvePin();
2562
- const agent = await T200024.create({ pin, keyPath: opts.key });
2563
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2563
2564
  const result = await agent.investStrategy({ strategy: name.toLowerCase(), usdAmount: parsed, dryRun: opts.dryRun });
2564
2565
  if (isJsonMode()) {
2565
2566
  printJson(result);
@@ -2588,7 +2589,7 @@ function registerInvest(program2) {
2588
2589
  printKeyValue("Tx", explorerUrl(txDigests[0]));
2589
2590
  } else {
2590
2591
  for (const buy of result.buys) {
2591
- printLine(` ${pc14.dim(`${buy.asset}: ${explorerUrl(buy.tx)}`)}`);
2592
+ printLine(` ${pc15.dim(`${buy.asset}: ${explorerUrl(buy.tx)}`)}`);
2592
2593
  }
2593
2594
  }
2594
2595
  }
@@ -2600,7 +2601,7 @@ function registerInvest(program2) {
2600
2601
  strategyCmd.command("sell <name>").description("Sell all positions in a strategy").option("--key <path>", "Key file path").action(async (name, opts) => {
2601
2602
  try {
2602
2603
  const pin = await resolvePin();
2603
- const agent = await T200024.create({ pin, keyPath: opts.key });
2604
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2604
2605
  const result = await agent.sellStrategy({ strategy: name.toLowerCase() });
2605
2606
  if (isJsonMode()) {
2606
2607
  printJson(result);
@@ -2610,18 +2611,18 @@ function registerInvest(program2) {
2610
2611
  printSuccess(`Sold all ${name} strategy positions`);
2611
2612
  printSeparator();
2612
2613
  for (const sell of result.sells) {
2613
- const pnlColor = sell.realizedPnL >= 0 ? pc14.green : pc14.red;
2614
+ const pnlColor = sell.realizedPnL >= 0 ? pc15.green : pc15.red;
2614
2615
  const pnlSign = sell.realizedPnL >= 0 ? "+" : "";
2615
2616
  printKeyValue(sell.asset, `${formatAssetAmount4(sell.amount, sell.asset)} \u2192 ${formatUsd15(sell.usdValue)} ${pnlColor(`${pnlSign}${formatUsd15(sell.realizedPnL)}`)}`);
2616
2617
  }
2617
2618
  if (result.failed && result.failed.length > 0) {
2618
2619
  for (const f of result.failed) {
2619
- console.error(pc14.yellow(` \u26A0 ${f.asset}: ${f.reason}`));
2620
+ console.error(pc15.yellow(` \u26A0 ${f.asset}: ${f.reason}`));
2620
2621
  }
2621
2622
  }
2622
2623
  printSeparator();
2623
2624
  printKeyValue("Total proceeds", formatUsd15(result.totalProceeds));
2624
- const rpnlColor = result.realizedPnL >= 0 ? pc14.green : pc14.red;
2625
+ const rpnlColor = result.realizedPnL >= 0 ? pc15.green : pc15.red;
2625
2626
  const rpnlSign = result.realizedPnL >= 0 ? "+" : "";
2626
2627
  printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd15(result.realizedPnL)}`));
2627
2628
  printBlank();
@@ -2632,7 +2633,7 @@ function registerInvest(program2) {
2632
2633
  strategyCmd.command("status <name>").description("Show current status and weights of a strategy").option("--key <path>", "Key file path").action(async (name, opts) => {
2633
2634
  try {
2634
2635
  const pin = await resolvePin();
2635
- const agent = await T200024.create({ pin, keyPath: opts.key });
2636
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2636
2637
  const status = await agent.getStrategyStatus(name.toLowerCase());
2637
2638
  if (isJsonMode()) {
2638
2639
  printJson(status);
@@ -2648,8 +2649,8 @@ function registerInvest(program2) {
2648
2649
  const target = status.definition.allocations[pos.asset] ?? 0;
2649
2650
  const actual = status.currentWeights[pos.asset] ?? 0;
2650
2651
  const drift = actual - target;
2651
- const driftColor = Math.abs(drift) > 3 ? pc14.yellow : pc14.dim;
2652
- const pnlColor = pos.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2652
+ const driftColor = Math.abs(drift) > 3 ? pc15.yellow : pc15.dim;
2653
+ const pnlColor = pos.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2653
2654
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2654
2655
  printKeyValue(
2655
2656
  pos.asset,
@@ -2667,7 +2668,7 @@ function registerInvest(program2) {
2667
2668
  strategyCmd.command("rebalance <name>").description("Rebalance a strategy to target weights").option("--key <path>", "Key file path").action(async (name, opts) => {
2668
2669
  try {
2669
2670
  const pin = await resolvePin();
2670
- const agent = await T200024.create({ pin, keyPath: opts.key });
2671
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2671
2672
  const result = await agent.rebalanceStrategy({ strategy: name.toLowerCase() });
2672
2673
  if (isJsonMode()) {
2673
2674
  printJson(result);
@@ -2680,7 +2681,7 @@ function registerInvest(program2) {
2680
2681
  printSuccess(`Rebalanced ${name} strategy`);
2681
2682
  printSeparator();
2682
2683
  for (const t of result.trades) {
2683
- const action = t.action === "buy" ? pc14.green("BUY") : pc14.red("SELL");
2684
+ const action = t.action === "buy" ? pc15.green("BUY") : pc15.red("SELL");
2684
2685
  printKeyValue(t.asset, `${action} ${formatUsd15(t.usdAmount)} (${formatAssetAmount4(t.amount, t.asset)})`);
2685
2686
  }
2686
2687
  printSeparator();
@@ -2697,14 +2698,14 @@ function registerInvest(program2) {
2697
2698
  for (const pair of opts.alloc) {
2698
2699
  const [asset, pctStr] = pair.split(":");
2699
2700
  if (!asset || !pctStr) {
2700
- console.error(pc14.red(` \u2717 Invalid allocation: '${pair}'. Use ASSET:PCT format (e.g. SUI:60)`));
2701
+ console.error(pc15.red(` \u2717 Invalid allocation: '${pair}'. Use ASSET:PCT format (e.g. SUI:60)`));
2701
2702
  process.exitCode = 1;
2702
2703
  return;
2703
2704
  }
2704
2705
  allocations[asset.toUpperCase()] = parseFloat(pctStr);
2705
2706
  }
2706
2707
  const pin = await resolvePin();
2707
- const agent = await T200024.create({ pin });
2708
+ const agent = await T200025.create({ pin });
2708
2709
  const definition = agent.strategies.create({ name, allocations, description: opts.description });
2709
2710
  if (isJsonMode()) {
2710
2711
  printJson(definition);
@@ -2722,9 +2723,9 @@ function registerInvest(program2) {
2722
2723
  strategyCmd.command("delete <name>").description("Delete a custom strategy").option("--key <path>", "Key file path").action(async (name, opts) => {
2723
2724
  try {
2724
2725
  const pin = await resolvePin();
2725
- const agent = await T200024.create({ pin, keyPath: opts.key });
2726
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2726
2727
  if (agent.portfolio.hasStrategyPositions(name.toLowerCase())) {
2727
- console.error(pc14.red(` \u2717 Strategy '${name}' has open positions. Sell first: t2000 invest strategy sell ${name}`));
2728
+ console.error(pc15.red(` \u2717 Strategy '${name}' has open positions. Sell first: t2000 invest strategy sell ${name}`));
2728
2729
  process.exitCode = 1;
2729
2730
  return;
2730
2731
  }
@@ -2745,22 +2746,22 @@ function registerInvest(program2) {
2745
2746
  try {
2746
2747
  const parsed = parseFloat(amount);
2747
2748
  if (isNaN(parsed) || parsed < 1) {
2748
- console.error(pc14.red(" \u2717 Amount must be at least $1"));
2749
+ console.error(pc15.red(" \u2717 Amount must be at least $1"));
2749
2750
  process.exitCode = 1;
2750
2751
  return;
2751
2752
  }
2752
2753
  if (!["daily", "weekly", "monthly"].includes(frequency)) {
2753
- console.error(pc14.red(" \u2717 Frequency must be daily, weekly, or monthly"));
2754
+ console.error(pc15.red(" \u2717 Frequency must be daily, weekly, or monthly"));
2754
2755
  process.exitCode = 1;
2755
2756
  return;
2756
2757
  }
2757
2758
  const pin = await resolvePin();
2758
- const agent = await T200024.create({ pin, keyPath: opts.key });
2759
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2759
2760
  const allStrategies = agent.strategies.getAll();
2760
2761
  const isStrategy = target ? target.toLowerCase() in allStrategies : false;
2761
2762
  const isAsset = target ? target.toUpperCase() in INVESTMENT_ASSETS2 : false;
2762
2763
  if (target && !isStrategy && !isAsset) {
2763
- console.error(pc14.red(` \u2717 '${target}' is not a valid strategy or asset`));
2764
+ console.error(pc15.red(` \u2717 '${target}' is not a valid strategy or asset`));
2764
2765
  process.exitCode = 1;
2765
2766
  return;
2766
2767
  }
@@ -2791,7 +2792,7 @@ function registerInvest(program2) {
2791
2792
  autoCmd.command("status").description("Show all DCA schedules").option("--key <path>", "Key file path").action(async (opts) => {
2792
2793
  try {
2793
2794
  const pin = await resolvePin();
2794
- const agent = await T200024.create({ pin, keyPath: opts.key });
2795
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2795
2796
  const status = agent.getAutoInvestStatus();
2796
2797
  if (isJsonMode()) {
2797
2798
  printJson(status);
@@ -2807,9 +2808,9 @@ function registerInvest(program2) {
2807
2808
  printSeparator();
2808
2809
  for (const s of status.schedules) {
2809
2810
  const target = s.strategy ?? s.asset ?? "?";
2810
- const statusTag = s.enabled ? pc14.green("active") : pc14.dim("paused");
2811
+ const statusTag = s.enabled ? pc15.green("active") : pc15.dim("paused");
2811
2812
  printKeyValue(s.id, `${formatUsd15(s.amount)} ${s.frequency} \u2192 ${target} ${statusTag}`);
2812
- printLine(` ${pc14.dim(`Next: ${new Date(s.nextRun).toLocaleDateString()} \xB7 Runs: ${s.runCount} \xB7 Total: ${formatUsd15(s.totalInvested)}`)}`);
2813
+ printLine(` ${pc15.dim(`Next: ${new Date(s.nextRun).toLocaleDateString()} \xB7 Runs: ${s.runCount} \xB7 Total: ${formatUsd15(s.totalInvested)}`)}`);
2813
2814
  }
2814
2815
  printSeparator();
2815
2816
  if (status.pendingRuns.length > 0) {
@@ -2825,7 +2826,7 @@ function registerInvest(program2) {
2825
2826
  autoCmd.command("run").description("Execute pending DCA purchases").option("--key <path>", "Key file path").action(async (opts) => {
2826
2827
  try {
2827
2828
  const pin = await resolvePin();
2828
- const agent = await T200024.create({ pin, keyPath: opts.key });
2829
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2829
2830
  const status = agent.getAutoInvestStatus();
2830
2831
  if (status.pendingRuns.length === 0) {
2831
2832
  if (isJsonMode()) {
@@ -2852,7 +2853,7 @@ function registerInvest(program2) {
2852
2853
  }
2853
2854
  if (result.skipped.length > 0) {
2854
2855
  for (const skip of result.skipped) {
2855
- printLine(` ${pc14.yellow("\u26A0")} Skipped ${skip.scheduleId}: ${skip.reason}`);
2856
+ printLine(` ${pc15.yellow("\u26A0")} Skipped ${skip.scheduleId}: ${skip.reason}`);
2856
2857
  }
2857
2858
  }
2858
2859
  printBlank();
@@ -2863,7 +2864,7 @@ function registerInvest(program2) {
2863
2864
  autoCmd.command("stop <id>").description("Stop an auto-invest schedule").option("--key <path>", "Key file path").action(async (id, opts) => {
2864
2865
  try {
2865
2866
  const pin = await resolvePin();
2866
- const agent = await T200024.create({ pin, keyPath: opts.key });
2867
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2867
2868
  agent.stopAutoInvest(id);
2868
2869
  if (isJsonMode()) {
2869
2870
  printJson({ stopped: id });
@@ -2879,22 +2880,22 @@ function registerInvest(program2) {
2879
2880
  }
2880
2881
 
2881
2882
  // src/commands/portfolio.ts
2882
- import pc15 from "picocolors";
2883
- import { T2000 as T200025, formatUsd as formatUsd16, formatAssetAmount as formatAssetAmount5 } from "@t2000/sdk";
2883
+ import pc16 from "picocolors";
2884
+ import { T2000 as T200026, formatUsd as formatUsd16, formatAssetAmount as formatAssetAmount5 } from "@t2000/sdk";
2884
2885
  function printPositionLine(pos, rewardKeys) {
2885
2886
  if (pos.currentPrice === 0 && pos.totalAmount > 0) {
2886
2887
  printKeyValue(
2887
2888
  pos.asset,
2888
- `${formatAssetAmount5(pos.totalAmount, pos.asset)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${pc15.yellow("unavailable")}`
2889
+ `${formatAssetAmount5(pos.totalAmount, pos.asset)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${pc16.yellow("unavailable")}`
2889
2890
  );
2890
2891
  } else {
2891
- const pnlColor = pos.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2892
+ const pnlColor = pos.unrealizedPnL >= 0 ? pc16.green : pc16.red;
2892
2893
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2893
2894
  let yieldSuffix = "";
2894
2895
  if (pos.earning && pos.earningApy) {
2895
2896
  const hasRewards = rewardKeys?.has(`${pos.earningProtocol}:${pos.asset}`);
2896
- const rewardTag = hasRewards ? ` ${pc15.yellow("+rewards")}` : "";
2897
- yieldSuffix = ` ${pc15.cyan(`${pos.earningApy.toFixed(1)}% APY (${pos.earningProtocol})`)}${rewardTag}`;
2897
+ const rewardTag = hasRewards ? ` ${pc16.yellow("+rewards")}` : "";
2898
+ yieldSuffix = ` ${pc16.cyan(`${pos.earningApy.toFixed(1)}% APY (${pos.earningProtocol})`)}${rewardTag}`;
2898
2899
  }
2899
2900
  printKeyValue(
2900
2901
  pos.asset,
@@ -2906,7 +2907,7 @@ function registerPortfolio(program2) {
2906
2907
  program2.command("portfolio").description("Show investment portfolio").option("--key <path>", "Key file path").action(async (opts) => {
2907
2908
  try {
2908
2909
  const pin = await resolvePin();
2909
- const agent = await T200025.create({ pin, keyPath: opts.key });
2910
+ const agent = await T200026.create({ pin, keyPath: opts.key });
2910
2911
  const portfolio = await agent.getPortfolio();
2911
2912
  if (isJsonMode()) {
2912
2913
  printJson(portfolio);
@@ -2922,7 +2923,7 @@ function registerPortfolio(program2) {
2922
2923
  const hasDirectPositions = portfolio.positions.length > 0;
2923
2924
  const hasStrategyPositions = portfolio.strategyPositions && Object.keys(portfolio.strategyPositions).length > 0;
2924
2925
  if (!hasDirectPositions && !hasStrategyPositions) {
2925
- printInfo("No investments yet. Try: t2000 invest buy 100 SUI");
2926
+ printInfo("No investments yet. Try: t2000 buy 100 SUI");
2926
2927
  printBlank();
2927
2928
  return;
2928
2929
  }
@@ -2935,19 +2936,19 @@ function registerPortfolio(program2) {
2935
2936
  stratLabel = def.name;
2936
2937
  } catch {
2937
2938
  }
2938
- printLine(` ${pc15.bold(pc15.cyan(`\u25B8 ${stratLabel}`))}`);
2939
+ printLine(` ${pc16.bold(pc16.cyan(`\u25B8 ${stratLabel}`))}`);
2939
2940
  printSeparator();
2940
2941
  for (const pos of positions) {
2941
2942
  printPositionLine(pos, rewardKeys);
2942
2943
  }
2943
2944
  const stratValue = positions.reduce((s, p) => s + p.currentValue, 0);
2944
- printLine(` ${pc15.dim(`Subtotal: ${formatUsd16(stratValue)}`)}`);
2945
+ printLine(` ${pc16.dim(`Subtotal: ${formatUsd16(stratValue)}`)}`);
2945
2946
  printBlank();
2946
2947
  }
2947
2948
  }
2948
2949
  if (hasDirectPositions) {
2949
2950
  if (hasStrategyPositions) {
2950
- printLine(` ${pc15.bold(pc15.cyan("\u25B8 Direct"))}`);
2951
+ printLine(` ${pc16.bold(pc16.cyan("\u25B8 Direct"))}`);
2951
2952
  }
2952
2953
  printSeparator();
2953
2954
  for (const pos of portfolio.positions) {
@@ -2955,21 +2956,21 @@ function registerPortfolio(program2) {
2955
2956
  }
2956
2957
  if (hasStrategyPositions) {
2957
2958
  const directValue = portfolio.positions.reduce((s, p) => s + p.currentValue, 0);
2958
- printLine(` ${pc15.dim(`Subtotal: ${formatUsd16(directValue)}`)}`);
2959
+ printLine(` ${pc16.dim(`Subtotal: ${formatUsd16(directValue)}`)}`);
2959
2960
  }
2960
2961
  }
2961
2962
  printSeparator();
2962
2963
  const hasPriceUnavailable = portfolio.positions.some((p) => p.currentPrice === 0 && p.totalAmount > 0);
2963
2964
  if (hasPriceUnavailable) {
2964
- printInfo(pc15.yellow("\u26A0 Price data unavailable for some assets. Values may be inaccurate."));
2965
+ printInfo(pc16.yellow("\u26A0 Price data unavailable for some assets. Values may be inaccurate."));
2965
2966
  }
2966
2967
  printKeyValue("Total invested", formatUsd16(portfolio.totalInvested));
2967
2968
  printKeyValue("Current value", formatUsd16(portfolio.totalValue));
2968
- const upnlColor = portfolio.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2969
+ const upnlColor = portfolio.unrealizedPnL >= 0 ? pc16.green : pc16.red;
2969
2970
  const upnlSign = portfolio.unrealizedPnL >= 0 ? "+" : "";
2970
2971
  printKeyValue("Unrealized P&L", upnlColor(`${upnlSign}${formatUsd16(portfolio.unrealizedPnL)} (${upnlSign}${portfolio.unrealizedPnLPct.toFixed(1)}%)`));
2971
2972
  if (portfolio.realizedPnL !== 0) {
2972
- const rpnlColor = portfolio.realizedPnL >= 0 ? pc15.green : pc15.red;
2973
+ const rpnlColor = portfolio.realizedPnL >= 0 ? pc16.green : pc16.red;
2973
2974
  const rpnlSign = portfolio.realizedPnL >= 0 ? "+" : "";
2974
2975
  printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd16(portfolio.realizedPnL)}`));
2975
2976
  }
@@ -2981,13 +2982,13 @@ function registerPortfolio(program2) {
2981
2982
  }
2982
2983
 
2983
2984
  // src/commands/claimRewards.ts
2984
- import pc16 from "picocolors";
2985
- import { T2000 as T200026, formatUsd as formatUsd17 } from "@t2000/sdk";
2985
+ import pc17 from "picocolors";
2986
+ import { T2000 as T200027, formatUsd as formatUsd17 } from "@t2000/sdk";
2986
2987
  function registerClaimRewards(program2) {
2987
2988
  program2.command("claim-rewards").description("Claim pending protocol rewards").option("--key <path>", "Key file path").action(async (opts) => {
2988
2989
  try {
2989
2990
  const pin = await resolvePin();
2990
- const agent = await T200026.create({ pin, keyPath: opts.key });
2991
+ const agent = await T200027.create({ pin, keyPath: opts.key });
2991
2992
  const result = await agent.claimRewards();
2992
2993
  if (isJsonMode()) {
2993
2994
  printJson(result);
@@ -2995,20 +2996,20 @@ function registerClaimRewards(program2) {
2995
2996
  }
2996
2997
  printBlank();
2997
2998
  if (result.rewards.length === 0) {
2998
- printLine(` ${pc16.dim("No rewards to claim")}`);
2999
+ printLine(` ${pc17.dim("No rewards to claim")}`);
2999
3000
  printBlank();
3000
3001
  return;
3001
3002
  }
3002
3003
  const protocols = [...new Set(result.rewards.map((r) => r.protocol))];
3003
- printLine(` ${pc16.green("\u2713")} Claimed and converted rewards to USDC`);
3004
+ printLine(` ${pc17.green("\u2713")} Claimed and converted rewards to USDC`);
3004
3005
  printSeparator();
3005
3006
  const received = result.usdcReceived;
3006
3007
  if (received >= 0.01) {
3007
- printKeyValue("Received", `${pc16.green(formatUsd17(received))} USDC`);
3008
+ printKeyValue("Received", `${pc17.green(formatUsd17(received))} USDC`);
3008
3009
  } else if (received > 0) {
3009
- printKeyValue("Received", `${pc16.green("< $0.01")} USDC`);
3010
+ printKeyValue("Received", `${pc17.green("< $0.01")} USDC`);
3010
3011
  } else {
3011
- printKeyValue("Received", `${pc16.dim("< $0.01 USDC (rewards are still accruing)")}`);
3012
+ printKeyValue("Received", `${pc17.dim("< $0.01 USDC (rewards are still accruing)")}`);
3012
3013
  }
3013
3014
  printKeyValue("Source", protocols.join(", "));
3014
3015
  if (result.tx) {
@@ -3022,13 +3023,13 @@ function registerClaimRewards(program2) {
3022
3023
  }
3023
3024
 
3024
3025
  // src/commands/gas.ts
3025
- import pc17 from "picocolors";
3026
- import { T2000 as T200027, getGasStatus } from "@t2000/sdk";
3026
+ import pc18 from "picocolors";
3027
+ import { T2000 as T200028, getGasStatus } from "@t2000/sdk";
3027
3028
  function registerGas(program2) {
3028
3029
  program2.command("gas").description("Check gas station status and wallet gas balance").option("--key <path>", "Key file path").action(async (opts) => {
3029
3030
  try {
3030
3031
  const pin = await resolvePin();
3031
- const agent = await T200027.create({ pin, keyPath: opts.key });
3032
+ const agent = await T200028.create({ pin, keyPath: opts.key });
3032
3033
  const address = agent.address();
3033
3034
  const [status, bal] = await Promise.allSettled([
3034
3035
  getGasStatus(address),
@@ -3045,36 +3046,36 @@ function registerGas(program2) {
3045
3046
  }
3046
3047
  printHeader("Gas Status");
3047
3048
  if (gasStatus) {
3048
- const cbStatus = gasStatus.circuitBreaker ? pc17.red("TRIPPED \u2014 sponsorship paused") : pc17.green("OK");
3049
+ const cbStatus = gasStatus.circuitBreaker ? pc18.red("TRIPPED \u2014 sponsorship paused") : pc18.green("OK");
3049
3050
  printKeyValue("Gas Station", cbStatus);
3050
3051
  printKeyValue("SUI Price (TWAP)", `$${gasStatus.suiPrice.toFixed(4)}`);
3051
3052
  if (gasStatus.bootstrapRemaining !== void 0) {
3052
3053
  printKeyValue("Bootstrap", `${gasStatus.bootstrapUsed}/10 used (${gasStatus.bootstrapRemaining} remaining)`);
3053
3054
  }
3054
3055
  } else {
3055
- printKeyValue("Gas Station", pc17.red("unreachable"));
3056
+ printKeyValue("Gas Station", pc18.red("unreachable"));
3056
3057
  const reason = status.status === "rejected" ? status.reason : "unknown";
3057
- printLine(` ${pc17.dim(reason instanceof Error ? reason.message : String(reason))}`);
3058
+ printLine(` ${pc18.dim(reason instanceof Error ? reason.message : String(reason))}`);
3058
3059
  }
3059
3060
  printDivider();
3060
3061
  if (balData) {
3061
3062
  const suiBal = balData.gasReserve.sui;
3062
- const suiColor = suiBal < 0.05 ? pc17.red : pc17.green;
3063
+ const suiColor = suiBal < 0.05 ? pc18.red : pc18.green;
3063
3064
  printKeyValue("SUI (gas)", suiColor(`${suiBal.toFixed(4)} SUI`));
3064
3065
  if (suiBal < 0.05) {
3065
- printLine(` ${pc17.yellow("\u26A0")} Below gas threshold (0.05 SUI) \u2014 transactions will need sponsorship`);
3066
+ printLine(` ${pc18.yellow("\u26A0")} Below gas threshold (0.05 SUI) \u2014 transactions will need sponsorship`);
3066
3067
  }
3067
3068
  printKeyValue("Available", `$${balData.available.toFixed(2)}`);
3068
3069
  } else {
3069
- printKeyValue("Wallet", pc17.dim("could not fetch balances"));
3070
+ printKeyValue("Wallet", pc18.dim("could not fetch balances"));
3070
3071
  }
3071
3072
  printBlank();
3072
3073
  if (gasStatus && !gasStatus.circuitBreaker && (balData?.gasReserve.sui ?? 0) >= 0.05) {
3073
- printLine(` ${pc17.green("\u2713")} Gas is healthy \u2014 transactions should succeed`);
3074
+ printLine(` ${pc18.green("\u2713")} Gas is healthy \u2014 transactions should succeed`);
3074
3075
  } else if (gasStatus && !gasStatus.circuitBreaker) {
3075
- printLine(` ${pc17.yellow("\u26A0")} Low SUI but gas station is online \u2014 sponsorship available`);
3076
+ printLine(` ${pc18.yellow("\u26A0")} Low SUI but gas station is online \u2014 sponsorship available`);
3076
3077
  } else {
3077
- printLine(` ${pc17.red("\u2717")} Gas station issues detected \u2014 fund wallet with SUI directly`);
3078
+ printLine(` ${pc18.red("\u2717")} Gas station issues detected \u2014 fund wallet with SUI directly`);
3078
3079
  printInfo("Send SUI to your address: t2000 address");
3079
3080
  }
3080
3081
  printBlank();
@@ -3092,7 +3093,18 @@ function createProgram() {
3092
3093
  program2.name("t2000").description("A bank account for AI agents").version(`${CLI_VERSION} (beta)`).option("--json", "Output in JSON format").hook("preAction", (thisCommand) => {
3093
3094
  const opts = thisCommand.optsWithGlobals();
3094
3095
  if (opts.json) setJsonMode(true);
3095
- });
3096
+ }).addHelpText("after", `
3097
+ Examples:
3098
+ $ t2000 init Create a new agent bank account
3099
+ $ t2000 balance Show wallet balance
3100
+ $ t2000 save 100 Save $100 to earn yield
3101
+ $ t2000 send 50 to 0xabc... Send $50 USDC
3102
+ $ t2000 borrow 200 Borrow $200 against savings
3103
+ $ t2000 pay openai ... Pay for an API via MPP gateway
3104
+ $ t2000 buy 100 BTC Buy $100 of BTC
3105
+ $ t2000 sell 0.001 BTC Sell BTC for USDC
3106
+ $ t2000 swap 100 USDC SUI Swap between any tokens
3107
+ $ t2000 mcp install Install MCP for AI platforms`);
3096
3108
  registerInit(program2);
3097
3109
  registerSend(program2);
3098
3110
  registerBalance(program2);
@@ -3117,6 +3129,7 @@ function createProgram() {
3117
3129
  registerSentinel(program2);
3118
3130
  registerEarn(program2);
3119
3131
  registerRebalance(program2);
3132
+ registerSwap(program2);
3120
3133
  registerExchange(program2);
3121
3134
  registerMcp(program2);
3122
3135
  registerContacts(program2);