@t2000/cli 6.0.0 → 7.0.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
@@ -33122,7 +33122,7 @@ function registerMcpStart(parent) {
33122
33122
  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) => {
33123
33123
  let mod3;
33124
33124
  try {
33125
- mod3 = await import("./dist-DYYYQUW7.js");
33125
+ mod3 = await import("./dist-Q2GGV3W4.js");
33126
33126
  } catch {
33127
33127
  console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
33128
33128
  process.exit(1);
@@ -33594,9 +33594,6 @@ For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
33594
33594
  registerSkillsUninstall(group);
33595
33595
  }
33596
33596
 
33597
- // src/commands/agent/index.ts
33598
- import { createHash as createHash2 } from "crypto";
33599
-
33600
33597
  // src/commands/agent/create.ts
33601
33598
  var DEFAULT_API_BASE3 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
33602
33599
  var STORE_BASE = "https://agents.t2000.ai";
@@ -33745,236 +33742,7 @@ function registerAgentCreate(group) {
33745
33742
  printBlank();
33746
33743
  printLine("Next:");
33747
33744
  printLine(" t2 fund # add USDC (QR / card link)");
33748
- printLine(" t2 agent services add ... # list something to sell");
33749
- printLine(" t2 agent deploy ... # wrap an API behind x402");
33750
- printBlank();
33751
- } catch (error) {
33752
- handleError(error);
33753
- }
33754
- });
33755
- }
33756
-
33757
- // src/commands/agent/services.ts
33758
- import { createHash } from "crypto";
33759
- import { readFileSync as readFileSync3 } from "fs";
33760
- var SLUG_RE = /^[a-z0-9][a-z0-9-]{1,39}$/;
33761
- async function fetchJson2(url, init) {
33762
- const res = await fetch(url, {
33763
- method: init?.method ?? "GET",
33764
- headers: init?.body ? { "Content-Type": "application/json" } : void 0,
33765
- body: init?.body ? JSON.stringify(init.body) : void 0
33766
- });
33767
- const json = await res.json().catch(() => ({}));
33768
- if (!res.ok) {
33769
- const err = json.error;
33770
- const msg = typeof err === "string" ? err : err?.message ?? `HTTP ${res.status}`;
33771
- throw new Error(msg);
33772
- }
33773
- return json;
33774
- }
33775
- function canonicalServicesJson(services) {
33776
- return JSON.stringify(
33777
- services.map(
33778
- (s) => Object.fromEntries(
33779
- Object.entries(s).sort(([a], [b]) => a.localeCompare(b))
33780
- )
33781
- )
33782
- );
33783
- }
33784
- async function getCatalog(base, address) {
33785
- const res = await fetchJson2(
33786
- `${base}/agent/services?address=${encodeURIComponent(address)}`
33787
- );
33788
- return Array.isArray(res.services) ? res.services : [];
33789
- }
33790
- async function putCatalog(opts) {
33791
- const agent = await withAgent({ keyPath: opts.keyPath });
33792
- const address = agent.address();
33793
- const challenge = await fetchJson2(`${opts.base}/agent/challenge`, {
33794
- method: "POST",
33795
- body: { address }
33796
- });
33797
- const nonce = challenge.nonce;
33798
- if (!nonce) {
33799
- throw new Error("Failed to get a challenge nonce.");
33800
- }
33801
- const digest = createHash("sha256").update(canonicalServicesJson(opts.services)).digest("hex");
33802
- const message = new TextEncoder().encode(
33803
- `t2000-agent-services:${nonce}:${digest}`
33804
- );
33805
- const { signature } = await agent.keypair.signPersonalMessage(message);
33806
- const res = await fetchJson2(`${opts.base}/agent/services`, {
33807
- method: "POST",
33808
- body: { address, nonce, signature, services: opts.services }
33809
- });
33810
- return { address, count: Number(res.count ?? opts.services.length) };
33811
- }
33812
- function entryFromFlags(opts) {
33813
- const slug = String(opts.slug ?? "").trim().toLowerCase();
33814
- if (!SLUG_RE.test(slug)) {
33815
- throw new Error("--slug is required: [a-z0-9-], 2-40 chars.");
33816
- }
33817
- const out = { slug };
33818
- if (opts.title !== void 0) {
33819
- out.title = opts.title;
33820
- }
33821
- if (opts.description !== void 0) {
33822
- out.description = opts.description;
33823
- }
33824
- if (opts.price !== void 0) {
33825
- out.priceUsdc = opts.price;
33826
- }
33827
- if (opts.input !== void 0) {
33828
- out.input = opts.input || null;
33829
- }
33830
- if (opts.endpoint !== void 0) {
33831
- out.endpoint = opts.endpoint || null;
33832
- }
33833
- if (opts.method !== void 0) {
33834
- out.method = opts.method.toUpperCase() === "GET" ? "GET" : "POST";
33835
- }
33836
- return out;
33837
- }
33838
- function registerAgentServices(agentGroup, defaults) {
33839
- const group = agentGroup.command("services").description(
33840
- "Manage this agent's service CATALOG (one agent, many services). Buy URLs: commerce/pay/<agent>/<slug>. [Store v2]"
33841
- );
33842
- group.command("list").argument("[address]", "Agent address (default: your wallet)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${defaults.apiBase})`).description("List the catalog (public read).").action(async (addressArg, opts) => {
33843
- try {
33844
- const base = opts.api ?? defaults.apiBase;
33845
- const address = addressArg ?? (await withAgent({ keyPath: opts.key })).address();
33846
- const services = await getCatalog(base, address);
33847
- if (isJsonMode()) {
33848
- printJson({ address, services });
33849
- return;
33850
- }
33851
- printBlank();
33852
- if (services.length === 0) {
33853
- printLine("No services in the catalog. Add one: t2 agent services add --slug <slug> --title \u2026 --description \u2026 --price \u2026");
33854
- printBlank();
33855
- return;
33856
- }
33857
- for (const s of services) {
33858
- printKeyValue(
33859
- s.slug,
33860
- `$${s.priceUsdc} \u2014 ${s.title}${s.active === false ? " (inactive)" : ""}`
33861
- );
33862
- }
33863
- printBlank();
33864
- } catch (error) {
33865
- handleError(error);
33866
- }
33867
- });
33868
- group.command("add").description("Add one service to the catalog.").requiredOption("--slug <slug>", "Service slug ([a-z0-9-], 2-40 chars)").requiredOption("--title <title>", "Service title (\u226480 chars)").requiredOption("--description <text>", "Listing copy (\u2264480 chars)").requiredOption("--price <usdc>", "Price per call in USDC (e.g. 0.02)").option("--input <hint>", 'Input hint, e.g. "Provide: 1. address 2. chain"').option("--endpoint <url>", "Self-hosted https endpoint (omit for wrap/payment-only)").option("--method <method>", "Wrap delivery method: GET or POST").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${defaults.apiBase})`).action(async (opts) => {
33869
- try {
33870
- const base = opts.api ?? defaults.apiBase;
33871
- const agent = await withAgent({ keyPath: opts.key });
33872
- const current = await getCatalog(base, agent.address());
33873
- const entry = entryFromFlags(opts);
33874
- if (current.some((s) => s.slug === entry.slug)) {
33875
- throw new Error(
33876
- `Slug "${entry.slug}" already exists \u2014 use: t2 agent services update --slug ${entry.slug}`
33877
- );
33878
- }
33879
- const next = {
33880
- title: "",
33881
- description: "",
33882
- priceUsdc: "0",
33883
- active: true,
33884
- ...entry
33885
- };
33886
- const { count } = await putCatalog({
33887
- base,
33888
- keyPath: opts.key,
33889
- services: [...current, next]
33890
- });
33891
- if (isJsonMode()) {
33892
- printJson({ added: entry.slug, count });
33893
- return;
33894
- }
33895
- printBlank();
33896
- printSuccess(`Service "${entry.slug}" added \u2014 catalog now ${count} service${count === 1 ? "" : "s"}.`);
33897
- printLine(`Buy URL: https://x402.t2000.ai/commerce/pay/${agent.address()}/${entry.slug}`);
33898
- printBlank();
33899
- } catch (error) {
33900
- handleError(error);
33901
- }
33902
- });
33903
- group.command("update").description("Update one service (only the provided fields change).").requiredOption("--slug <slug>", "Service slug to update").option("--title <title>", "Service title (\u226480 chars)").option("--description <text>", "Listing copy (\u2264480 chars)").option("--price <usdc>", "Price per call in USDC").option("--input <hint>", 'Input hint ("" to clear)').option("--endpoint <url>", 'Self-hosted https endpoint ("" to clear \u2192 wrap mode)').option("--method <method>", "Wrap delivery method: GET or POST").option("--active <bool>", "true | false \u2014 per-service kill switch").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${defaults.apiBase})`).action(async (opts) => {
33904
- try {
33905
- const base = opts.api ?? defaults.apiBase;
33906
- const agent = await withAgent({ keyPath: opts.key });
33907
- const current = await getCatalog(base, agent.address());
33908
- const entry = entryFromFlags(opts);
33909
- const idx = current.findIndex((s) => s.slug === entry.slug);
33910
- if (idx === -1) {
33911
- throw new Error(`No service "${entry.slug}" in the catalog.`);
33912
- }
33913
- const merged = { ...current[idx], ...entry };
33914
- if (opts.active !== void 0) {
33915
- merged.active = String(opts.active).toLowerCase() !== "false";
33916
- }
33917
- const services = [...current];
33918
- services[idx] = merged;
33919
- const { count } = await putCatalog({ base, keyPath: opts.key, services });
33920
- if (isJsonMode()) {
33921
- printJson({ updated: entry.slug, count });
33922
- return;
33923
- }
33924
- printBlank();
33925
- printSuccess(`Service "${entry.slug}" updated.`);
33926
- printBlank();
33927
- } catch (error) {
33928
- handleError(error);
33929
- }
33930
- });
33931
- group.command("remove").description("Remove one service from the catalog.").requiredOption("--slug <slug>", "Service slug to remove").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${defaults.apiBase})`).action(async (opts) => {
33932
- try {
33933
- const base = opts.api ?? defaults.apiBase;
33934
- const agent = await withAgent({ keyPath: opts.key });
33935
- const slug = String(opts.slug ?? "").trim().toLowerCase();
33936
- const current = await getCatalog(base, agent.address());
33937
- const services = current.filter((s) => s.slug !== slug);
33938
- if (services.length === current.length) {
33939
- throw new Error(`No service "${slug}" in the catalog.`);
33940
- }
33941
- const { count } = await putCatalog({ base, keyPath: opts.key, services });
33942
- if (isJsonMode()) {
33943
- printJson({ removed: slug, count });
33944
- return;
33945
- }
33946
- printBlank();
33947
- printSuccess(`Service "${slug}" removed \u2014 catalog now ${count} service${count === 1 ? "" : "s"}.`);
33948
- printBlank();
33949
- } catch (error) {
33950
- handleError(error);
33951
- }
33952
- });
33953
- group.command("sync").description(
33954
- "Declarative catalog sync \u2014 the manifest file IS the catalog (adds/updates/removes to match). The catalog-scale path."
33955
- ).argument("<file>", "Path to a JSON manifest: [{ slug, title, description, priceUsdc, input?, endpoint?, method?, active? }]").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${defaults.apiBase})`).action(async (file, opts) => {
33956
- try {
33957
- const base = opts.api ?? defaults.apiBase;
33958
- const raw = JSON.parse(readFileSync3(file, "utf8"));
33959
- const list = Array.isArray(raw) ? raw : raw?.services ?? null;
33960
- if (!Array.isArray(list)) {
33961
- throw new Error(
33962
- 'Manifest must be a JSON array of services (or { "services": [...] }).'
33963
- );
33964
- }
33965
- const services = list.map((s) => {
33966
- const entry = s;
33967
- return { ...entry, active: entry.active !== false };
33968
- });
33969
- const agent = await withAgent({ keyPath: opts.key });
33970
- const before = await getCatalog(base, agent.address());
33971
- const { count } = await putCatalog({ base, keyPath: opts.key, services });
33972
- if (isJsonMode()) {
33973
- printJson({ synced: count, before: before.length });
33974
- return;
33975
- }
33976
- printBlank();
33977
- printSuccess(`Catalog synced \u2014 ${before.length} \u2192 ${count} services.`);
33745
+ printLine(" t2 agent service ... # declare a paid endpoint (sell per call)");
33978
33746
  printBlank();
33979
33747
  } catch (error) {
33980
33748
  handleError(error);
@@ -33985,7 +33753,6 @@ function registerAgentServices(agentGroup, defaults) {
33985
33753
  // src/commands/agent/index.ts
33986
33754
  var DEFAULT_API_BASE4 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
33987
33755
  var DEFAULT_GATEWAY = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
33988
- var DEFAULT_RAIL = process.env.T2000_RAIL_URL ?? "https://x402.t2000.ai";
33989
33756
  var AGENT_CATEGORIES2 = [
33990
33757
  "ai-models",
33991
33758
  "data-feeds",
@@ -34007,13 +33774,6 @@ function normalizeCategory(input) {
34007
33774
  }
34008
33775
  return c;
34009
33776
  }
34010
- function collectHeader(value, previous) {
34011
- const [key, ...rest] = value.split("=");
34012
- if (key && rest.length > 0) {
34013
- previous[key.trim()] = rest.join("=").trim();
34014
- }
34015
- return previous;
34016
- }
34017
33777
  function normalizeTopupAsset(input) {
34018
33778
  return input?.toLowerCase() === "usdsui" ? "USDsui" : "USDC";
34019
33779
  }
@@ -34023,19 +33783,19 @@ async function fundCredit(agent, base, amountStr, assetOpt) {
34023
33783
  throw new Error(`amount must be a positive number (got "${amountStr}").`);
34024
33784
  }
34025
33785
  const asset = normalizeTopupAsset(assetOpt);
34026
- const cfg = await fetchJson3(`${base}/agent/topup`, { method: "GET" });
33786
+ const cfg = await fetchJson2(`${base}/agent/topup`, { method: "GET" });
34027
33787
  const treasury = cfg.treasury;
34028
33788
  if (!treasury) {
34029
33789
  throw new Error("Could not resolve the t2000 treasury address.");
34030
33790
  }
34031
33791
  const sent = await agent.send({ to: treasury, amount, asset });
34032
- const topup = await fetchJson3(`${base}/agent/topup`, {
33792
+ const topup = await fetchJson2(`${base}/agent/topup`, {
34033
33793
  method: "POST",
34034
33794
  body: { address: agent.address(), digest: sent.tx }
34035
33795
  });
34036
33796
  return { amount, asset, balanceUsd: topup.balanceUsd };
34037
33797
  }
34038
- async function fetchJson3(url, init) {
33798
+ async function fetchJson2(url, init) {
34039
33799
  const res = await fetch(url, {
34040
33800
  method: init.method,
34041
33801
  headers: init.body ? { "Content-Type": "application/json" } : void 0,
@@ -34058,12 +33818,10 @@ Subcommands:
34058
33818
  $ t2 agent onboard --fund 5 Fund 5 USDC \u2192 mint an API key (ready to call)
34059
33819
  $ t2 agent onboard --fund 5 --asset USDsui
34060
33820
  $ t2 agent onboard Already funded \u2192 just mint a key
34061
- $ t2 agent services add --slug sui-price --title "SUI spot" --description "\u2026" --price 0.02
34062
- $ t2 agent services sync ./services.json Manifest IS the catalog (catalog-scale sellers)
33821
+ $ t2 agent pay <address> Pay another agent's declared service
34063
33822
  `
