@t2000/cli 5.3.0 → 5.4.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
@@ -22105,7 +22105,7 @@ var {
22105
22105
  } = import_index.default;
22106
22106
 
22107
22107
  // src/program.ts
22108
- import { createRequire } from "module";
22108
+ import { createRequire as createRequire2 } from "module";
22109
22109
 
22110
22110
  // src/output.ts
22111
22111
  var import_picocolors = __toESM(require_picocolors(), 1);
@@ -26711,6 +26711,7 @@ __export(token_registry_exports, {
26711
26711
  getCoinMeta: () => getCoinMeta,
26712
26712
  getDecimalsForCoinType: () => getDecimalsForCoinType,
26713
26713
  isInRegistry: () => isInRegistry,
26714
+ resolveCoinDecimals: () => resolveCoinDecimals,
26714
26715
  resolveSymbol: () => resolveSymbol,
26715
26716
  resolveTokenType: () => resolveTokenType
26716
26717
  });
@@ -26732,6 +26733,16 @@ function getDecimalsForCoinType(coinType) {
26732
26733
  }
26733
26734
  return 9;
26734
26735
  }
26736
+ async function resolveCoinDecimals(client, coinType) {
26737
+ if (isInRegistry(coinType)) return getDecimalsForCoinType(coinType);
26738
+ try {
26739
+ const res = await client.core.getCoinMetadata({ coinType });
26740
+ const d = res?.metadata?.decimals ?? res?.decimals;
26741
+ if (typeof d === "number" && Number.isFinite(d)) return d;
26742
+ } catch {
26743
+ }
26744
+ return getDecimalsForCoinType(coinType);
26745
+ }
26735
26746
  function resolveSymbol(coinType) {
26736
26747
  const direct = BY_TYPE.get(coinType);
26737
26748
  if (direct) return direct.symbol;
@@ -27236,7 +27247,7 @@ async function getSwapQuote(params) {
27236
27247
  );
27237
27248
  }
27238
27249
  const byAmountIn = params.byAmountIn ?? true;
27239
- const fromDecimals = getDecimalsForCoinType(fromType);
27250
+ const fromDecimals = params.fromDecimals ?? getDecimalsForCoinType(fromType);
27240
27251
  const rawAmount = BigInt(Math.floor(params.amount * 10 ** fromDecimals));
