@t2000/cli 0.22.7 → 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,29 +2374,30 @@ 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 });
2397
+ const sym = asset.toUpperCase();
2326
2398
  const usdAmount = isAll ? "all" : parseFloat(amount);
2327
2399
  const result = await agent.investSell({
2328
- asset: asset.toUpperCase(),
2400
+ asset: sym,
2329
2401
  usdAmount,
2330
2402
  maxSlippage: parseFloat(opts.slippage) / 100
2331
2403
  });
@@ -2334,17 +2406,13 @@ function registerInvest(program2) {
2334
2406
  return;
2335
2407
  }
2336
2408
  printBlank();
2337
- const sym = asset.toUpperCase();
2338
2409
  printSuccess(`Sold ${formatAssetAmount4(result.amount, sym)} ${sym} at ${formatUsd15(result.price)}`);
2339
2410
  printKeyValue("Proceeds", formatUsd15(result.usdValue));
2340
2411
  if (result.realizedPnL !== void 0) {
2341
- const pnlColor = result.realizedPnL >= 0 ? pc14.green : pc14.red;
2412
+ const pnlColor = result.realizedPnL >= 0 ? pc15.green : pc15.red;
2342
2413
  const pnlSign = result.realizedPnL >= 0 ? "+" : "";
2343
2414
  printKeyValue("Realized P&L", pnlColor(`${pnlSign}${formatUsd15(result.realizedPnL)}`));
2344
2415
  }
2345
- if (result.position.totalAmount > 0) {
2346
- printKeyValue("Remaining", `${formatAssetAmount4(result.position.totalAmount, sym)} ${sym} (avg ${formatUsd15(result.position.avgPrice)})`);
2347
- }
2348
2416
  printKeyValue("Tx", explorerUrl(result.tx));
2349
2417
  printBlank();