34064
33823
  );
34065
33824
  registerAgentCreate(group);
34066
- registerAgentServices(group, { apiBase: DEFAULT_API_BASE4 });
34067
33825
  group.command("onboard").description(
34068
33826
  "Buy-side setup: fund credit (gasless USDC/USDsui) + mint a Private API key. Registering an Agent ID is free and separate \u2014 `t2 init` / `t2 agent register`."
34069
33827
  ).option("--fund <amount>", "Stablecoin amount to deposit as credit (omit if already funded)").option("--asset <asset>", "USDC (default) or USDsui", "USDC").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
@@ -34080,7 +33838,7 @@ Subcommands:
34080
33838
  );
34081
33839
  }
34082
33840
  }
34083
- const challenge = await fetchJson3(`${base}/agent/challenge`, {
33841
+ const challenge = await fetchJson2(`${base}/agent/challenge`, {
34084
33842
  method: "POST",
34085
33843
  body: { address }
34086
33844
  });
@@ -34090,7 +33848,7 @@ Subcommands:
34090
33848
  }
34091
33849
  const message = new TextEncoder().encode(`t2000-agent-keys:${nonce}`);
34092
33850
  const { signature } = await agent.keypair.signPersonalMessage(message);
34093
- const minted = await fetchJson3(`${base}/agent/keys`, {
33851
+ const minted = await fetchJson2(`${base}/agent/keys`, {
34094
33852
  method: "POST",
34095
33853
  body: { address, nonce, signature }
34096
33854
  });
@@ -34287,7 +34045,7 @@ Subcommands:
34287
34045
  const base = opts.api ?? DEFAULT_API_BASE4;
34288
34046
  const agent = await withAgent({ keyPath: opts.key });
34289
34047
  const address = agent.address();
34290
- const challenge = await fetchJson3(`${base}/agent/challenge`, {
34048
+ const challenge = await fetchJson2(`${base}/agent/challenge`, {
34291
34049
  method: "POST",
34292
34050
  body: { address }
34293
34051
  });
@@ -34297,7 +34055,7 @@ Subcommands:
34297
34055
  }
34298
34056
  const message = new TextEncoder().encode(`t2000-agent-profile:${nonce}`);
34299
34057
  const { signature } = await agent.keypair.signPersonalMessage(message);
34300
- await fetchJson3(`${base}/agent/profile`, {
34058
+ await fetchJson2(`${base}/agent/profile`, {
34301
34059
  method: "POST",
34302
34060
  body: {
34303
34061
  address,
@@ -34394,141 +34152,9 @@ Subcommands:
34394
34152
  }
34395
34153
  }
34396
34154
  );
34397
- group.command("deploy").description(
34398
- "Deploy a paid service by wrapping any HTTP API \u2014 t2000 hosts the proxy (your key stays server-side, encrypted), lists it, and settles payments. No server needed. Use --remove to take it down. [Agent Commerce]"
34399
- ).option("--upstream <url>", "The upstream API URL to wrap (https)").option(
34400
- "--header <k=v>",
34401
- "Header to inject into upstream calls (repeatable; e.g. your API key)",
34402
- collectHeader,
34403
- {}
34404
- ).option("--method <method>", "Upstream method: GET or POST (default POST)").option("--price <usdc>", "Price per call in USDC (e.g. 0.02)").option(
34405
- "--category <category>",
34406
- `Storefront category: ${AGENT_CATEGORIES2.join(" | ")}`
34407
- ).option("--remove", "Take down the deployed service").option(
34408
- "--service <slug>",
34409
- "Catalog service slug \u2014 wrap config for ONE SKU (Store v2; omit = the default service)"
34410
- ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
34411
- async (opts) => {
34412
- try {
34413
- const base = opts.api ?? DEFAULT_API_BASE4;
34414
- const gateway = opts.gateway ?? DEFAULT_GATEWAY;
34415
- const category = normalizeCategory(opts.category);
34416
- const slug = opts.service?.trim().toLowerCase() || void 0;
34417
- const agent = await withAgent({ keyPath: opts.key });
34418
- const address = agent.address();
34419
- if (opts.remove) {
34420
- const ts2 = Date.now();
34421
- const msg2 = `t2000-deploy-remove:${ts2}${slug ? `:${slug}` : ""}`;
34422
- const { signature: signature2 } = await agent.keypair.signPersonalMessage(
34423
- new TextEncoder().encode(msg2)
34424
- );
34425
- await fetchJson3(`${gateway}/deploy/config`, {
34426
- method: "DELETE",
34427
- body: { address, timestamp: ts2, signature: signature2, ...slug ? { slug } : {} }
34428
- });
34429
- if (!slug) {
34430
- await runSponsoredTx({
34431
- keypair: agent.keypair,
34432
- actor: address,
34433
- prepareUrl: `${base}/agent/service/prepare`,
34434
- prepareBody: { address, mcpEndpoint: "" },
34435
- submitUrl: `${base}/agent/service/submit`
34436
- }).catch(() => void 0);
34437
- }
34438
- if (isJsonMode()) {
34439
- printJson({ address, removed: true });
34440
- return;
34441
- }
34442
- printBlank();
34443
- printSuccess("Service taken down.");
34444
- printBlank();
34445
- return;
34446
- }
34447
- if (!(opts.upstream && opts.price)) {
34448
- throw new Error("Both --upstream and --price are required (or use --remove).");
34449
- }
34450
- const price = Number.parseFloat(opts.price);
34451
- if (Number.isNaN(price) || price <= 0) {
34452
- throw new Error(`--price must be a positive number (got "${opts.price}").`);
34453
- }
34454
- const method = (opts.method ?? "POST").toUpperCase() === "GET" ? "GET" : "POST";
34455
- const headers = opts.header ?? {};
34456
- const ts = Date.now();
34457
- const bodyHash = createHash2("sha256").update(
34458
- `${opts.upstream}|${method}|${JSON.stringify(headers)}${slug ? `|${slug}` : ""}`
34459
- ).digest("hex");
34460
- const msg = `t2000-deploy:${ts}:${bodyHash}`;
34461
- const { signature } = await agent.keypair.signPersonalMessage(
34462
- new TextEncoder().encode(msg)
34463
- );
34464
- await fetchJson3(`${gateway}/deploy/config`, {
34465
- method: "POST",
34466
- body: {
34467
- address,
34468
- timestamp: ts,
34469
- signature,
34470
- upstreamUrl: opts.upstream,
34471
- method,
34472
- headers,
34473
- ...slug ? { slug } : {}
34474
- }
34475
- });
34476
- if (slug) {
34477
- if (isJsonMode()) {
34478
- printJson({ address, slug, upstream: opts.upstream, price });
34479
- return;
34480
- }
34481
- printBlank();
34482
- printSuccess(`Wrap config stored for service "${slug}".`);
34483
- printKeyValue("Wraps", opts.upstream);
34484
- printKeyValue("Buy URL", `${DEFAULT_RAIL}/commerce/pay/${address}/${slug}`);
34485
- printInfo(
34486
- `List it in the catalog: t2 agent services add --slug ${slug} --title \u2026 --description \u2026 --price ${opts.price}`
34487
- );
34488
- printBlank();
34489
- return;
34490
- }
34491
- const { digest } = await runSponsoredTx({
34492
- keypair: agent.keypair,
34493
- actor: address,
34494
- prepareUrl: `${base}/agent/service/prepare`,
34495
- prepareBody: {
34496
- address,
34497
- // The real, x402-callable buy endpoint (GET → 402 + requirements,
34498
- // pay → collect/deliver/forward). `/deploy/<addr>` was a phantom
34499
- // (no route → 404). Any x402 client can hit this URL.
34500
- mcpEndpoint: `${DEFAULT_RAIL}/commerce/pay/${address}`,
34501
- paymentMethods: ["x402"],
34502
- priceUsdc: opts.price,
34503
- ...category ? { category } : {}
34504
- },
34505
- submitUrl: `${base}/agent/service/submit`
34506
- });
34507
- if (isJsonMode()) {
34508
- printJson({ address, upstream: opts.upstream, price, digest });
34509
- return;
34510
- }
34511
- printBlank();
34512
- printSuccess("Service deployed \u2014 live + listed in the directory.");
34513
- printKeyValue("Wraps", opts.upstream);
34514
- printKeyValue("Price", `$${opts.price} USDC`);
34515
- if (category) {
34516
- printKeyValue("Category", category);
34517
- }
34518
- printKeyValue("Tx", String(digest));
34519
- printInfo(`Buyers: t2 agent pay ${truncateAddress(address)}`);
34520
- printBlank();
34521
- } catch (error) {
34522
- handleError(error);
34523
- }
34524
- }
34525
- );
34526
34155
  group.command("pay").argument("<seller>", "The seller agent's Sui address").description(
34527
34156
  "Pay a seller agent for a service (gateway-mediated, USDC). t2000 collects, keeps a small fee, and forwards the rest to the seller \u2014 with a receipt. [Agent Commerce]"
34528
34157
  ).option("--amount <usdc>", "Override the price (default: the seller's declared price)").option("--data <json>", "Service input forwarded to the seller's endpoint").option("--max-price <usdc>", "Max USDC to auto-approve (default 1.00, or --amount)").option(
34529
- "--service <slug>",
34530
- "Catalog service slug \u2014 buys ONE SKU of the seller's catalog (Store v2)"
34531
- ).option(
34532
34158
  "--gateway <url>",
34533
34159
  `Gateway base URL (default ${DEFAULT_GATEWAY})`
34534
34160
  ).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
@@ -34544,8 +34170,7 @@ Subcommands:
34544
34170
  const gateway = opts.gateway ?? DEFAULT_GATEWAY;
34545
34171
  const agent = await withAgent({ keyPath: opts.key });
34546
34172
  const resolvedSeller = seller.startsWith("0x") ? seller : (await agent.resolveRecipient(seller)).address;
34547
- const slugPath = opts.service ? `/${opts.service.trim().toLowerCase()}` : "";
34548
- const url = opts.amount ? `${gateway}/commerce/pay/${resolvedSeller}${slugPath}?amount=${encodeURIComponent(opts.amount)}` : `${gateway}/commerce/pay/${resolvedSeller}${slugPath}`;
34173
+ const url = opts.amount ? `${gateway}/commerce/pay/${resolvedSeller}?amount=${encodeURIComponent(opts.amount)}` : `${gateway}/commerce/pay/${resolvedSeller}`;
34549
34174
  const result = await agent.pay({
34550
34175
  url,
34551
34176
  method: "POST",
@@ -34614,7 +34239,7 @@ Subcommands:
34614
34239
  const gateway = opts.gateway ?? DEFAULT_GATEWAY;
34615
34240
  const agent = await withAgent({ keyPath: opts.key });
34616
34241
  const address = agent.address();
34617
- const stats = await fetchJson3(
34242
+ const stats = await fetchJson2(
34618
34243
  `${gateway}/commerce/stats/${address}`,
34619
34244
  { method: "GET" }
34620
34245
  );
@@ -34643,7 +34268,7 @@ Subcommands:
34643
34268
  const base = opts.api ?? DEFAULT_API_BASE4;
34644
34269
  const agent = await withAgent({ keyPath: opts.key });
34645
34270
  const address = agent.address();
34646
- const challenge = await fetchJson3(`${base}/agent/challenge`, {
34271
+ const challenge = await fetchJson2(`${base}/agent/challenge`, {
34647
34272
  method: "POST",
34648
34273
  body: { address }
34649
34274
  });
@@ -34655,7 +34280,7 @@ Subcommands:
34655
34280
  const message = new TextEncoder().encode(`${action}:${nonce}:${label}`);
34656
34281
  const { signature } = await agent.keypair.signPersonalMessage(message);
34657
34282
  const path2 = opts.release ? "/agent/handle/release" : "/agent/handle";
34658
- const res = await fetchJson3(`${base}${path2}`, {
34283
+ const res = await fetchJson2(`${base}${path2}`, {
34659
34284
  method: "POST",
34660
34285
  body: { address, label, nonce, signature }
34661
34286
  });
@@ -34695,8 +34320,8 @@ function firstLine(text, max = 76) {
34695
34320
  }
34696
34321
  function registerAgents(program3) {
34697
34322
  program3.command("agents").argument("[address]", "Show one agent\u2019s full listing (profile + reputation)").description(
34698
- "Browse the agent store (agents.t2000.ai): priced services from the live directory, or one agent\u2019s full listing. Buy with `t2 agent pay <address>`. [Agent Commerce]"
34699
- ).option("--category <category>", "Filter the list by store category").option("--all", "Include agents without a priced service").option("--limit <n>", "Max rows (default: all)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
34323
+ "Look up the agent directory (agents.t2000.ai): priced services from the live registry, or one agent\u2019s full listing. Buy with `t2 agent pay <address>`. [Agent Commerce]"
34324
+ ).option("--category <category>", "Filter the list by category").option("--all", "Include agents without a priced service").option("--limit <n>", "Max rows (default: all)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
34700
34325
  async (address, opts) => {
34701
34326
  try {
34702
34327
  const base = opts.api ?? DEFAULT_API_BASE5;
@@ -34752,7 +34377,7 @@ function registerAgents(program3) {
34752
34377
  }
34753
34378
  printBlank();
34754
34379
  printHeader(
34755
- `Agent store \u2014 ${agents.length} ${opts.all ? "agents" : "priced services"}${opts.category ? ` in ${opts.category}` : ""}`
34380
+ `Agent directory \u2014 ${agents.length} ${opts.all ? "agents" : "priced services"}${opts.category ? ` in ${opts.category}` : ""}`
34756
34381
  );
34757
34382
  for (const a of agents) {
34758
34383
  const price = a.priceUsdc ? formatUsd(Number.parseFloat(a.priceUsdc)).padStart(6) : " \u2014";
@@ -34792,7 +34417,7 @@ Examples:
34792
34417
  $ t2 models List the Private API model catalog
34793
34418
  $ t2 pay <url> --estimate Preview an x402 service's price + input schema (no payment)
34794
34419
  $ t2 services search "image" Discover x402 services in the gateway catalog
34795
- $ t2 agents Browse the agent store (agents.t2000.ai)
34420
+ $ t2 agents Look up the agent directory (agents.t2000.ai)
34796
34421
  $ t2 agent pay <address> Buy an agent's service (escrowed, auto-refund on failure)
34797
34422
  $ t2 limit set --daily 100 Change the daily spend cap (default $100/day)
34798
34423
  $ t2 mcp install Connect Claude / Cursor / Windsurf