@t2000/cli 6.0.0 → 8.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-
|
|
33125
|
+
mod3 = await import("./dist-BOOS6EPV.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";
|
|
@@ -33630,7 +33627,7 @@ function registerAgentCreate(group) {
|
|
|
33630
33627
|
"Create an agent in one pass \u2014 wallet + on-chain Agent ID + profile (+ optional owner link). Sponsored, gasless."
|
|
33631
33628
|
).requiredOption("--name <name>", "Display name (shown in the store)").option("--description <text>", "Short description (what it does, for whom)").option(
|
|
33632
33629
|
"--category <category>",
|
|
33633
|
-
`
|
|
33630
|
+
`Directory category: ${AGENT_CATEGORIES.join(" | ")}`
|
|
33634
33631
|
).option(
|
|
33635
33632
|
"--owner <address>",
|
|
33636
33633
|
"Propose a Passport owner (confirm at agents.t2000.ai \u2192 My agents)"
|
|
@@ -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("
|
|
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(" agents.t2000.ai/skills # give it skills to act on Sui");
|
|
33978
33746
|
printBlank();
|
|
33979
33747
|
} catch (error) {
|
|
33980
33748
|
handleError(error);
|
|
@@ -33984,36 +33752,6 @@ function registerAgentServices(agentGroup, defaults) {
|
|
|
33984
33752
|
|
|
33985
33753
|
// src/commands/agent/index.ts
|
|
33986
33754
|
var DEFAULT_API_BASE4 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
33987
|
-
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
|
-
var AGENT_CATEGORIES2 = [
|
|
33990
|
-
"ai-models",
|
|
33991
|
-
"data-feeds",
|
|
33992
|
-
"finance",
|
|
33993
|
-
"research",
|
|
33994
|
-
"dev-tools",
|
|
33995
|
-
"creative",
|
|
33996
|
-
"other"
|
|
33997
|
-
];
|
|
33998
|
-
function normalizeCategory(input) {
|
|
33999
|
-
if (input === void 0) {
|
|
34000
|
-
return;
|
|
34001
|
-
}
|
|
34002
|
-
const c = input.trim().toLowerCase();
|
|
34003
|
-
if (!AGENT_CATEGORIES2.includes(c)) {
|
|
34004
|
-
throw new Error(
|
|
34005
|
-
`--category must be one of: ${AGENT_CATEGORIES2.join(", ")} (got "${input}").`
|
|
34006
|
-
);
|
|
34007
|
-
}
|
|
34008
|
-
return c;
|
|
34009
|
-
}
|
|
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
33755
|
function normalizeTopupAsset(input) {
|
|
34018
33756
|
return input?.toLowerCase() === "usdsui" ? "USDsui" : "USDC";
|
|
34019
33757
|
}
|
|
@@ -34023,19 +33761,19 @@ async function fundCredit(agent, base, amountStr, assetOpt) {
|
|
|
34023
33761
|
throw new Error(`amount must be a positive number (got "${amountStr}").`);
|
|
34024
33762
|
}
|
|
34025
33763
|
const asset = normalizeTopupAsset(assetOpt);
|
|
34026
|
-
const cfg = await
|
|
33764
|
+
const cfg = await fetchJson2(`${base}/agent/topup`, { method: "GET" });
|
|
34027
33765
|
const treasury = cfg.treasury;
|
|
34028
33766
|
if (!treasury) {
|
|
34029
33767
|
throw new Error("Could not resolve the t2000 treasury address.");
|
|
34030
33768
|
}
|
|
34031
33769
|
const sent = await agent.send({ to: treasury, amount, asset });
|
|
34032
|
-
const topup = await
|
|
33770
|
+
const topup = await fetchJson2(`${base}/agent/topup`, {
|
|
34033
33771
|
method: "POST",
|
|
34034
33772
|
body: { address: agent.address(), digest: sent.tx }
|
|
34035
33773
|
});
|
|
34036
33774
|
return { amount, asset, balanceUsd: topup.balanceUsd };
|
|
34037
33775
|
}
|
|
34038
|
-
async function
|
|
33776
|
+
async function fetchJson2(url, init) {
|
|
34039
33777
|
const res = await fetch(url, {
|
|
34040
33778
|
method: init.method,
|
|
34041
33779
|
headers: init.body ? { "Content-Type": "application/json" } : void 0,
|
|
@@ -34058,12 +33796,9 @@ Subcommands:
|
|
|
34058
33796
|
$ t2 agent onboard --fund 5 Fund 5 USDC \u2192 mint an API key (ready to call)
|
|
34059
33797
|
$ t2 agent onboard --fund 5 --asset USDsui
|
|
34060
33798
|
$ 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)
|
|
34063
33799
|
`
|
|
34064
33800
|
);
|
|
34065
33801
|
registerAgentCreate(group);
|
|
34066
|
-
registerAgentServices(group, { apiBase: DEFAULT_API_BASE4 });
|
|
34067
33802
|
group.command("onboard").description(
|
|
34068
33803
|
"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
33804
|
).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 +33815,7 @@ Subcommands:
|
|
|
34080
33815
|
);
|
|
34081
33816
|
}
|
|
34082
33817
|
}
|
|
34083
|
-
const challenge = await
|
|
33818
|
+
const challenge = await fetchJson2(`${base}/agent/challenge`, {
|
|
34084
33819
|
method: "POST",
|
|
34085
33820
|
body: { address }
|
|
34086
33821
|
});
|
|
@@ -34090,7 +33825,7 @@ Subcommands:
|
|
|
34090
33825
|
}
|
|
34091
33826
|
const message = new TextEncoder().encode(`t2000-agent-keys:${nonce}`);
|
|
34092
33827
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
34093
|
-
const minted = await
|
|
33828
|
+
const minted = await fetchJson2(`${base}/agent/keys`, {
|
|
34094
33829
|
method: "POST",
|
|
34095
33830
|
body: { address, nonce, signature }
|
|
34096
33831
|
});
|
|
@@ -34287,7 +34022,7 @@ Subcommands:
|
|
|
34287
34022
|
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34288
34023
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34289
34024
|
const address = agent.address();
|
|
34290
|
-
const challenge = await
|
|
34025
|
+
const challenge = await fetchJson2(`${base}/agent/challenge`, {
|
|
34291
34026
|
method: "POST",
|
|
34292
34027
|
body: { address }
|
|
34293
34028
|
});
|
|
@@ -34297,7 +34032,7 @@ Subcommands:
|
|
|
34297
34032
|
}
|
|
34298
34033
|
const message = new TextEncoder().encode(`t2000-agent-profile:${nonce}`);
|
|
34299
34034
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
34300
|
-
await
|
|
34035
|
+
await fetchJson2(`${base}/agent/profile`, {
|
|
34301
34036
|
method: "POST",
|
|
34302
34037
|
body: {
|
|
34303
34038
|
address,
|
|
@@ -34323,318 +34058,6 @@ Subcommands:
|
|
|
34323
34058
|
}
|
|
34324
34059
|
}
|
|
34325
34060
|
);
|
|
34326
|
-
group.command("service").description(
|
|
34327
|
-
"Declare this agent's paid service \u2014 an MCP endpoint + accepted payment methods (e.g. x402). Sponsored, gasless. Lights up Service / x402 in the directory."
|
|
34328
|
-
).option("--mcp-endpoint <url>", "Your agent service endpoint (https)").option(
|
|
34329
|
-
"--payment-methods <list>",
|
|
34330
|
-
'Comma-separated methods you accept, e.g. "x402"'
|
|
34331
|
-
).option("--price <usdc>", "Price per call in USDC (e.g. 0.02) \u2014 buyers pay this").option(
|
|
34332
|
-
"--category <category>",
|
|
34333
|
-
`Storefront category: ${AGENT_CATEGORIES2.join(" | ")}`
|
|
34334
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
34335
|
-
async (opts) => {
|
|
34336
|
-
try {
|
|
34337
|
-
if (opts.mcpEndpoint === void 0 && opts.paymentMethods === void 0 && opts.price === void 0 && opts.category === void 0) {
|
|
34338
|
-
throw new Error(
|
|
34339
|
-
'Provide at least one of --mcp-endpoint, --payment-methods, --price, --category. (Pass --mcp-endpoint "" to clear your endpoint.)'
|
|
34340
|
-
);
|
|
34341
|
-
}
|
|
34342
|
-
if (opts.price !== void 0) {
|
|
34343
|
-
const p = Number.parseFloat(opts.price);
|
|
34344
|
-
if (Number.isNaN(p) || p <= 0) {
|
|
34345
|
-
throw new Error(`--price must be a positive number (got "${opts.price}").`);
|
|
34346
|
-
}
|
|
34347
|
-
}
|
|
34348
|
-
const category = normalizeCategory(opts.category);
|
|
34349
|
-
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34350
|
-
const agent = await withAgent({ keyPath: opts.key });
|
|
34351
|
-
const address = agent.address();
|
|
34352
|
-
const prepareBody = { address };
|
|
34353
|
-
if (opts.mcpEndpoint !== void 0) {
|
|
34354
|
-
prepareBody.mcpEndpoint = opts.mcpEndpoint;
|
|
34355
|
-
}
|
|
34356
|
-
if (opts.paymentMethods !== void 0) {
|
|
34357
|
-
prepareBody.paymentMethods = opts.paymentMethods.split(",").map((s) => s.trim()).filter(Boolean);
|
|
34358
|
-
}
|
|
34359
|
-
if (opts.price !== void 0) {
|
|
34360
|
-
prepareBody.priceUsdc = opts.price;
|
|
34361
|
-
}
|
|
34362
|
-
if (category !== void 0) {
|
|
34363
|
-
prepareBody.category = category;
|
|
34364
|
-
}
|
|
34365
|
-
const { digest } = await runSponsoredTx({
|
|
34366
|
-
keypair: agent.keypair,
|
|
34367
|
-
actor: address,
|
|
34368
|
-
prepareUrl: `${base}/agent/service/prepare`,
|
|
34369
|
-
prepareBody,
|
|
34370
|
-
submitUrl: `${base}/agent/service/submit`
|
|
34371
|
-
});
|
|
34372
|
-
if (isJsonMode()) {
|
|
34373
|
-
printJson({ address, updated: true, digest });
|
|
34374
|
-
return;
|
|
34375
|
-
}
|
|
34376
|
-
printBlank();
|
|
34377
|
-
printSuccess("Service declared \u2014 showing in the directory.");
|
|
34378
|
-
if (opts.mcpEndpoint) {
|
|
34379
|
-
printKeyValue("MCP endpoint", opts.mcpEndpoint);
|
|
34380
|
-
}
|
|
34381
|
-
if (opts.paymentMethods) {
|
|
34382
|
-
printKeyValue("Payment methods", opts.paymentMethods);
|
|
34383
|
-
}
|
|
34384
|
-
if (opts.price) {
|
|
34385
|
-
printKeyValue("Price", `$${opts.price} USDC`);
|
|
34386
|
-
}
|
|
34387
|
-
if (category) {
|
|
34388
|
-
printKeyValue("Category", category);
|
|
34389
|
-
}
|
|
34390
|
-
printKeyValue("Tx", String(digest));
|
|
34391
|
-
printBlank();
|
|
34392
|
-
} catch (error) {
|
|
34393
|
-
handleError(error);
|
|
34394
|
-
}
|
|
34395
|
-
}
|
|
34396
|
-
);
|
|
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
|
-
group.command("pay").argument("<seller>", "The seller agent's Sui address").description(
|
|
34527
|
-
"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
|
-
).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
|
-
"--gateway <url>",
|
|
34533
|
-
`Gateway base URL (default ${DEFAULT_GATEWAY})`
|
|
34534
|
-
).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
|
|
34535
|
-
async (seller, opts) => {
|
|
34536
|
-
try {
|
|
34537
|
-
if (opts.amount !== void 0) {
|
|
34538
|
-
const a = Number.parseFloat(opts.amount);
|
|
34539
|
-
if (Number.isNaN(a) || a <= 0) {
|
|
34540
|
-
throw new Error(`--amount must be a positive number (got "${opts.amount}").`);
|
|
34541
|
-
}
|
|
34542
|
-
}
|
|
34543
|
-
const maxPrice = opts.maxPrice ? Number.parseFloat(opts.maxPrice) : opts.amount ? Number.parseFloat(opts.amount) : 1;
|
|
34544
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY;
|
|
34545
|
-
const agent = await withAgent({ keyPath: opts.key });
|
|
34546
|
-
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}`;
|
|
34549
|
-
const result = await agent.pay({
|
|
34550
|
-
url,
|
|
34551
|
-
method: "POST",
|
|
34552
|
-
body: opts.data,
|
|
34553
|
-
maxPrice,
|
|
34554
|
-
force: opts.force
|
|
34555
|
-
});
|
|
34556
|
-
const body2 = result.body;
|
|
34557
|
-
if (result.status >= 400) {
|
|
34558
|
-
throw new Error(
|
|
34559
|
-
`${body2?.error ?? `Request failed (HTTP ${result.status})`}${result.paid ? "" : " \u2014 nothing was paid."}`
|
|
34560
|
-
);
|
|
34561
|
-
}
|
|
34562
|
-
const receipt = body2?.receipt;
|
|
34563
|
-
const chargedMicros = receipt?.chargedMicros ?? receipt?.grossMicros;
|
|
34564
|
-
const paidUsd = typeof chargedMicros === "number" ? chargedMicros / 1e6 : opts.amount ? Number.parseFloat(opts.amount) : result.cost ?? 0;
|
|
34565
|
-
if (isJsonMode()) {
|
|
34566
|
-
printJson({
|
|
34567
|
-
seller: resolvedSeller,
|
|
34568
|
-
amount: paidUsd,
|
|
34569
|
-
paid: result.paid,
|
|
34570
|
-
cost: result.cost,
|
|
34571
|
-
receipt,
|
|
34572
|
-
response: body2?.response
|
|
34573
|
-
});
|
|
34574
|
-
return;
|
|
34575
|
-
}
|
|
34576
|
-
printBlank();
|
|
34577
|
-
printSuccess(
|
|
34578
|
-
`Paid ${formatUsd(paidUsd)} to ${seller.startsWith("0x") ? truncateAddress(seller) : `${seller} (${truncateAddress(resolvedSeller)})`}`
|
|
34579
|
-
);
|
|
34580
|
-
if (receipt) {
|
|
34581
|
-
if (typeof receipt.refundMicros === "number" && receipt.refundMicros > 0 && typeof receipt.authorizedMicros === "number") {
|
|
34582
|
-
printKeyValue(
|
|
34583
|
-
"Authorized",
|
|
34584
|
-
`$${(receipt.authorizedMicros / 1e6).toFixed(6)}`
|
|
34585
|
-
);
|
|
34586
|
-
printKeyValue("Charged", `$${paidUsd.toFixed(6)}`);
|
|
34587
|
-
printKeyValue("Refunded", `$${(receipt.refundMicros / 1e6).toFixed(6)}`);
|
|
34588
|
-
}
|
|
34589
|
-
if (typeof receipt.netMicros === "number") {
|
|
34590
|
-
printKeyValue("Seller received", `$${(receipt.netMicros / 1e6).toFixed(6)}`);
|
|
34591
|
-
}
|
|
34592
|
-
if (typeof receipt.feeMicros === "number") {
|
|
34593
|
-
printKeyValue("Facilitator fee", `$${(receipt.feeMicros / 1e6).toFixed(6)}`);
|
|
34594
|
-
}
|
|
34595
|
-
if (receipt.forwardDigest) {
|
|
34596
|
-
printKeyValue("Settlement tx", receipt.forwardDigest);
|
|
34597
|
-
}
|
|
34598
|
-
}
|
|
34599
|
-
if (body2?.response !== void 0) {
|
|
34600
|
-
printBlank();
|
|
34601
|
-
printInfo("Service response:");
|
|
34602
|
-
printLine(JSON.stringify(body2.response, null, 2));
|
|
34603
|
-
}
|
|
34604
|
-
printBlank();
|
|
34605
|
-
} catch (error) {
|
|
34606
|
-
handleError(error);
|
|
34607
|
-
}
|
|
34608
|
-
}
|
|
34609
|
-
);
|
|
34610
|
-
group.command("earnings").description(
|
|
34611
|
-
"Your sales as a seller \u2014 count, USDC earned (net), and unique buyers, from the on-chain settlement ledger. [Agent Commerce]"
|
|
34612
|
-
).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
|
|
34613
|
-
try {
|
|
34614
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY;
|
|
34615
|
-
const agent = await withAgent({ keyPath: opts.key });
|
|
34616
|
-
const address = agent.address();
|
|
34617
|
-
const stats = await fetchJson3(
|
|
34618
|
-
`${gateway}/commerce/stats/${address}`,
|
|
34619
|
-
{ method: "GET" }
|
|
34620
|
-
);
|
|
34621
|
-
if (isJsonMode()) {
|
|
34622
|
-
printJson({ address, ...stats });
|
|
34623
|
-
return;
|
|
34624
|
-
}
|
|
34625
|
-
printBlank();
|
|
34626
|
-
printSuccess(`Earnings for ${truncateAddress(address)}`);
|
|
34627
|
-
printKeyValue("Sales", String(stats.sales ?? 0));
|
|
34628
|
-
printKeyValue("Earned (net)", `$${(stats.volumeUsd ?? 0).toFixed(6)} USDC`);
|
|
34629
|
-
printKeyValue("Unique buyers", String(stats.buyers ?? 0));
|
|
34630
|
-
if (stats.lastSaleAt) {
|
|
34631
|
-
printKeyValue("Last sale", new Date(stats.lastSaleAt).toISOString());
|
|
34632
|
-
}
|
|
34633
|
-
printBlank();
|
|
34634
|
-
} catch (error) {
|
|
34635
|
-
handleError(error);
|
|
34636
|
-
}
|
|
34637
|
-
});
|
|
34638
34061
|
group.command("handle").argument("<label>", "Handle label (3\u201320 chars: lowercase a\u2013z, 0\u20139, hyphens)").description(
|
|
34639
34062
|
"Claim <label>.agent-id.sui \u2192 this wallet (custody-minted, gasless). Use --release to give it up."
|
|
34640
34063
|
).option("--release", "Release (revoke) this handle instead of claiming it").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
@@ -34643,7 +34066,7 @@ Subcommands:
|
|
|
34643
34066
|
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34644
34067
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34645
34068
|
const address = agent.address();
|
|
34646
|
-
const challenge = await
|
|
34069
|
+
const challenge = await fetchJson2(`${base}/agent/challenge`, {
|
|
34647
34070
|
method: "POST",
|
|
34648
34071
|
body: { address }
|
|
34649
34072
|
});
|
|
@@ -34655,7 +34078,7 @@ Subcommands:
|
|
|
34655
34078
|
const message = new TextEncoder().encode(`${action}:${nonce}:${label}`);
|
|
34656
34079
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
34657
34080
|
const path2 = opts.release ? "/agent/handle/release" : "/agent/handle";
|
|
34658
|
-
const res = await
|
|
34081
|
+
const res = await fetchJson2(`${base}${path2}`, {
|
|
34659
34082
|
method: "POST",
|
|
34660
34083
|
body: { address, label, nonce, signature }
|
|
34661
34084
|
});
|
|
@@ -34694,9 +34117,9 @@ function firstLine(text, max = 76) {
|
|
|
34694
34117
|
return line.length > max ? `${line.slice(0, max - 1)}\u2026` : line;
|
|
34695
34118
|
}
|
|
34696
34119
|
function registerAgents(program3) {
|
|
34697
|
-
program3.command("agents").argument("[address]", "Show one agent\u2019s
|
|
34698
|
-
"
|
|
34699
|
-
).option("--category <category>", "Filter the list by
|
|
34120
|
+
program3.command("agents").argument("[address]", "Show one agent\u2019s identity profile").description(
|
|
34121
|
+
"Look up the agent directory (agents.t2000.ai): registered on-chain Agent IDs. Read-only. [Agent ID]"
|
|
34122
|
+
).option("--category <category>", "Filter the list by category").option("--limit <n>", "Max rows (default: all)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
|
|
34700
34123
|
async (address, opts) => {
|
|
34701
34124
|
try {
|
|
34702
34125
|
const base = opts.api ?? DEFAULT_API_BASE5;
|
|
@@ -34706,30 +34129,20 @@ function registerAgents(program3) {
|
|
|
34706
34129
|
printJson(profile);
|
|
34707
34130
|
return;
|
|
34708
34131
|
}
|
|
34709
|
-
const rep = profile.reputation;
|
|
34710
34132
|
printBlank();
|
|
34711
34133
|
printHeader(profile.name ?? truncateAddress(profile.address));
|
|
34712
34134
|
printKeyValue("Address", profile.address);
|
|
34713
|
-
if (profile.
|
|
34714
|
-
printKeyValue(
|
|
34715
|
-
"Price",
|
|
34716
|
-
`${formatUsd(Number.parseFloat(profile.priceUsdc))} / call${profile.category ? ` \xB7 ${profile.category}` : ""}`
|
|
34717
|
-
);
|
|
34135
|
+
if (profile.numericId != null) {
|
|
34136
|
+
printKeyValue("Agent ID", `#${profile.numericId}`);
|
|
34718
34137
|
}
|
|
34719
34138
|
if (profile.description) {
|
|
34720
34139
|
printKeyValue("About", firstLine(profile.description, 90));
|
|
34721
34140
|
}
|
|
34722
|
-
if (
|
|
34723
|
-
printKeyValue(
|
|
34724
|
-
"Verified on the rail",
|
|
34725
|
-
`${rep.sales ?? 0} sold \xB7 ${rep.buyers ?? 0} buyer${(rep.buyers ?? 0) === 1 ? "" : "s"} \xB7 ${formatUsd(rep.volumeUsd ?? 0)} settled${typeof rep.deliveredRate === "number" ? ` \xB7 ${Math.round(rep.deliveredRate * 100)}% delivered` : ""}`
|
|
34726
|
-
);
|
|
34141
|
+
if (profile.owner) {
|
|
34142
|
+
printKeyValue("Owner", truncateAddress(profile.owner));
|
|
34727
34143
|
}
|
|
34728
34144
|
printBlank();
|
|
34729
|
-
|
|
34730
|
-
printInfo(`Buy it: t2 agent pay ${profile.address}`);
|
|
34731
|
-
}
|
|
34732
|
-
printInfo(`Listing: https://agents.t2000.ai/${profile.address}`);
|
|
34145
|
+
printInfo(`Profile: https://agents.t2000.ai/${profile.numericId ?? profile.address}`);
|
|
34733
34146
|
printBlank();
|
|
34734
34147
|
return;
|
|
34735
34148
|
}
|
|
@@ -34738,9 +34151,6 @@ function registerAgents(program3) {
|
|
|
34738
34151
|
`${base}/agents?limit=100`
|
|
34739
34152
|
);
|
|
34740
34153
|
let agents = (data.agents ?? []).filter((a) => a.active !== false);
|
|
34741
|
-
if (!opts.all) {
|
|
34742
|
-
agents = agents.filter((a) => a.service && a.priceUsdc);
|
|
34743
|
-
}
|
|
34744
34154
|
if (opts.category) {
|
|
34745
34155
|
const cat = opts.category.trim().toLowerCase();
|
|
34746
34156
|
agents = agents.filter((a) => a.category?.toLowerCase() === cat);
|
|
@@ -34752,17 +34162,16 @@ function registerAgents(program3) {
|
|
|
34752
34162
|
}
|
|
34753
34163
|
printBlank();
|
|
34754
34164
|
printHeader(
|
|
34755
|
-
`Agent
|
|
34165
|
+
`Agent directory \u2014 ${agents.length} agents${opts.category ? ` in ${opts.category}` : ""}`
|
|
34756
34166
|
);
|
|
34757
34167
|
for (const a of agents) {
|
|
34758
|
-
const price = a.priceUsdc ? formatUsd(Number.parseFloat(a.priceUsdc)).padStart(6) : " \u2014";
|
|
34759
34168
|
printLine(
|
|
34760
|
-
`
|
|
34169
|
+
` #${String(a.numericId ?? "\u2014").padEnd(4)} ${(a.name ?? truncateAddress(a.address)).padEnd(24).slice(0, 24)} ${firstLine(a.description, 40)}`
|
|
34761
34170
|
);
|
|
34762
|
-
printLine(`
|
|
34171
|
+
printLine(` ${a.address}`);
|
|
34763
34172
|
}
|
|
34764
34173
|
printBlank();
|
|
34765
|
-
printInfo("Detail: t2 agents <address>
|
|
34174
|
+
printInfo("Detail: t2 agents <address>");
|
|
34766
34175
|
printBlank();
|
|
34767
34176
|
} catch (error) {
|
|
34768
34177
|
handleError(error);
|
|
@@ -34792,8 +34201,7 @@ Examples:
|
|
|
34792
34201
|
$ t2 models List the Private API model catalog
|
|
34793
34202
|
$ t2 pay <url> --estimate Preview an x402 service's price + input schema (no payment)
|
|
34794
34203
|
$ t2 services search "image" Discover x402 services in the gateway catalog
|
|
34795
|
-
$ t2 agents
|
|
34796
|
-
$ t2 agent pay <address> Buy an agent's service (escrowed, auto-refund on failure)
|
|
34204
|
+
$ t2 agents Look up the agent directory (agents.t2000.ai)
|
|
34797
34205
|
$ t2 limit set --daily 100 Change the daily spend cap (default $100/day)
|
|
34798
34206
|
$ t2 mcp install Connect Claude / Cursor / Windsurf
|
|
34799
34207
|
$ t2 skills install Install skills as local SKILL.md files`);
|