2350
2418
  } catch (error) {
@@ -2354,7 +2422,7 @@ function registerInvest(program2) {
2354
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) => {
2355
2423
  try {
2356
2424
  const pin = await resolvePin();
2357
- const agent = await T200024.create({ pin, keyPath: opts.key });
2425
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2358
2426
  const result = await agent.investEarn({
2359
2427
  asset: asset.toUpperCase(),
2360
2428
  protocol: opts.protocol?.toLowerCase()
@@ -2382,7 +2450,7 @@ function registerInvest(program2) {
2382
2450
  investCmd.command("unearn <asset>").description("Withdraw invested asset from lending (keeps in portfolio)").option("--key <path>", "Key file path").action(async (asset, opts) => {
2383
2451
  try {
2384
2452
  const pin = await resolvePin();
2385
- const agent = await T200024.create({ pin, keyPath: opts.key });
2453
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2386
2454
  const result = await agent.investUnearn({
2387
2455
  asset: asset.toUpperCase()
2388
2456
  });
@@ -2393,7 +2461,7 @@ function registerInvest(program2) {
2393
2461
  printBlank();
2394
2462
  const sym = asset.toUpperCase();
2395
2463
  printSuccess(`Withdrew ${formatAssetAmount4(result.amount, sym)} ${sym} from ${result.protocol}`);
2396
- printKeyValue("Status", `${sym} remains in investment portfolio (locked)`);
2464
+ printKeyValue("Status", `${sym} withdrawn to wallet`);
2397
2465
  printKeyValue("Tx", explorerUrl(result.tx));
2398
2466
  printBlank();
2399
2467
  } catch (error) {
@@ -2403,7 +2471,7 @@ function registerInvest(program2) {
2403
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) => {
2404
2472
  try {
2405
2473
  const pin = await resolvePin();
2406
- const agent = await T200024.create({ pin, keyPath: opts.key });
2474
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2407
2475
  const result = await agent.investRebalance({
2408
2476
  dryRun: opts.dryRun,
2409
2477
  minYieldDiff: opts.minDiff ? parseFloat(opts.minDiff) : void 0
@@ -2458,7 +2526,7 @@ function registerInvest(program2) {
2458
2526
  strategyCmd.command("list").description("List available strategies").option("--key <path>", "Key file path").action(async (opts) => {
2459
2527
  try {
2460
2528
  const pin = await resolvePin();
2461
- const agent = await T200024.create({ pin, keyPath: opts.key });
2529
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2462
2530
  const all = agent.strategies.getAll();
2463
2531
  if (isJsonMode()) {
2464
2532
  printJson(all);
@@ -2469,9 +2537,9 @@ function registerInvest(program2) {
2469
2537
  printSeparator();
2470
2538
  for (const [key, def] of Object.entries(all)) {
2471
2539
  const allocs = Object.entries(def.allocations).map(([a, p]) => `${a} ${p}%`).join(", ");
2472
- const tag = def.custom ? pc14.dim(" (custom)") : "";
2540
+ const tag = def.custom ? pc15.dim(" (custom)") : "";
2473
2541
  printKeyValue(key, `${allocs}${tag}`);
2474
- printLine(` ${pc14.dim(def.description)}`);
2542
+ printLine(` ${pc15.dim(def.description)}`);
2475
2543
  }
2476
2544
  printSeparator();
2477
2545
  const hasPositions = Object.keys(all).some((k) => agent.portfolio.hasStrategyPositions(k));
@@ -2487,12 +2555,12 @@ function registerInvest(program2) {
2487
2555
  try {
2488
2556
  const parsed = parseFloat(amount);
2489
2557
  if (isNaN(parsed) || parsed <= 0) {
2490
- console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2558
+ console.error(pc15.red(" \u2717 Amount must be greater than $0"));
2491
2559
  process.exitCode = 1;
2492
2560
  return;
2493
2561
  }
2494
2562
  const pin = await resolvePin();
2495
- const agent = await T200024.create({ pin, keyPath: opts.key });
2563
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2496
2564
  const result = await agent.investStrategy({ strategy: name.toLowerCase(), usdAmount: parsed, dryRun: opts.dryRun });
2497
2565
  if (isJsonMode()) {
2498
2566
  printJson(result);
@@ -2521,7 +2589,7 @@ function registerInvest(program2) {
2521
2589
  printKeyValue("Tx", explorerUrl(txDigests[0]));
2522
2590
  } else {
2523
2591
  for (const buy of result.buys) {
2524
- printLine(` ${pc14.dim(`${buy.asset}: ${explorerUrl(buy.tx)}`)}`);
2592
+ printLine(` ${pc15.dim(`${buy.asset}: ${explorerUrl(buy.tx)}`)}`);
2525
2593
  }
2526
2594
  }
2527
2595
  }
@@ -2533,7 +2601,7 @@ function registerInvest(program2) {
2533
2601
  strategyCmd.command("sell <name>").description("Sell all positions in a strategy").option("--key <path>", "Key file path").action(async (name, opts) => {
2534
2602
  try {
2535
2603
  const pin = await resolvePin();
2536
- const agent = await T200024.create({ pin, keyPath: opts.key });
2604
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2537
2605
  const result = await agent.sellStrategy({ strategy: name.toLowerCase() });
2538
2606
  if (isJsonMode()) {
2539
2607
  printJson(result);
@@ -2543,18 +2611,18 @@ function registerInvest(program2) {
2543
2611
  printSuccess(`Sold all ${name} strategy positions`);
2544
2612
  printSeparator();
2545
2613
  for (const sell of result.sells) {
2546
- const pnlColor = sell.realizedPnL >= 0 ? pc14.green : pc14.red;
2614
+ const pnlColor = sell.realizedPnL >= 0 ? pc15.green : pc15.red;
2547
2615
  const pnlSign = sell.realizedPnL >= 0 ? "+" : "";
2548
2616
  printKeyValue(sell.asset, `${formatAssetAmount4(sell.amount, sell.asset)} \u2192 ${formatUsd15(sell.usdValue)} ${pnlColor(`${pnlSign}${formatUsd15(sell.realizedPnL)}`)}`);
2549
2617
  }
2550
2618
  if (result.failed && result.failed.length > 0) {
2551
2619
  for (const f of result.failed) {
2552
- console.error(pc14.yellow(` \u26A0 ${f.asset}: ${f.reason}`));
2620
+ console.error(pc15.yellow(` \u26A0 ${f.asset}: ${f.reason}`));
2553
2621
  }
2554
2622
  }
2555
2623
  printSeparator();
2556
2624
  printKeyValue("Total proceeds", formatUsd15(result.totalProceeds));
2557
- const rpnlColor = result.realizedPnL >= 0 ? pc14.green : pc14.red;
2625
+ const rpnlColor = result.realizedPnL >= 0 ? pc15.green : pc15.red;
2558
2626
  const rpnlSign = result.realizedPnL >= 0 ? "+" : "";
2559
2627
  printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd15(result.realizedPnL)}`));
2560
2628
  printBlank();
@@ -2565,7 +2633,7 @@ function registerInvest(program2) {
2565
2633
  strategyCmd.command("status <name>").description("Show current status and weights of a strategy").option("--key <path>", "Key file path").action(async (name, opts) => {
2566
2634
  try {
2567
2635
  const pin = await resolvePin();
2568
- const agent = await T200024.create({ pin, keyPath: opts.key });
2636
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2569
2637
  const status = await agent.getStrategyStatus(name.toLowerCase());
2570
2638
  if (isJsonMode()) {
2571
2639
  printJson(status);
@@ -2581,8 +2649,8 @@ function registerInvest(program2) {
2581
2649
  const target = status.definition.allocations[pos.asset] ?? 0;
2582
2650
  const actual = status.currentWeights[pos.asset] ?? 0;
2583
2651
  const drift = actual - target;
2584
- const driftColor = Math.abs(drift) > 3 ? pc14.yellow : pc14.dim;
2585
- 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;
2586
2654
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2587
2655
  printKeyValue(
2588
2656
  pos.asset,
@@ -2600,7 +2668,7 @@ function registerInvest(program2) {
2600
2668
  strategyCmd.command("rebalance <name>").description("Rebalance a strategy to target weights").option("--key <path>", "Key file path").action(async (name, opts) => {
2601
2669
  try {
2602
2670
  const pin = await resolvePin();
2603
- const agent = await T200024.create({ pin, keyPath: opts.key });
2671
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2604
2672
  const result = await agent.rebalanceStrategy({ strategy: name.toLowerCase() });
2605
2673
  if (isJsonMode()) {
2606
2674
  printJson(result);
@@ -2613,7 +2681,7 @@ function registerInvest(program2) {
2613
2681
  printSuccess(`Rebalanced ${name} strategy`);
2614
2682
  printSeparator();
2615
2683
  for (const t of result.trades) {
2616
- const action = t.action === "buy" ? pc14.green("BUY") : pc14.red("SELL");
2684
+ const action = t.action === "buy" ? pc15.green("BUY") : pc15.red("SELL");
2617
2685
  printKeyValue(t.asset, `${action} ${formatUsd15(t.usdAmount)} (${formatAssetAmount4(t.amount, t.asset)})`);
2618
2686
  }
2619
2687
  printSeparator();
@@ -2630,14 +2698,14 @@ function registerInvest(program2) {
2630
2698
  for (const pair of opts.alloc) {
2631
2699
  const [asset, pctStr] = pair.split(":");
2632
2700
  if (!asset || !pctStr) {
2633
- 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)`));
2634
2702
  process.exitCode = 1;
2635
2703
  return;
2636
2704
  }
2637
2705
  allocations[asset.toUpperCase()] = parseFloat(pctStr);
2638
2706
  }
2639
2707
  const pin = await resolvePin();
2640
- const agent = await T200024.create({ pin });
2708
+ const agent = await T200025.create({ pin });
2641
2709
  const definition = agent.strategies.create({ name, allocations, description: opts.description });
2642
2710
  if (isJsonMode()) {
2643
2711
  printJson(definition);
@@ -2655,9 +2723,9 @@ function registerInvest(program2) {
2655
2723
  strategyCmd.command("delete <name>").description("Delete a custom strategy").option("--key <path>", "Key file path").action(async (name, opts) => {
2656
2724
  try {
2657
2725
  const pin = await resolvePin();
2658
- const agent = await T200024.create({ pin, keyPath: opts.key });
2726
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2659
2727
  if (agent.portfolio.hasStrategyPositions(name.toLowerCase())) {
2660
- 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}`));
2661
2729
  process.exitCode = 1;
2662
2730
  return;
2663
2731
  }
@@ -2678,22 +2746,22 @@ function registerInvest(program2) {
2678
2746
  try {
2679
2747
  const parsed = parseFloat(amount);
2680
2748
  if (isNaN(parsed) || parsed < 1) {
2681
- console.error(pc14.red(" \u2717 Amount must be at least $1"));
2749
+ console.error(pc15.red(" \u2717 Amount must be at least $1"));
2682
2750
  process.exitCode = 1;
2683
2751
  return;
2684
2752
  }
2685
2753
  if (!["daily", "weekly", "monthly"].includes(frequency)) {
2686
- 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"));
2687
2755
  process.exitCode = 1;
2688
2756
  return;
2689
2757
  }
2690
2758
  const pin = await resolvePin();
2691
- const agent = await T200024.create({ pin, keyPath: opts.key });
2759
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2692
2760
  const allStrategies = agent.strategies.getAll();
2693
2761
  const isStrategy = target ? target.toLowerCase() in allStrategies : false;
2694
2762
  const isAsset = target ? target.toUpperCase() in INVESTMENT_ASSETS2 : false;
2695
2763
  if (target && !isStrategy && !isAsset) {
2696
- 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`));
2697
2765
  process.exitCode = 1;
2698
2766
  return;
2699
2767
  }
@@ -2724,7 +2792,7 @@ function registerInvest(program2) {
2724
2792
  autoCmd.command("status").description("Show all DCA schedules").option("--key <path>", "Key file path").action(async (opts) => {
2725
2793
  try {
2726
2794
  const pin = await resolvePin();
2727
- const agent = await T200024.create({ pin, keyPath: opts.key });
2795
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2728
2796
  const status = agent.getAutoInvestStatus();
2729
2797
  if (isJsonMode()) {
2730
2798
  printJson(status);
@@ -2740,9 +2808,9 @@ function registerInvest(program2) {
2740
2808
  printSeparator();
2741
2809
  for (const s of status.schedules) {
2742
2810
  const target = s.strategy ?? s.asset ?? "?";
2743
- const statusTag = s.enabled ? pc14.green("active") : pc14.dim("paused");
2811
+ const statusTag = s.enabled ? pc15.green("active") : pc15.dim("paused");
2744
2812
  printKeyValue(s.id, `${formatUsd15(s.amount)} ${s.frequency} \u2192 ${target} ${statusTag}`);
2745
- 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)}`)}`);
2746
2814
  }
2747
2815
  printSeparator();
2748
2816
  if (status.pendingRuns.length > 0) {
@@ -2758,7 +2826,7 @@ function registerInvest(program2) {
2758
2826
  autoCmd.command("run").description("Execute pending DCA purchases").option("--key <path>", "Key file path").action(async (opts) => {
2759
2827
  try {
2760
2828
  const pin = await resolvePin();
2761
- const agent = await T200024.create({ pin, keyPath: opts.key });
2829
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2762
2830
  const status = agent.getAutoInvestStatus();
2763
2831
  if (status.pendingRuns.length === 0) {
2764
2832
  if (isJsonMode()) {
@@ -2785,7 +2853,7 @@ function registerInvest(program2) {
2785
2853
  }
2786
2854
  if (result.skipped.length > 0) {
2787
2855
  for (const skip of result.skipped) {
2788
- printLine(` ${pc14.yellow("\u26A0")} Skipped ${skip.scheduleId}: ${skip.reason}`);
2856
+ printLine(` ${pc15.yellow("\u26A0")} Skipped ${skip.scheduleId}: ${skip.reason}`);
2789
2857
  }
2790
2858
  }
2791
2859
  printBlank();
@@ -2796,7 +2864,7 @@ function registerInvest(program2) {
2796
2864
  autoCmd.command("stop <id>").description("Stop an auto-invest schedule").option("--key <path>", "Key file path").action(async (id, opts) => {
2797
2865
  try {
2798
2866
  const pin = await resolvePin();
2799
- const agent = await T200024.create({ pin, keyPath: opts.key });
2867
+ const agent = await T200025.create({ pin, keyPath: opts.key });
2800
2868
  agent.stopAutoInvest(id);
2801
2869
  if (isJsonMode()) {
2802
2870
  printJson({ stopped: id });
@@ -2812,22 +2880,22 @@ function registerInvest(program2) {
2812
2880
  }
2813
2881
 
2814
2882
  // src/commands/portfolio.ts
2815
- import pc15 from "picocolors";
2816
- 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";
2817
2885
  function printPositionLine(pos, rewardKeys) {
2818
2886
  if (pos.currentPrice === 0 && pos.totalAmount > 0) {
2819
2887
  printKeyValue(
2820
2888
  pos.asset,
2821
- `${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")}`
2822
2890
  );
2823
2891
  } else {
2824
- const pnlColor = pos.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2892
+ const pnlColor = pos.unrealizedPnL >= 0 ? pc16.green : pc16.red;
2825
2893
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2826
2894
  let yieldSuffix = "";
2827
2895
  if (pos.earning && pos.earningApy) {
2828
2896
  const hasRewards = rewardKeys?.has(`${pos.earningProtocol}:${pos.asset}`);
2829
- const rewardTag = hasRewards ? ` ${pc15.yellow("+rewards")}` : "";
2830
- 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}`;
2831
2899
  }
2832
2900
  printKeyValue(
2833
2901
  pos.asset,
@@ -2839,7 +2907,7 @@ function registerPortfolio(program2) {
2839
2907
  program2.command("portfolio").description("Show investment portfolio").option("--key <path>", "Key file path").action(async (opts) => {
2840
2908
  try {
2841
2909
  const pin = await resolvePin();
2842
- const agent = await T200025.create({ pin, keyPath: opts.key });
2910
+ const agent = await T200026.create({ pin, keyPath: opts.key });
2843
2911
  const portfolio = await agent.getPortfolio();
2844
2912
  if (isJsonMode()) {
2845
2913
  printJson(portfolio);
@@ -2855,7 +2923,7 @@ function registerPortfolio(program2) {
2855
2923
  const hasDirectPositions = portfolio.positions.length > 0;
2856
2924
  const hasStrategyPositions = portfolio.strategyPositions && Object.keys(portfolio.strategyPositions).length > 0;
2857
2925
  if (!hasDirectPositions && !hasStrategyPositions) {
2858
- printInfo("No investments yet. Try: t2000 invest buy 100 SUI");
2926
+ printInfo("No investments yet. Try: t2000 buy 100 SUI");
2859
2927
  printBlank();
2860
2928
  return;
2861
2929
  }
@@ -2868,19 +2936,19 @@ function registerPortfolio(program2) {
2868
2936
  stratLabel = def.name;
2869
2937
  } catch {
2870
2938
  }
2871
- printLine(` ${pc15.bold(pc15.cyan(`\u25B8 ${stratLabel}`))}`);
2939
+ printLine(` ${pc16.bold(pc16.cyan(`\u25B8 ${stratLabel}`))}`);
2872
2940
  printSeparator();
2873
2941
  for (const pos of positions) {
2874
2942
  printPositionLine(pos, rewardKeys);
2875
2943
  }
2876
2944
  const stratValue = positions.reduce((s, p) => s + p.currentValue, 0);
2877
- printLine(` ${pc15.dim(`Subtotal: ${formatUsd16(stratValue)}`)}`);
2945
+ printLine(` ${pc16.dim(`Subtotal: ${formatUsd16(stratValue)}`)}`);
2878
2946
  printBlank();
2879
2947
  }
2880
2948
  }
2881
2949
  if (hasDirectPositions) {
2882
2950
  if (hasStrategyPositions) {
2883
- printLine(` ${pc15.bold(pc15.cyan("\u25B8 Direct"))}`);
2951
+ printLine(` ${pc16.bold(pc16.cyan("\u25B8 Direct"))}`);
2884
2952
  }
2885
2953
  printSeparator();
2886
2954
  for (const pos of portfolio.positions) {
@@ -2888,21 +2956,21 @@ function registerPortfolio(program2) {
2888
2956
  }
2889
2957
  if (hasStrategyPositions) {
2890
2958
  const directValue = portfolio.positions.reduce((s, p) => s + p.currentValue, 0);
2891
- printLine(` ${pc15.dim(`Subtotal: ${formatUsd16(directValue)}`)}`);
2959
+ printLine(` ${pc16.dim(`Subtotal: ${formatUsd16(directValue)}`)}`);
2892
2960
  }
2893
2961
  }
2894
2962
  printSeparator();
2895
2963
  const hasPriceUnavailable = portfolio.positions.some((p) => p.currentPrice === 0 && p.totalAmount > 0);
2896
2964
  if (hasPriceUnavailable) {
2897
- 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."));
2898
2966
  }
2899
2967
  printKeyValue("Total invested", formatUsd16(portfolio.totalInvested));
2900
2968
  printKeyValue("Current value", formatUsd16(portfolio.totalValue));
2901
- const upnlColor = portfolio.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2969
+ const upnlColor = portfolio.unrealizedPnL >= 0 ? pc16.green : pc16.red;
2902
2970
  const upnlSign = portfolio.unrealizedPnL >= 0 ? "+" : "";
2903
2971
  printKeyValue("Unrealized P&L", upnlColor(`${upnlSign}${formatUsd16(portfolio.unrealizedPnL)} (${upnlSign}${portfolio.unrealizedPnLPct.toFixed(1)}%)`));
2904
2972
  if (portfolio.realizedPnL !== 0) {
2905
- const rpnlColor = portfolio.realizedPnL >= 0 ? pc15.green : pc15.red;
2973
+ const rpnlColor = portfolio.realizedPnL >= 0 ? pc16.green : pc16.red;
2906
2974
  const rpnlSign = portfolio.realizedPnL >= 0 ? "+" : "";
2907
2975
  printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd16(portfolio.realizedPnL)}`));
2908
2976
  }
@@ -2914,13 +2982,13 @@ function registerPortfolio(program2) {
2914
2982
  }
2915
2983
 
2916
2984
  // src/commands/claimRewards.ts
2917
- import pc16 from "picocolors";
2918
- 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";
2919
2987
  function registerClaimRewards(program2) {
2920
2988
  program2.command("claim-rewards").description("Claim pending protocol rewards").option("--key <path>", "Key file path").action(async (opts) => {
2921
2989
  try {
2922
2990
  const pin = await resolvePin();
2923
- const agent = await T200026.create({ pin, keyPath: opts.key });
2991
+ const agent = await T200027.create({ pin, keyPath: opts.key });
2924
2992
  const result = await agent.claimRewards();
2925
2993
  if (isJsonMode()) {
2926
2994
  printJson(result);
@@ -2928,20 +2996,20 @@ function registerClaimRewards(program2) {
2928
2996
  }
2929
2997
  printBlank();
2930
2998
  if (result.rewards.length === 0) {
2931
- printLine(` ${pc16.dim("No rewards to claim")}`);
2999
+ printLine(` ${pc17.dim("No rewards to claim")}`);
2932
3000
  printBlank();
2933
3001
  return;
2934
3002
  }
2935
3003
  const protocols = [...new Set(result.rewards.map((r) => r.protocol))];
2936
- printLine(` ${pc16.green("\u2713")} Claimed and converted rewards to USDC`);
3004
+ printLine(` ${pc17.green("\u2713")} Claimed and converted rewards to USDC`);
2937
3005
  printSeparator();
2938
3006
  const received = result.usdcReceived;
2939
3007
  if (received >= 0.01) {
2940
- printKeyValue("Received", `${pc16.green(formatUsd17(received))} USDC`);
3008
+ printKeyValue("Received", `${pc17.green(formatUsd17(received))} USDC`);
2941
3009
  } else if (received > 0) {
2942
- printKeyValue("Received", `${pc16.green("< $0.01")} USDC`);
3010
+ printKeyValue("Received", `${pc17.green("< $0.01")} USDC`);
2943
3011
  } else {
2944
- printKeyValue("Received", `${pc16.dim("< $0.01 USDC (rewards are still accruing)")}`);
3012
+ printKeyValue("Received", `${pc17.dim("< $0.01 USDC (rewards are still accruing)")}`);
2945
3013
  }
2946
3014
  printKeyValue("Source", protocols.join(", "));
2947
3015
  if (result.tx) {
@@ -2955,13 +3023,13 @@ function registerClaimRewards(program2) {
2955
3023
  }
2956
3024
 
2957
3025
  // src/commands/gas.ts
2958
- import pc17 from "picocolors";
2959
- import { T2000 as T200027, getGasStatus } from "@t2000/sdk";
3026
+ import pc18 from "picocolors";
3027
+ import { T2000 as T200028, getGasStatus } from "@t2000/sdk";
2960
3028
  function registerGas(program2) {
2961
3029
  program2.command("gas").description("Check gas station status and wallet gas balance").option("--key <path>", "Key file path").action(async (opts) => {
2962
3030
  try {
2963
3031
  const pin = await resolvePin();
2964
- const agent = await T200027.create({ pin, keyPath: opts.key });
3032
+ const agent = await T200028.create({ pin, keyPath: opts.key });
2965
3033
  const address = agent.address();
2966
3034
  const [status, bal] = await Promise.allSettled([
2967
3035
  getGasStatus(address),
@@ -2978,36 +3046,36 @@ function registerGas(program2) {
2978
3046
  }
2979
3047
  printHeader("Gas Status");
2980
3048
  if (gasStatus) {
2981
- 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");
2982
3050
  printKeyValue("Gas Station", cbStatus);
2983
3051
  printKeyValue("SUI Price (TWAP)", `$${gasStatus.suiPrice.toFixed(4)}`);
2984
3052
  if (gasStatus.bootstrapRemaining !== void 0) {
2985
3053
  printKeyValue("Bootstrap", `${gasStatus.bootstrapUsed}/10 used (${gasStatus.bootstrapRemaining} remaining)`);
2986
3054
  }
2987
3055
  } else {
2988
- printKeyValue("Gas Station", pc17.red("unreachable"));
3056
+ printKeyValue("Gas Station", pc18.red("unreachable"));
2989
3057
  const reason = status.status === "rejected" ? status.reason : "unknown";
2990
- printLine(` ${pc17.dim(reason instanceof Error ? reason.message : String(reason))}`);
3058
+ printLine(` ${pc18.dim(reason instanceof Error ? reason.message : String(reason))}`);
2991
3059
  }
2992
3060
  printDivider();
2993
3061
  if (balData) {
2994
3062
  const suiBal = balData.gasReserve.sui;
2995
- const suiColor = suiBal < 0.05 ? pc17.red : pc17.green;
3063
+ const suiColor = suiBal < 0.05 ? pc18.red : pc18.green;
2996
3064
  printKeyValue("SUI (gas)", suiColor(`${suiBal.toFixed(4)} SUI`));
2997
3065
  if (suiBal < 0.05) {
2998
- 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`);
2999
3067
  }
3000
3068
  printKeyValue("Available", `$${balData.available.toFixed(2)}`);
3001
3069
  } else {
3002
- printKeyValue("Wallet", pc17.dim("could not fetch balances"));
3070
+ printKeyValue("Wallet", pc18.dim("could not fetch balances"));
3003
3071
  }
3004
3072
  printBlank();
3005
3073
  if (gasStatus && !gasStatus.circuitBreaker && (balData?.gasReserve.sui ?? 0) >= 0.05) {
3006
- printLine(` ${pc17.green("\u2713")} Gas is healthy \u2014 transactions should succeed`);
3074
+ printLine(` ${pc18.green("\u2713")} Gas is healthy \u2014 transactions should succeed`);
3007
3075
  } else if (gasStatus && !gasStatus.circuitBreaker) {
3008
- 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`);
3009
3077
  } else {
3010
- 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`);
3011
3079
  printInfo("Send SUI to your address: t2000 address");
3012
3080
  }
3013
3081
  printBlank();
@@ -3025,7 +3093,18 @@ function createProgram() {
3025
3093
  program2.name("t2000").description("A bank account for AI agents").version(`${CLI_VERSION} (beta)`).option("--json", "Output in JSON format").hook("preAction", (thisCommand) => {
3026
3094
  const opts = thisCommand.optsWithGlobals();
3027
3095
  if (opts.json) setJsonMode(true);
3028
- });
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`);
3029
3108
  registerInit(program2);
3030
3109
  registerSend(program2);
3031
3110
  registerBalance(program2);
@@ -3050,6 +3129,7 @@ function createProgram() {
3050
3129
  registerSentinel(program2);
3051
3130
  registerEarn(program2);
3052
3131
  registerRebalance(program2);
3132
+ registerSwap(program2);
3053
3133
  registerExchange(program2);
3054
3134
  registerMcp(program2);
3055
3135
  registerContacts(program2);