27241
27252
  const route = await findSwapRoute2({
27242
27253
  walletAddress: params.walletAddress,
@@ -27250,7 +27261,7 @@ async function getSwapQuote(params) {
27250
27261
  if (route.insufficientLiquidity) {
27251
27262
  throw new T2000Error("SWAP_FAILED", `Insufficient liquidity for ${params.from} -> ${params.to}.`);
27252
27263
  }
27253
- const toDecimals = getDecimalsForCoinType(toType);
27264
+ const toDecimals = params.toDecimals ?? getDecimalsForCoinType(toType);
27254
27265
  const fromAmount = Number(route.amountIn) / 10 ** fromDecimals;
27255
27266
  const toAmount = Number(route.amountOut) / 10 ** toDecimals;
27256
27267
  const routeDesc = route.routerData.paths?.map((p) => p.provider).filter(Boolean).slice(0, 3).join(" + ") ?? "Cetus Aggregator";
@@ -28435,7 +28446,7 @@ var T2000 = class _T2000 extends import_index2.default {
28435
28446
  if (!toType) throw new T2000Error("ASSET_NOT_SUPPORTED", `Unknown token: ${params.to}. Provide the full coin type.`);
28436
28447
  const byAmountIn = params.byAmountIn ?? true;
28437
28448
  const slippage = Math.min(params.slippage ?? 0.01, 0.05);
28438
- const fromDecimals = getDecimalsForCoinType(fromType);
28449
+ const fromDecimals = await resolveCoinDecimals(this.client, fromType);
28439
28450
  const rawAmount = BigInt(Math.floor(params.amount * 10 ** fromDecimals));
28440
28451
  const route = await findSwapRoute2({
28441
28452
  walletAddress: this._address,
@@ -28449,7 +28460,7 @@ var T2000 = class _T2000 extends import_index2.default {
28449
28460
  if (route.priceImpact > 0.05) {
28450
28461
  console.warn(`[swap] High price impact: ${(route.priceImpact * 100).toFixed(2)}%`);
28451
28462
  }
28452
- const toDecimals = getDecimalsForCoinType(toType);
28463
+ const toDecimals = await resolveCoinDecimals(this.client, toType);
28453
28464
  let preBalRaw = 0n;
28454
28465
  try {
28455
28466
  const preBal = await this.client.core.getBalance({ owner: this._address, coinType: toType });
@@ -28542,13 +28553,18 @@ var T2000 = class _T2000 extends import_index2.default {
28542
28553
  */
28543
28554
  async swapQuote(params) {
28544
28555
  const { getSwapQuote: getSwapQuote2 } = await Promise.resolve().then(() => (init_swap_quote(), swap_quote_exports));
28556
+ const { resolveTokenType: resolveTokenType2 } = await Promise.resolve().then(() => (init_cetus_swap(), cetus_swap_exports));
28557
+ const fromType = resolveTokenType2(params.from);
28558
+ const toType = resolveTokenType2(params.to);
28545
28559
  return getSwapQuote2({
28546
28560
  walletAddress: this._address,
28547
28561
  from: params.from,
28548
28562
  to: params.to,
28549
28563
  amount: params.amount,
28550
28564
  byAmountIn: params.byAmountIn,
28551
- providers: params.providers
28565
+ providers: params.providers,
28566
+ fromDecimals: fromType ? await resolveCoinDecimals(this.client, fromType) : void 0,
28567
+ toDecimals: toType ? await resolveCoinDecimals(this.client, toType) : void 0
28552
28568
  });
28553
28569
  }
28554
28570
  // -- Wallet --
@@ -28684,8 +28700,8 @@ var T2000 = class _T2000 extends import_index2.default {
28684
28700
  /**
28685
28701
  * [SPEC_AGENTIC_STACK P1 / SDK F2 — 2026-05-25; refreshed S.342 / 2026-05-26]
28686
28702
  * Preferred alias of `deposit()`. Was introduced to mirror the v3 `t2000 fund`
28687
- * CLI command; the v4 CLI surface is `t2 receive` (deleted `fund` in the
28688
- * S.332 bulk cut). `deposit()` stays as the canonical method name for
28703
+ * CLI command; the v4 CLI surface is `t2 fund` (renamed back from the
28704
+ * interim `t2 receive` in S.464). `deposit()` stays as the canonical method name for
28689
28705
  * back-compat; `fund()` stays as a programmatic alias for audric + other
28690
28706
  * SDK consumers that prefer the verb.
28691
28707
  */
@@ -31234,6 +31250,17 @@ async function withAgent(options = {}) {
31234
31250
  rpcUrl: options.rpcUrl
31235
31251
  });
31236
31252
  }
31253
+ async function tryWithAgent(options = {}) {
31254
+ try {
31255
+ const agent = await T2000.create({
31256
+ keyPath: options.keyPath,
31257
+ rpcUrl: options.rpcUrl
31258
+ });
31259
+ return { kind: "ok", agent };
31260
+ } catch (error) {
31261
+ return { kind: "error", error };
31262
+ }
31263
+ }
31237
31264
 
31238
31265
  // src/commands/export.ts
31239
31266
  function registerExport(program3) {
@@ -31265,16 +31292,17 @@ function registerExport(program3) {
31265
31292
  });
31266
31293
  }
31267
31294
 
31268
- // src/commands/receive.ts
31295
+ // src/commands/fund.ts
31269
31296
  var import_qrcode = __toESM(require_lib4(), 1);
31270
31297
  var import_picocolors2 = __toESM(require_picocolors(), 1);
31271
- function registerReceive(program3) {
31272
- program3.command("receive").description("Print your wallet address + QR code for incoming transfers").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--qr-only", "Print only the QR code (no address text)").action(async (opts) => {
31298
+ var VALUE_PROMISE = "$5 USDC \u2248 ~250 paid API calls (at the $0.02 floor).";
31299
+ function registerFund(program3) {
31300
+ program3.command("fund").description("Show your wallet address + QR to fund it (USDC / USDsui / SUI on Sui)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--qr-only", "Print only the QR code (no address text)").action(async (opts) => {
31273
31301
  try {
31274
31302
  const agent = await withAgent({ keyPath: opts.key });
31275
31303
  const address = agent.address();
31276
31304
  if (isJsonMode()) {
31277
- printJson({ address, qrEncodedFor: address });
31305
+ printJson({ address, qrEncodedFor: address, valuePromise: VALUE_PROMISE });
31278
31306
  return;
31279
31307
  }
31280
31308
  printBlank();
@@ -31282,6 +31310,7 @@ function registerReceive(program3) {
31282
31310
  printKeyValue("Address", address);
31283
31311
  printBlank();
31284
31312
  printLine(import_picocolors2.default.dim("Accepts USDC, USDsui, or SUI on Sui mainnet."));
31313
+ printLine(import_picocolors2.default.dim(VALUE_PROMISE));
31285
31314
  printLine(import_picocolors2.default.dim("Scan to send to this wallet:"));
31286
31315
  printBlank();
31287
31316
  }
@@ -31432,8 +31461,171 @@ function registerHistory(program3) {
31432
31461
  });
31433
31462
  }
31434
31463
 
31435
- // src/commands/send.ts
31464
+ // src/commands/status.ts
31436
31465
  var import_picocolors5 = __toESM(require_picocolors(), 1);
31466
+ import { createRequire } from "module";
31467
+
31468
+ // src/commands/mcp/platforms.ts
31469
+ import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
31470
+ import { join as join3, dirname as dirname2 } from "path";
31471
+ import { homedir as homedir2 } from "os";
31472
+ import { existsSync as existsSync2 } from "fs";
31473
+ var MCP_SERVER_ENTRY = {
31474
+ command: "t2000",
31475
+ args: ["mcp", "start"]
31476
+ };
31477
+ var MCP_SERVER_KEY = "t2000";
31478
+ function getPlatformConfigs() {
31479
+ const home = homedir2();
31480
+ return [
31481
+ {
31482
+ name: "Claude Desktop",
31483
+ slug: "claude-desktop",
31484
+ path: join3(home, "Library", "Application Support", "Claude", "claude_desktop_config.json")
31485
+ },
31486
+ {
31487
+ name: "Cursor",
31488
+ slug: "cursor",
31489
+ path: join3(home, ".cursor", "mcp.json")
31490
+ },
31491
+ {
31492
+ name: "Windsurf",
31493
+ slug: "windsurf",
31494
+ path: join3(home, ".codeium", "windsurf", "mcp_config.json")
31495
+ }
31496
+ ];
31497
+ }
31498
+ async function readJsonFile(path2) {
31499
+ try {
31500
+ const content = await readFile2(path2, "utf-8");
31501
+ return JSON.parse(content);
31502
+ } catch {
31503
+ return {};
31504
+ }
31505
+ }
31506
+ async function writeJsonFile(path2, data) {
31507
+ const dir = dirname2(path2);
31508
+ if (!existsSync2(dir)) {
31509
+ await mkdir2(dir, { recursive: true });
31510
+ }
31511
+ await writeFile2(path2, JSON.stringify(data, null, 2) + "\n", "utf-8");
31512
+ }
31513
+ function withMcpEntry(config) {
31514
+ return {
31515
+ ...config,
31516
+ mcpServers: {
31517
+ ...config.mcpServers ?? {},
31518
+ [MCP_SERVER_KEY]: { ...MCP_SERVER_ENTRY }
31519
+ }
31520
+ };
31521
+ }
31522
+ function hasMcpEntry(config) {
31523
+ return typeof config.mcpServers === "object" && config.mcpServers !== null && MCP_SERVER_KEY in config.mcpServers;
31524
+ }
31525
+ function withoutMcpEntry(config) {
31526
+ if (!hasMcpEntry(config)) return config;
31527
+ const servers = { ...config.mcpServers };
31528
+ delete servers[MCP_SERVER_KEY];
31529
+ return { ...config, mcpServers: servers };
31530
+ }
31531
+
31532
+ // src/commands/status.ts
31533
+ var require2 = createRequire(import.meta.url);
31534
+ var { version: CLI_VERSION } = require2("../package.json");
31535
+ var GATEWAY_URL = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
31536
+ var GATEWAY_TIMEOUT_MS = 3e3;
31537
+ async function checkGateway() {
31538
+ const start = Date.now();
31539
+ try {
31540
+ const controller = new AbortController();
31541
+ const timer = setTimeout(() => controller.abort(), GATEWAY_TIMEOUT_MS);
31542
+ const res = await fetch(`${GATEWAY_URL}/api/services`, { signal: controller.signal });
31543
+ clearTimeout(timer);
31544
+ return { url: GATEWAY_URL, reachable: res.ok, latencyMs: Date.now() - start };
31545
+ } catch {
31546
+ return { url: GATEWAY_URL, reachable: false, latencyMs: null };
31547
+ }
31548
+ }
31549
+ async function checkMcpClients() {
31550
+ const platforms = getPlatformConfigs();
31551
+ return Promise.all(
31552
+ platforms.map(async (p) => ({ name: p.name, wired: hasMcpEntry(await readJsonFile(p.path)) }))
31553
+ );
31554
+ }
31555
+ function registerStatus(program3) {
31556
+ program3.command("status").description("Health check: wallet, balances, limits, MCP wiring, gateway reachability").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
31557
+ try {
31558
+ const [agentResult, gateway, mcpClients] = await Promise.all([
31559
+ tryWithAgent({ keyPath: opts.key }),
31560
+ checkGateway(),
31561
+ checkMcpClients()
31562
+ ]);
31563
+ let wallet = { created: false };
31564
+ let balance = null;
31565
+ let limits = null;
31566
+ if (agentResult.kind === "ok") {
31567
+ const agent = agentResult.agent;
31568
+ wallet = { created: true, address: agent.address() };
31569
+ try {
31570
+ const b = await agent.balance();
31571
+ balance = { totalUsd: b.totalUsd, stables: b.stables, sui: b.sui.amount };
31572
+ } catch {
31573
+ balance = null;
31574
+ }
31575
+ const lim = agent.limits.getLimits();
31576
+ limits = {
31577
+ perTxUsd: lim?.perTxUsd,
31578
+ dailyUsd: lim?.dailyUsd,
31579
+ spentTodayUsd: agent.limits.dailySpentToday()
31580
+ };
31581
+ }
31582
+ if (isJsonMode()) {
31583
+ printJson({ cliVersion: CLI_VERSION, wallet, balance, limits, gateway, mcpClients });
31584
+ return;
31585
+ }
31586
+ printBlank();
31587
+ printLine(import_picocolors5.default.bold("t2000 Agent Wallet \u2014 status"));
31588
+ printBlank();
31589
+ printKeyValue("CLI version", CLI_VERSION);
31590
+ if (wallet.created && wallet.address) {
31591
+ const short = `${wallet.address.slice(0, 6)}\u2026${wallet.address.slice(-4)}`;
31592
+ printKeyValue("Wallet", `${short} ${import_picocolors5.default.green("\u2713")}`);
31593
+ if (balance) {
31594
+ const parts = Object.entries(balance.stables).map(([k, v]) => `${k} ${v}`).concat(`SUI ${balance.sui}`).join(", ");
31595
+ printKeyValue("Balance", `$${balance.totalUsd.toFixed(2)} ${import_picocolors5.default.dim(`(${parts})`)}`);
31596
+ } else {
31597
+ printKeyValue("Balance", import_picocolors5.default.dim("(could not read \u2014 network?)"));
31598
+ }
31599
+ if (limits && (limits.perTxUsd !== void 0 || limits.dailyUsd !== void 0)) {
31600
+ const caps = [
31601
+ limits.perTxUsd !== void 0 ? `$${limits.perTxUsd}/tx` : null,
31602
+ limits.dailyUsd !== void 0 ? `$${limits.dailyUsd}/day` : null
31603
+ ].filter(Boolean).join(" \xB7 ");
31604
+ printKeyValue("Limits", `${caps} ${import_picocolors5.default.dim(`(spent today: $${limits.spentTodayUsd.toFixed(2)})`)}`);
31605
+ } else {
31606
+ printKeyValue("Limits", import_picocolors5.default.dim("off (no caps set)"));
31607
+ }
31608
+ } else {
31609
+ printKeyValue("Wallet", `${import_picocolors5.default.yellow("not created")} ${import_picocolors5.default.dim("\u2014 run `t2 init`")}`);
31610
+ }
31611
+ printKeyValue(
31612
+ "Gateway",
31613
+ gateway.reachable ? `${import_picocolors5.default.green("\u2713 reachable")} ${import_picocolors5.default.dim(`(${gateway.latencyMs}ms)`)}` : `${import_picocolors5.default.red("\u2717 unreachable")} ${import_picocolors5.default.dim(`(${gateway.url})`)}`
31614
+ );
31615
+ const mcpSummary = mcpClients.map((c) => `${c.name} ${c.wired ? import_picocolors5.default.green("\u2713") : import_picocolors5.default.dim("\u2717")}`).join(" \xB7 ");
31616
+ printKeyValue("MCP wired", mcpSummary);
31617
+ if (!mcpClients.some((c) => c.wired)) {
31618
+ printLine(import_picocolors5.default.dim(" Run `t2 mcp install` to connect Claude / Cursor / Windsurf."));
31619
+ }
31620
+ printBlank();
31621
+ } catch (err) {
31622
+ handleError(err);
31623
+ }
31624
+ });
31625
+ }
31626
+
31627
+ // src/commands/send.ts
31628
+ var import_picocolors6 = __toESM(require_picocolors(), 1);
31437
31629
  var ACCEPTED_ASSETS = ["USDC", "USDsui", "SUI"];
31438
31630
  var ACCEPTED_ASSETS_LIST = ACCEPTED_ASSETS.join(", ");
31439
31631
  function parseSendArgs(args) {
@@ -31478,7 +31670,7 @@ function registerSend(program3) {
31478
31670
  program3.command("send").argument("<amount>", "Amount of <asset> to send (denominated in asset units, NOT USD)").argument(
31479
31671
  "[args...]",
31480
31672
  'Asset (USDC | USDsui | SUI), optional "to" keyword, and recipient (0x address, SuiNS name like alice.sui, or @audric handle)'
31481
- ).description("Send USDC, USDsui, or SUI. USDC + USDsui are gasless (no SUI required).").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--force", "Override opt-in spending limits (see `t2 limit`)").addHelpText(
31673
+ ).description("Send USDC, USDsui, or SUI. USDC + USDsui are gasless (no SUI required).").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--force", "Override spending limits for this call (see `t2 limit`)").addHelpText(
31482
31674
  "after",
31483
31675
  `
31484
31676
  Examples:
@@ -31507,12 +31699,12 @@ Examples:
31507
31699
  });
31508
31700
  return;
31509
31701
  }
31510
- const displayTo = result.suinsName ? `${result.suinsName} ${import_picocolors5.default.dim(`(${truncateAddress(result.to)})`)}` : truncateAddress(result.to);
31702
+ const displayTo = result.suinsName ? `${result.suinsName} ${import_picocolors6.default.dim(`(${truncateAddress(result.to)})`)}` : truncateAddress(result.to);
31511
31703
  const amountDisplay = asset === "SUI" ? `${result.amount.toFixed(4)} SUI` : `${formatUsd(result.amount)} ${asset}`;
31512
31704
  printBlank();
31513
31705
  printSuccess(`Sent ${amountDisplay} \u2192 ${displayTo}`);
31514
31706
  if (result.gasCost === 0) {
31515
- printKeyValue("Gas", import_picocolors5.default.green("gasless \u26A1"));
31707
+ printKeyValue("Gas", import_picocolors6.default.green("gasless \u26A1"));
31516
31708
  } else {
31517
31709
  printKeyValue("Gas", `${result.gasCost.toFixed(6)} ${result.gasCostUnit}`);
31518
31710
  }
@@ -31525,7 +31717,7 @@ Examples:
31525
31717
  }
31526
31718
 
31527
31719
  // src/commands/swap.ts
31528
- var import_picocolors6 = __toESM(require_picocolors(), 1);
31720
+ var import_picocolors7 = __toESM(require_picocolors(), 1);
31529
31721
  function parseSwapArgs(amountStr, from, to) {
31530
31722
  const amount = parseFloat(amountStr);
31531
31723
  if (Number.isNaN(amount) || amount <= 0) {
@@ -31539,7 +31731,7 @@ function parseSwapArgs(amountStr, from, to) {
31539
31731
  return { amount, from, to };
31540
31732
  }
31541
31733
  function registerSwap(program3) {
31542
- program3.command("swap").argument("<amount>", "Amount of <from> to swap (denominated in <from> units)").argument("<from>", "Source token symbol (e.g. USDC, SUI, USDsui)").argument("<to>", "Destination token symbol (e.g. SUI, USDC, USDsui)").description("Swap tokens via Cetus aggregator (20+ DEXs)").option("--quote", "Preview the swap (price, route, impact) without executing").option("--slippage <pct>", "Max slippage percentage (default: 1)", "1").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--force", "Override opt-in spending limits (see `t2 limit`)").addHelpText(
31734
+ program3.command("swap").argument("<amount>", "Amount of <from> to swap (denominated in <from> units)").argument("<from>", "Source token \u2014 symbol (USDC, SUI, \u2026) or full coin type (0x\u2026::mod::TOK)").argument("<to>", "Destination token \u2014 symbol (SUI, USDC, \u2026) or full coin type (0x\u2026::mod::TOK)").description("Swap any token pair via Cetus aggregator (20+ DEXs). Unknown coin types resolve decimals on-chain.").option("--quote", "Preview the swap (price, route, impact) without executing").option("--slippage <pct>", "Max slippage percentage (default: 1)", "1").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--force", "Override spending limits for this call (see `t2 limit`)").addHelpText(
31543
31735
  "after",
31544
31736
  `
31545
31737
  Examples:
@@ -31565,9 +31757,9 @@ Examples:
31565
31757
  }
31566
31758
  printBlank();
31567
31759
  printKeyValue("Input", `${quote.fromAmount} ${quote.fromToken}`);
31568
- printKeyValue("Output", import_picocolors6.default.green(`${quote.toAmount.toFixed(6)} ${quote.toToken}`));
31760
+ printKeyValue("Output", import_picocolors7.default.green(`${quote.toAmount.toFixed(6)} ${quote.toToken}`));
31569
31761
  if (quote.priceImpact > 1e-3) {
31570
- printKeyValue("Price impact", import_picocolors6.default.yellow(`${(quote.priceImpact * 100).toFixed(2)}%`));
31762
+ printKeyValue("Price impact", import_picocolors7.default.yellow(`${(quote.priceImpact * 100).toFixed(2)}%`));
31571
31763
  }
31572
31764
  printKeyValue("Route", `${quote.fromToken} \u2192 ${quote.toToken} (${quote.route})`);
31573
31765
  printBlank();
@@ -31587,10 +31779,10 @@ Examples:
31587
31779
  }
31588
31780
  printBlank();
31589
31781
  printSuccess(
31590
- `Swapped ${import_picocolors6.default.yellow(String(result.fromAmount))} ${result.fromToken} \u2192 ${import_picocolors6.default.green(result.toAmount.toFixed(6))} ${result.toToken}`
31782
+ `Swapped ${import_picocolors7.default.yellow(String(result.fromAmount))} ${result.fromToken} \u2192 ${import_picocolors7.default.green(result.toAmount.toFixed(6))} ${result.toToken}`
31591
31783
  );
31592
31784
  if (result.priceImpact > 5e-3) {
31593
- printKeyValue("Price impact", import_picocolors6.default.yellow(`${(result.priceImpact * 100).toFixed(2)}%`));
31785
+ printKeyValue("Price impact", import_picocolors7.default.yellow(`${(result.priceImpact * 100).toFixed(2)}%`));
31594
31786
  }
31595
31787
  printKeyValue("Route", `${result.fromToken} \u2192 ${result.toToken} (${result.route})`);
31596
31788
  printKeyValue("Gas", `${result.gasCost.toFixed(6)} SUI`);
@@ -31604,12 +31796,12 @@ Examples:
31604
31796
  }
31605
31797
 
31606
31798
  // src/commands/pay.ts
31607
- var import_picocolors7 = __toESM(require_picocolors(), 1);
31799
+ var import_picocolors8 = __toESM(require_picocolors(), 1);
31608
31800
  function registerPay(program3) {
31609
31801
  program3.command("pay <url>").description("Pay an MPP / x402 service (USDC on Sui)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--method <method>", "HTTP method (GET, POST, PUT)", "GET").option("--data <json>", "Request body for POST/PUT (auto-promotes --method to POST)").option("--header <key=value>", "Additional HTTP header (repeatable)", collectHeaders, {}).option("--max-price <amount>", "Max USDC price to auto-approve", "1.00").option(
31610
31802
  "--estimate",
31611
31803
  "Preview the price + service info (no signing, no payment). Exits 0 if the service responds with a 402 challenge."
31612
- ).option("--force", "Override opt-in spending limits (see `t2 limit`)").addHelpText(
31804
+ ).option("--force", "Override spending limits for this call (see `t2 limit`)").addHelpText(
31613
31805
  "after",
31614
31806
  `
31615
31807
  Examples:
@@ -31663,10 +31855,10 @@ Examples:
31663
31855
  return;
31664
31856
  }
31665
31857
  if (result.paid && result.receipt) {
31666
- const gasNote = typeof result.gasCostSui === "number" ? result.gasCostSui === 0 ? import_picocolors7.default.green(" \xB7 gasless \u26A1") : import_picocolors7.default.dim(` \xB7 gas: ${result.gasCostSui.toFixed(6)} SUI`) : "";
31667
- printSuccess(`Paid via MPP (tx: ${result.receipt.reference.slice(0, 10)}\u2026)${gasNote}`);
31858
+ const gasNote = typeof result.gasCostSui === "number" ? result.gasCostSui === 0 ? import_picocolors8.default.green(" \xB7 gasless \u26A1") : import_picocolors8.default.dim(` \xB7 gas: ${result.gasCostSui.toFixed(6)} SUI`) : "";
31859
+ printSuccess(`Paid via ${result.dialect ?? "x402"} (tx: ${result.receipt.reference.slice(0, 10)}\u2026)${gasNote}`);
31668
31860
  }
31669
- printInfo(`\u2190 ${result.status} OK ${import_picocolors7.default.dim(`[${elapsed}ms]`)}`);
31861
+ printInfo(`\u2190 ${result.status} OK ${import_picocolors8.default.dim(`[${elapsed}ms]`)}`);
31670
31862
  printBlank();
31671
31863
  if (typeof result.body === "string") {
31672
31864
  console.log(result.body);
@@ -31684,7 +31876,7 @@ async function runEstimate(url, opts) {
31684
31876
  const canHaveBody = method !== "GET" && method !== "HEAD";
31685
31877
  if (!isJsonMode()) {
31686
31878
  printBlank();
31687
- printInfo(`\u2192 ${method} ${url} ${import_picocolors7.default.dim("(estimate \u2014 no payment)")}`);
31879
+ printInfo(`\u2192 ${method} ${url} ${import_picocolors8.default.dim("(estimate \u2014 no payment)")}`);
31688
31880
  }
31689
31881
  const response = await fetch(url, {
31690
31882
  method,
@@ -31734,6 +31926,7 @@ async function runEstimate(url, opts) {
31734
31926
  const recipient = req.payTo ?? "unknown";
31735
31927
  const looksLikeUsdc = /::usdc::USDC/i.test(asset);
31736
31928
  const display = amountRaw && looksLikeUsdc ? `$${(Number(amountRaw) / 1e6).toFixed(4)} USDC` : amountRaw ?? "unknown";
31929
+ const inputSchema = await fetchInputSchema(url, method);
31737
31930
  if (isJsonMode()) {
31738
31931
  printJson({
31739
31932
  url,
@@ -31747,19 +31940,28 @@ async function runEstimate(url, opts) {
31747
31940
  amount: amountRaw,
31748
31941
  amountDisplay: display,
31749
31942
  asset,
31750
- recipient
31943
+ recipient,
31944
+ inputSchema
31751
31945
  }
31752
31946
  });
31753
31947
  return;
31754
31948
  }
31755
31949
  printBlank();
31756
31950
  printSuccess(`Service requires payment (x402 ${req.scheme ?? "exact"} on ${req.network ?? "sui"})`);
31757
- printKeyValue("Price", import_picocolors7.default.green(display));
31951
+ printKeyValue("Price", import_picocolors8.default.green(display));
31758
31952
  printKeyValue("Asset", asset);
31759
31953
  printKeyValue("Recipient", recipient);
31760
31954
  if (req.resource) {
31761
31955
  printKeyValue("Resource", req.resource);
31762
31956
  }
31957
+ const fields = describeSchemaFields(inputSchema);
31958
+ if (fields.length > 0) {
31959
+ printBlank();
31960
+ printInfo("Input (request body):");
31961
+ for (const f of fields) {
31962
+ printLine(" " + import_picocolors8.default.dim(f));
31963
+ }
31964
+ }
31763
31965
  printBlank();
31764
31966
  printInfo(`Run without --estimate to pay and execute.`);
31765
31967
  printBlank();
@@ -31771,9 +31973,31 @@ function collectHeaders(value, previous) {
31771
31973
  }
31772
31974
  return previous;
31773
31975
  }
31976
+ async function fetchInputSchema(url, method) {
31977
+ try {
31978
+ const u = new URL(url);
31979
+ const res = await fetch(`${u.origin}/openapi.json`);
31980
+ if (!res.ok) return null;
31981
+ const doc = await res.json();
31982
+ const op = doc.paths?.[u.pathname]?.[method.toLowerCase()];
31983
+ return op?.requestBody?.content?.["application/json"]?.schema ?? null;
31984
+ } catch {
31985
+ return null;
31986
+ }
31987
+ }
31988
+ function describeSchemaFields(schema) {
31989
+ if (!schema || schema.type !== "object" || !schema.properties) return [];
31990
+ const required = new Set(schema.required ?? []);
31991
+ return Object.entries(schema.properties).map(([name, prop]) => {
31992
+ const type = prop.type ?? (prop.enum ? `enum(${prop.enum.join("|")})` : "any");
31993
+ const opt = required.has(name) ? "" : "?";
31994
+ const desc = prop.description ? ` \u2014 ${prop.description}` : "";
31995
+ return `${name}${opt}: ${type}${desc}`;
31996
+ });
31997
+ }
31774
31998
 
31775
31999
  // src/commands/services/search.ts
31776
- var import_picocolors8 = __toESM(require_picocolors(), 1);
32000
+ var import_picocolors9 = __toESM(require_picocolors(), 1);
31777
32001
 
31778
32002
  // src/commands/services/catalog.ts
31779
32003
  var DEFAULT_GATEWAY_URL = "https://mpp.t2000.ai";
@@ -31875,9 +32099,9 @@ Examples:
31875
32099
  }
31876
32100
  function renderServiceLine(svc) {
31877
32101
  const minPrice = cheapestEndpointPrice(svc);
31878
- const priceTag = minPrice !== null ? import_picocolors8.default.green(`from $${minPrice}`) : import_picocolors8.default.dim("no pricing");
31879
- const catTag = svc.categories.length > 0 ? import_picocolors8.default.dim(`[${svc.categories.join(", ")}]`) : "";
31880
- printKeyValue(import_picocolors8.default.bold(svc.name), `${priceTag} ${catTag}`);
32102
+ const priceTag = minPrice !== null ? import_picocolors9.default.green(`from $${minPrice}`) : import_picocolors9.default.dim("no pricing");
32103
+ const catTag = svc.categories.length > 0 ? import_picocolors9.default.dim(`[${svc.categories.join(", ")}]`) : "";
32104
+ printKeyValue(import_picocolors9.default.bold(svc.name), `${priceTag} ${catTag}`);
31881
32105
  printKeyValue(" url", svc.serviceUrl);
31882
32106
  printKeyValue(" about", svc.description);
31883
32107
  printBlank();
@@ -31891,7 +32115,7 @@ function cheapestEndpointPrice(svc) {
31891
32115
  }
31892
32116
 
31893
32117
  // src/commands/services/inspect.ts
31894
- var import_picocolors9 = __toESM(require_picocolors(), 1);
32118
+ var import_picocolors10 = __toESM(require_picocolors(), 1);
31895
32119
  function registerServicesInspect(parent) {
31896
32120
  parent.command("inspect").description("Show pricing + endpoints for an MPP service or endpoint URL").argument("<url>", "Service base URL or endpoint URL").option("--gateway <url>", "Override gateway base URL (default: https://mpp.t2000.ai)").addHelpText(
31897
32121
  "after",
@@ -31928,7 +32152,7 @@ Examples:
31928
32152
  return;
31929
32153
  }
31930
32154
  printBlank();
31931
- printKeyValue("Service", import_picocolors9.default.bold(service.name));
32155
+ printKeyValue("Service", import_picocolors10.default.bold(service.name));
31932
32156
  printKeyValue("URL", service.serviceUrl);
31933
32157
  printKeyValue("About", service.description);
31934
32158
  if (service.categories.length > 0) {
@@ -31958,7 +32182,7 @@ Examples:
31958
32182
  function renderEndpoint(ep, serviceUrl) {
31959
32183
  const price = `$${ep.price}`;
31960
32184
  const label = `${ep.method} ${ep.path}`.padEnd(40);
31961
- printKeyValue(label, `${import_picocolors9.default.green(price)} ${import_picocolors9.default.dim(ep.description)}`);
32185
+ printKeyValue(label, `${import_picocolors10.default.green(price)} ${import_picocolors10.default.dim(ep.description)}`);
31962
32186
  printKeyValue(" url", `${serviceUrl}${ep.path}`);
31963
32187
  printBlank();
31964
32188
  }
@@ -31981,7 +32205,7 @@ T2000_GATEWAY_URL or --gateway <url> for local development.
31981
32205
  }
31982
32206
 
31983
32207
  // src/commands/limit/show.ts
31984
- var import_picocolors10 = __toESM(require_picocolors(), 1);
32208
+ var import_picocolors11 = __toESM(require_picocolors(), 1);
31985
32209
  function registerLimitShow(parent) {
31986
32210
  parent.command("show").description("Show current spending limits").action(async (opts) => {
31987
32211
  try {
@@ -32004,10 +32228,10 @@ function registerLimitShow(parent) {
32004
32228
  }
32005
32229
  printBlank();
32006
32230
  if (limits.perTxUsd !== void 0) {
32007
- printKeyValue("Per-transaction", import_picocolors10.default.green(`$${limits.perTxUsd}`));
32231
+ printKeyValue("Per-transaction", import_picocolors11.default.green(`$${limits.perTxUsd}`));
32008
32232
  }
32009
32233
  if (limits.dailyUsd !== void 0) {
32010
- printKeyValue("Daily (cumulative)", import_picocolors10.default.green(`$${limits.dailyUsd}`));
32234
+ printKeyValue("Daily (cumulative)", import_picocolors11.default.green(`$${limits.dailyUsd}`));
32011
32235
  }
32012
32236
  printBlank();
32013
32237
  printInfo("Use `--force` on `t2 send` / `t2 swap` / `t2 pay` to override per-call.");
@@ -32019,7 +32243,7 @@ function registerLimitShow(parent) {
32019
32243
  }
32020
32244
 
32021
32245
  // src/commands/limit/set.ts
32022
- var import_picocolors11 = __toESM(require_picocolors(), 1);
32246
+ var import_picocolors12 = __toESM(require_picocolors(), 1);
32023
32247
  function parseLimitSetArgs(opts) {
32024
32248
  const perTx = opts.perTx !== void 0 ? parseUsdFlag("--per-tx", opts.perTx) : void 0;
32025
32249
  const daily = opts.daily !== void 0 ? parseUsdFlag("--daily", opts.daily) : void 0;
@@ -32061,10 +32285,10 @@ Examples:
32061
32285
  printBlank();
32062
32286
  printSuccess("Spending limits updated.");
32063
32287
  if (next?.perTxUsd !== void 0) {
32064
- printKeyValue("Per-transaction", import_picocolors11.default.green(`$${next.perTxUsd}`));
32288
+ printKeyValue("Per-transaction", import_picocolors12.default.green(`$${next.perTxUsd}`));
32065
32289
  }
32066
32290
  if (next?.dailyUsd !== void 0) {
32067
- printKeyValue("Daily (cumulative)", import_picocolors11.default.green(`$${next.dailyUsd}`));
32291
+ printKeyValue("Daily (cumulative)", import_picocolors12.default.green(`$${next.dailyUsd}`));
32068
32292
  }
32069
32293
  printBlank();
32070
32294
  printInfo("Use `t2 limit show` to view; `t2 limit reset` to clear.");
@@ -32106,7 +32330,7 @@ function registerLimitReset(parent) {
32106
32330
 
32107
32331
  // src/commands/limit/index.ts
32108
32332
  function registerLimit(program3) {
32109
- const group = program3.command("limit").description("Manage opt-in spending limits (no defaults)").addHelpText(
32333
+ const group = program3.command("limit").description("Manage spending limits (on by default: $25/tx, $100/day)").addHelpText(
32110
32334
  "after",
32111
32335
  `
32112
32336
  Subcommands:
@@ -32126,7 +32350,7 @@ function registerMcpStart(parent) {
32126
32350
  parent.command("start", { isDefault: true }).description("Start MCP server (stdio transport \u2014 for AI client integration)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
32127
32351
  let mod2;
32128
32352
  try {
32129
- mod2 = await import("./dist-U65BYMC5.js");
32353
+ mod2 = await import("./dist-O4WYNOSR.js");
32130
32354
  } catch {
32131
32355
  console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
32132
32356
  process.exit(1);
@@ -32135,70 +32359,6 @@ function registerMcpStart(parent) {
32135
32359
  });
32136
32360
  }
32137
32361
 
32138
- // src/commands/mcp/platforms.ts
32139
- import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
32140
- import { join as join3, dirname as dirname2 } from "path";
32141
- import { homedir as homedir2 } from "os";
32142
- import { existsSync as existsSync2 } from "fs";
32143
- var MCP_SERVER_ENTRY = {
32144
- command: "t2000",
32145
- args: ["mcp", "start"]
32146
- };
32147
- var MCP_SERVER_KEY = "t2000";
32148
- function getPlatformConfigs() {
32149
- const home = homedir2();
32150
- return [
32151
- {
32152
- name: "Claude Desktop",
32153
- slug: "claude-desktop",
32154
- path: join3(home, "Library", "Application Support", "Claude", "claude_desktop_config.json")
32155
- },
32156
- {
32157
- name: "Cursor",
32158
- slug: "cursor",
32159
- path: join3(home, ".cursor", "mcp.json")
32160
- },
32161
- {
32162
- name: "Windsurf",
32163
- slug: "windsurf",
32164
- path: join3(home, ".codeium", "windsurf", "mcp_config.json")
32165
- }
32166
- ];
32167
- }
32168
- async function readJsonFile(path2) {
32169
- try {
32170
- const content = await readFile2(path2, "utf-8");
32171
- return JSON.parse(content);
32172
- } catch {
32173
- return {};
32174
- }
32175
- }
32176
- async function writeJsonFile(path2, data) {
32177
- const dir = dirname2(path2);
32178
- if (!existsSync2(dir)) {
32179
- await mkdir2(dir, { recursive: true });
32180
- }
32181
- await writeFile2(path2, JSON.stringify(data, null, 2) + "\n", "utf-8");
32182
- }
32183
- function withMcpEntry(config) {
32184
- return {
32185
- ...config,
32186
- mcpServers: {
32187
- ...config.mcpServers ?? {},
32188
- [MCP_SERVER_KEY]: { ...MCP_SERVER_ENTRY }
32189
- }
32190
- };
32191
- }
32192
- function hasMcpEntry(config) {
32193
- return typeof config.mcpServers === "object" && config.mcpServers !== null && MCP_SERVER_KEY in config.mcpServers;
32194
- }
32195
- function withoutMcpEntry(config) {
32196
- if (!hasMcpEntry(config)) return config;
32197
- const servers = { ...config.mcpServers };
32198
- delete servers[MCP_SERVER_KEY];
32199
- return { ...config, mcpServers: servers };
32200
- }
32201
-
32202
32362
  // src/commands/mcp/install.ts
32203
32363
  async function runInstall() {
32204
32364
  const platforms = getPlatformConfigs();
@@ -32530,31 +32690,33 @@ For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
32530
32690
  }
32531
32691
 
32532
32692
  // src/program.ts
32533
- var require2 = createRequire(import.meta.url);
32534
- var { version: CLI_VERSION } = require2("../package.json");
32693
+ var require3 = createRequire2(import.meta.url);
32694
+ var { version: CLI_VERSION2 } = require3("../package.json");
32535
32695
  function createProgram() {
32536
32696
  const program3 = new Command();
32537
- program3.name("t2").description("Agent Wallet \u2014 autonomous Sui USDC + USDsui wallet for AI agents").version(`${CLI_VERSION}`).option("--json", "Output in JSON format").hook("preAction", (thisCommand) => {
32697
+ program3.name("t2").description("Agent Wallet \u2014 autonomous Sui USDC + USDsui wallet for AI agents").version(`${CLI_VERSION2}`).option("--json", "Output in JSON format").hook("preAction", (thisCommand) => {
32538
32698
  const opts = thisCommand.optsWithGlobals();
32539
32699
  if (opts.json) setJsonMode(true);
32540
32700
  }).addHelpText("after", `
32541
32701
  Examples:
32542
32702
  $ t2 init Create a new Agent Wallet
32543
32703
  $ t2 init --import Import an existing Bech32 secret (interactive)
32544
- $ t2 receive Show address + QR for incoming transfers
32704
+ $ t2 fund Show address + QR to fund the wallet
32705
+ $ t2 status Health check: wallet, balances, limits, MCP, gateway
32545
32706
  $ t2 balance Show USDC / USDsui / SUI holdings
32546
32707
  $ t2 send 5 USDC alice.sui Send 5 USDC (gasless; asset required)
32547
32708
  $ t2 swap 100 USDC SUI Swap 100 USDC for SUI via Cetus
32548
- $ t2 pay <mpp_url> Pay an MPP / x402 service
32549
- $ t2 services search "image" Discover MPP services in the gateway catalog
32550
- $ t2 limit set --daily 100 Opt in to a $100 daily-send spending cap
32709
+ $ t2 pay <url> --estimate Preview an x402 service's price + input schema (no payment)
32710
+ $ t2 services search "image" Discover x402 services in the gateway catalog
32711
+ $ t2 limit set --daily 100 Change the daily spend cap (default $100/day)
32551
32712
  $ t2 mcp install Connect Claude / Cursor / Windsurf
32552
32713
  $ t2 skills install Install skills as local SKILL.md files`);
32553
32714
  registerInit(program3);
32554
32715
  registerExport(program3);
32555
- registerReceive(program3);
32716
+ registerFund(program3);
32556
32717
  registerBalance(program3);
32557
32718
  registerHistory(program3);
32719
+ registerStatus(program3);
32558
32720
  registerSend(program3);
32559
32721
  registerSwap(program3);
32560
32722
  registerPay(program3);