@t2000/cli 9.12.0 → 9.14.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/README.md +4 -1
- package/dist/{chunk-KHOU3HJU.js → chunk-W2YJBW55.js} +91 -1
- package/dist/chunk-W2YJBW55.js.map +1 -0
- package/dist/{dist-PAYZWJCN.js → dist-ST4GSMNB.js} +590 -24
- package/dist/{dist-PAYZWJCN.js.map → dist-ST4GSMNB.js.map} +1 -1
- package/dist/{dist-24ZYDGZH.js → dist-XPUF4ETZ.js} +12 -2
- package/dist/index.js +40 -82
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-KHOU3HJU.js.map +0 -1
- /package/dist/{dist-24ZYDGZH.js.map → dist-XPUF4ETZ.js.map} +0 -0
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
CLOCK_ID,
|
|
13
13
|
COIN_REGISTRY,
|
|
14
14
|
DEFAULT_API_BASE,
|
|
15
|
+
DEFAULT_COMMERCE_API_BASE,
|
|
15
16
|
DEFAULT_GRPC_URL,
|
|
16
17
|
DEFAULT_NETWORK,
|
|
17
18
|
ETH_TYPE,
|
|
@@ -96,6 +97,7 @@ import {
|
|
|
96
97
|
extractTxSender,
|
|
97
98
|
fallbackLabel,
|
|
98
99
|
fetchAllCoins,
|
|
100
|
+
fetchOffering,
|
|
99
101
|
findSwapRoute,
|
|
100
102
|
formatAssetAmount,
|
|
101
103
|
formatSui,
|
|
@@ -107,6 +109,7 @@ import {
|
|
|
107
109
|
getDecimals,
|
|
108
110
|
getDecimalsForCoinType,
|
|
109
111
|
getJob,
|
|
112
|
+
getJobSpec,
|
|
110
113
|
getLimits,
|
|
111
114
|
getSponsoredSwapProviders,
|
|
112
115
|
getSuiClient,
|
|
@@ -119,6 +122,7 @@ import {
|
|
|
119
122
|
jobActionsFor,
|
|
120
123
|
keypairFromPrivateKey,
|
|
121
124
|
listModels,
|
|
125
|
+
listOfferings,
|
|
122
126
|
loadKey,
|
|
123
127
|
looksLikeSuiNs,
|
|
124
128
|
mapMoveAbortCode,
|
|
@@ -135,6 +139,7 @@ import {
|
|
|
135
139
|
preflightPay,
|
|
136
140
|
preflightSend,
|
|
137
141
|
preflightSwap,
|
|
142
|
+
putJobSpec,
|
|
138
143
|
queryBalance,
|
|
139
144
|
queryHistory,
|
|
140
145
|
queryTransaction,
|
|
@@ -166,7 +171,7 @@ import {
|
|
|
166
171
|
verifyReceipt,
|
|
167
172
|
walletExists,
|
|
168
173
|
writeLimitsFile
|
|
169
|
-
} from "./chunk-
|
|
174
|
+
} from "./chunk-W2YJBW55.js";
|
|
170
175
|
import "./chunk-634W6JCI.js";
|
|
171
176
|
import "./chunk-BHQGGFE6.js";
|
|
172
177
|
import "./chunk-GCC33SG5.js";
|
|
@@ -192,6 +197,7 @@ export {
|
|
|
192
197
|
CLOCK_ID,
|
|
193
198
|
COIN_REGISTRY,
|
|
194
199
|
DEFAULT_API_BASE,
|
|
200
|
+
DEFAULT_COMMERCE_API_BASE,
|
|
195
201
|
DEFAULT_GRPC_URL,
|
|
196
202
|
DEFAULT_NETWORK,
|
|
197
203
|
ETH_TYPE,
|
|
@@ -276,6 +282,7 @@ export {
|
|
|
276
282
|
extractTxSender,
|
|
277
283
|
fallbackLabel,
|
|
278
284
|
fetchAllCoins,
|
|
285
|
+
fetchOffering,
|
|
279
286
|
findSwapRoute,
|
|
280
287
|
formatAssetAmount,
|
|
281
288
|
formatSui,
|
|
@@ -287,6 +294,7 @@ export {
|
|
|
287
294
|
getDecimals,
|
|
288
295
|
getDecimalsForCoinType,
|
|
289
296
|
getJob,
|
|
297
|
+
getJobSpec,
|
|
290
298
|
getLimits,
|
|
291
299
|
getSponsoredSwapProviders,
|
|
292
300
|
getSuiClient,
|
|
@@ -299,6 +307,7 @@ export {
|
|
|
299
307
|
jobActionsFor,
|
|
300
308
|
keypairFromPrivateKey,
|
|
301
309
|
listModels,
|
|
310
|
+
listOfferings,
|
|
302
311
|
loadKey,
|
|
303
312
|
looksLikeSuiNs,
|
|
304
313
|
mapMoveAbortCode,
|
|
@@ -315,6 +324,7 @@ export {
|
|
|
315
324
|
preflightPay,
|
|
316
325
|
preflightSend,
|
|
317
326
|
preflightSwap,
|
|
327
|
+
putJobSpec,
|
|
318
328
|
queryBalance,
|
|
319
329
|
queryHistory,
|
|
320
330
|
queryTransaction,
|
|
@@ -347,4 +357,4 @@ export {
|
|
|
347
357
|
walletExists,
|
|
348
358
|
writeLimitsFile
|
|
349
359
|
};
|
|
350
|
-
//# sourceMappingURL=dist-
|
|
360
|
+
//# sourceMappingURL=dist-XPUF4ETZ.js.map
|
package/dist/index.js
CHANGED
|
@@ -7,16 +7,19 @@ import {
|
|
|
7
7
|
MAX_JOB_USDC,
|
|
8
8
|
T2000,
|
|
9
9
|
clearLimits,
|
|
10
|
+
fetchOffering,
|
|
10
11
|
formatUsd,
|
|
11
12
|
generateKeypair,
|
|
12
13
|
getAddress,
|
|
13
14
|
getJob,
|
|
15
|
+
getJobSpec,
|
|
14
16
|
getLimits,
|
|
15
17
|
getSuiClient,
|
|
16
18
|
hasLimits,
|
|
17
19
|
jobActionsFor,
|
|
18
20
|
keypairFromPrivateKey,
|
|
19
21
|
listModels,
|
|
22
|
+
putJobSpec,
|
|
20
23
|
saveBech32,
|
|
21
24
|
saveKey,
|
|
22
25
|
setLimits,
|
|
@@ -25,7 +28,7 @@ import {
|
|
|
25
28
|
verifyJobForSeller,
|
|
26
29
|
verifyReceipt,
|
|
27
30
|
walletExists
|
|
28
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-W2YJBW55.js";
|
|
29
32
|
import "./chunk-634W6JCI.js";
|
|
30
33
|
import "./chunk-BHQGGFE6.js";
|
|
31
34
|
import "./chunk-GCC33SG5.js";
|
|
@@ -22278,7 +22281,7 @@ async function runEstimate(url, opts) {
|
|
|
22278
22281
|
let req = accepts.find((a) => a.scheme === "exact" && a.network?.startsWith("sui:")) ?? accepts[0];
|
|
22279
22282
|
let dialect = "x402";
|
|
22280
22283
|
if (!req) {
|
|
22281
|
-
const { parseMppSuiChallenge } = await import("./dist-
|
|
22284
|
+
const { parseMppSuiChallenge } = await import("./dist-XPUF4ETZ.js");
|
|
22282
22285
|
const challenge = await parseMppSuiChallenge(response);
|
|
22283
22286
|
if (!challenge) {
|
|
22284
22287
|
throw new Error(
|
|
@@ -23370,7 +23373,7 @@ function registerMcpStart(parent) {
|
|
|
23370
23373
|
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) => {
|
|
23371
23374
|
let mod;
|
|
23372
23375
|
try {
|
|
23373
|
-
mod = await import("./dist-
|
|
23376
|
+
mod = await import("./dist-ST4GSMNB.js");
|
|
23374
23377
|
} catch {
|
|
23375
23378
|
console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
|
|
23376
23379
|
process.exit(1);
|
|
@@ -24512,11 +24515,10 @@ function registerCheck(program3) {
|
|
|
24512
24515
|
|
|
24513
24516
|
// src/commands/job.ts
|
|
24514
24517
|
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
24515
|
-
import { createHash
|
|
24518
|
+
import { createHash } from "crypto";
|
|
24516
24519
|
import { readFile as readFile3 } from "fs/promises";
|
|
24517
24520
|
|
|
24518
24521
|
// src/lib/offerings.ts
|
|
24519
|
-
import { createHash } from "crypto";
|
|
24520
24522
|
async function fetchJson3(url, init) {
|
|
24521
24523
|
const res = await fetch(url, {
|
|
24522
24524
|
method: init?.method ?? "GET",
|
|
@@ -24531,51 +24533,6 @@ async function fetchJson3(url, init) {
|
|
|
24531
24533
|
}
|
|
24532
24534
|
return json;
|
|
24533
24535
|
}
|
|
24534
|
-
async function fetchOffering(base, agent, slug) {
|
|
24535
|
-
const json = await fetchJson3(
|
|
24536
|
-
`${base}/offerings?agent=${encodeURIComponent(agent)}`
|
|
24537
|
-
);
|
|
24538
|
-
const rows = json.offerings ?? [];
|
|
24539
|
-
const match = rows.find((o) => o.slug === slug.trim().toLowerCase());
|
|
24540
|
-
if (!match) {
|
|
24541
|
-
const live = rows.filter((o) => !o.retired).map((o) => o.slug);
|
|
24542
|
-
throw new Error(
|
|
24543
|
-
`Agent ${truncateAddress(agent)} has no offering "${slug}".` + (live.length > 0 ? ` Live offerings: ${live.join(", ")}` : "")
|
|
24544
|
-
);
|
|
24545
|
-
}
|
|
24546
|
-
if (match.retired) {
|
|
24547
|
-
throw new Error(
|
|
24548
|
-
`Offering "${slug}" is retired \u2014 the seller no longer sells it.`
|
|
24549
|
-
);
|
|
24550
|
-
}
|
|
24551
|
-
return match;
|
|
24552
|
-
}
|
|
24553
|
-
async function putJobSpec(base, content) {
|
|
24554
|
-
const json = await fetchJson3(`${base}/job/spec`, {
|
|
24555
|
-
method: "POST",
|
|
24556
|
-
body: { content }
|
|
24557
|
-
});
|
|
24558
|
-
const hash = json.hash;
|
|
24559
|
-
if (!hash) {
|
|
24560
|
-
throw new Error("Failed to store the job spec.");
|
|
24561
|
-
}
|
|
24562
|
-
return hash;
|
|
24563
|
-
}
|
|
24564
|
-
async function getJobSpec(base, hash) {
|
|
24565
|
-
const clean = hash.trim().toLowerCase().replace(/^0x/, "");
|
|
24566
|
-
const json = await fetchJson3(`${base}/job/spec/${clean}`);
|
|
24567
|
-
const content = json.content;
|
|
24568
|
-
if (content === void 0) {
|
|
24569
|
-
throw new Error("No spec stored for this hash.");
|
|
24570
|
-
}
|
|
24571
|
-
const actual = createHash("sha256").update(content, "utf8").digest("hex");
|
|
24572
|
-
if (actual !== clean) {
|
|
24573
|
-
throw new Error(
|
|
24574
|
-
"Spec content does NOT match its hash \u2014 the store returned tampered data. Do not trust it."
|
|
24575
|
-
);
|
|
24576
|
-
}
|
|
24577
|
-
return content;
|
|
24578
|
-
}
|
|
24579
24536
|
|
|
24580
24537
|
// src/commands/job.ts
|
|
24581
24538
|
var DEFAULT_API_BASE5 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
@@ -24600,7 +24557,7 @@ async function resolveCommitment(input) {
|
|
|
24600
24557
|
} catch {
|
|
24601
24558
|
bytes = Buffer.from(input, "utf8");
|
|
24602
24559
|
}
|
|
24603
|
-
return `0x${
|
|
24560
|
+
return `0x${createHash("sha256").update(bytes).digest("hex")}`;
|
|
24604
24561
|
}
|
|
24605
24562
|
function stateColor(state) {
|
|
24606
24563
|
if (state === "released") return import_picocolors15.default.green(state);
|
|
@@ -24679,14 +24636,14 @@ Typical flow:
|
|
|
24679
24636
|
either $ t2 job watch 0xJOB
|
|
24680
24637
|
seller $ t2 job watch --mine (the provider inbox \u2014 all your jobs)
|
|
24681
24638
|
|
|
24682
|
-
Buying
|
|
24639
|
+
Buying a SERVICE (t2 ACP) \u2014 price + terms come from the listing:
|
|
24683
24640
|
buyer $ t2 browse "market report"
|
|
24684
|
-
buyer $ t2 job create --agent 0xSELLER --
|
|
24641
|
+
buyer $ t2 job create --agent 0xSELLER --service sui-market-report \\
|
|
24685
24642
|
--requirements '{"token":"DEEP"}'
|
|
24686
24643
|
seller $ t2 job spec 0xJOB (read the buyer's requirements)
|
|
24687
24644
|
`
|
|
24688
24645
|
);
|
|
24689
|
-
group.command("create").argument("[amount]", `USDC to escrow (max ${MAX_JOB_USDC}; omit when buying
|
|
24646
|
+
group.command("create").argument("[amount]", `USDC to escrow (max ${MAX_JOB_USDC}; omit when buying a --service)`).argument("[seller]", "The seller's Sui address (omit when buying a --service)").description("Create + fund an escrow job in one transaction (buyer)").option("--spec <file-or-text>", "Job spec \u2014 a file path or inline text (hashed on-chain), or a 0x\u2026 hash").option("--agent <address>", "Buy a service: the seller's agent address").option("--service <slug>", "The service slug (see t2 browse / t2 service list <agent>)").option("--offering <slug>", "Alias for --service (compat)").option("--requirements <file-or-json-or-text>", "Your requirements for the service (what the seller asked for)").option("--deadline <duration>", "Time the seller has to deliver (e.g. 30m, 24h, 7d)", "24h").option("--review <duration>", "Your accept/reject window after delivery", "24h").option("--split <bps>", "Your share in bps if you reject (0\u201310000)", String(DEFAULT_REJECT_SPLIT_BPS)).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
|
|
24690
24647
|
async (amountArg, sellerArg, opts) => {
|
|
24691
24648
|
try {
|
|
24692
24649
|
const base = opts.api ?? DEFAULT_API_BASE5;
|
|
@@ -24697,17 +24654,18 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
24697
24654
|
let reviewWindowMs;
|
|
24698
24655
|
let rejectSplitBps;
|
|
24699
24656
|
let offeringSlug;
|
|
24700
|
-
|
|
24701
|
-
|
|
24702
|
-
|
|
24657
|
+
const serviceSlugOpt = opts.service ?? opts.offering;
|
|
24658
|
+
if (serviceSlugOpt || opts.agent) {
|
|
24659
|
+
if (!(serviceSlugOpt && opts.agent)) {
|
|
24660
|
+
throw new Error("--agent and --service go together.");
|
|
24703
24661
|
}
|
|
24704
24662
|
if (amountArg || sellerArg) {
|
|
24705
24663
|
throw new Error(
|
|
24706
|
-
"Omit the amount/seller arguments when buying
|
|
24664
|
+
"Omit the amount/seller arguments when buying a service \u2014 the listing sets the price and the seller."
|
|
24707
24665
|
);
|
|
24708
24666
|
}
|
|
24709
24667
|
const sellerAgent = validateAddress(opts.agent);
|
|
24710
|
-
const offering = await fetchOffering(base, sellerAgent,
|
|
24668
|
+
const offering = await fetchOffering(base, sellerAgent, serviceSlugOpt);
|
|
24711
24669
|
offeringSlug = offering.slug;
|
|
24712
24670
|
let requirements = null;
|
|
24713
24671
|
if (opts.requirements) {
|
|
@@ -24725,12 +24683,12 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
24725
24683
|
if (offering.requirements != null && requirements == null) {
|
|
24726
24684
|
const want = typeof offering.requirements === "string" ? offering.requirements : `JSON matching: ${JSON.stringify(offering.requirements)}`;
|
|
24727
24685
|
throw new Error(
|
|
24728
|
-
`This
|
|
24686
|
+
`This service needs --requirements. The seller asks for: ${want}`
|
|
24729
24687
|
);
|
|
24730
24688
|
}
|
|
24731
24689
|
if (offering.requirements != null && typeof offering.requirements === "object" && (typeof requirements !== "object" || requirements === null)) {
|
|
24732
24690
|
throw new Error(
|
|
24733
|
-
`This
|
|
24691
|
+
`This service expects JSON requirements matching: ${JSON.stringify(offering.requirements)}`
|
|
24734
24692
|
);
|
|
24735
24693
|
}
|
|
24736
24694
|
const buyer = (await withAgent({ keyPath: opts.key })).address();
|
|
@@ -24756,7 +24714,7 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
24756
24714
|
} else {
|
|
24757
24715
|
if (!(amountArg && sellerArg)) {
|
|
24758
24716
|
throw new Error(
|
|
24759
|
-
"Provide <amount> <seller> (direct job) or --agent + --
|
|
24717
|
+
"Provide <amount> <seller> (direct job) or --agent + --service (buy a listing)."
|
|
24760
24718
|
);
|
|
24761
24719
|
}
|
|
24762
24720
|
if (!opts.spec) {
|
|
@@ -24798,7 +24756,7 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
24798
24756
|
return;
|
|
24799
24757
|
}
|
|
24800
24758
|
printBlank();
|
|
24801
|
-
printSuccess(`Escrowed $${amountUsdc.toFixed(2)} USDC \u2192 job for ${truncateAddress(seller)}${offeringSlug ? ` (
|
|
24759
|
+
printSuccess(`Escrowed $${amountUsdc.toFixed(2)} USDC \u2192 job for ${truncateAddress(seller)}${offeringSlug ? ` (service: ${offeringSlug})` : ""}`);
|
|
24802
24760
|
if (jobId) printKeyValue("Job", jobId);
|
|
24803
24761
|
printKeyValue("Spec hash", specHash);
|
|
24804
24762
|
printKeyValue("Deliver by", new Date(deliverByMs).toISOString());
|
|
@@ -24927,7 +24885,7 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
24927
24885
|
stars,
|
|
24928
24886
|
text: opts.text?.trim() || null
|
|
24929
24887
|
};
|
|
24930
|
-
const payloadHash =
|
|
24888
|
+
const payloadHash = createHash("sha256").update(JSON.stringify(payload), "utf8").digest("hex");
|
|
24931
24889
|
const message = new TextEncoder().encode(
|
|
24932
24890
|
`t2000-job-review:${nonce}:${payloadHash}`
|
|
24933
24891
|
);
|
|
@@ -25058,7 +25016,7 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
25058
25016
|
|
|
25059
25017
|
// src/commands/offering.ts
|
|
25060
25018
|
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
25061
|
-
import { createHash as
|
|
25019
|
+
import { createHash as createHash2 } from "crypto";
|
|
25062
25020
|
import { readFile as readFile4 } from "fs/promises";
|
|
25063
25021
|
var DEFAULT_API_BASE6 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
25064
25022
|
async function signedOfferingAction(opts) {
|
|
@@ -25072,7 +25030,7 @@ async function signedOfferingAction(opts) {
|
|
|
25072
25030
|
if (!nonce) {
|
|
25073
25031
|
throw new Error("Failed to get a challenge nonce.");
|
|
25074
25032
|
}
|
|
25075
|
-
const payloadHash =
|
|
25033
|
+
const payloadHash = createHash2("sha256").update(JSON.stringify(opts.payload), "utf8").digest("hex");
|
|
25076
25034
|
const message = new TextEncoder().encode(
|
|
25077
25035
|
`t2000-agent-offering:${nonce}:${payloadHash}`
|
|
25078
25036
|
);
|
|
@@ -25130,29 +25088,29 @@ function printOffering(o) {
|
|
|
25130
25088
|
}
|
|
25131
25089
|
printKeyValue(
|
|
25132
25090
|
"Buy",
|
|
25133
|
-
`t2 job create --agent ${o.agent} --
|
|
25091
|
+
`t2 job create --agent ${o.agent} --service ${o.slug}`
|
|
25134
25092
|
);
|
|
25135
25093
|
}
|
|
25136
25094
|
function registerOffering(program3) {
|
|
25137
|
-
const group = program3.command("offering").description(
|
|
25095
|
+
const group = program3.command("service").alias("offering").description(
|
|
25138
25096
|
"Sell deliverable work \u2014 list what you do, at what price, on what SLA (t2 ACP)"
|
|
25139
25097
|
).addHelpText(
|
|
25140
25098
|
"after",
|
|
25141
25099
|
`
|
|
25142
|
-
|
|
25100
|
+
A service needs NO server and NO endpoint: buyers fund an on-chain escrow
|
|
25143
25101
|
Job against it, you deliver with \`t2 job deliver\`, the escrow settles. Your
|
|
25144
25102
|
catalog lives on your Agent ID and shows on agents.t2000.ai.
|
|
25145
25103
|
|
|
25146
25104
|
Examples:
|
|
25147
|
-
$ t2
|
|
25105
|
+
$ t2 service create --name "Sui market report" --price 5 --sla 24h \\
|
|
25148
25106
|
--description "Daily research report on any Sui token" \\
|
|
25149
25107
|
--deliverable "PDF report, 2+ pages, sources cited" \\
|
|
25150
25108
|
--requirements "Token symbol or coin type to analyze"
|
|
25151
|
-
$ t2
|
|
25152
|
-
$ t2
|
|
25109
|
+
$ t2 service list
|
|
25110
|
+
$ t2 service retire sui-market-report
|
|
25153
25111
|
`
|
|
25154
25112
|
);
|
|
25155
|
-
group.command("create").description("List
|
|
25113
|
+
group.command("create").description("List a service under your Agent ID (re-run to update it)").requiredOption("--name <name>", "Service name (max 80 chars)").requiredOption("--price <usdc>", "Fixed price in USDC (0.01\u201350)").requiredOption("--sla <duration>", "Delivery SLA \u2014 e.g. 30m, 24h, 7d").requiredOption("--description <text>", "What this service is (max 2000 chars)").requiredOption("--deliverable <text>", "What the buyer receives (max 1000 chars)").option("--slug <slug>", "Machine name (default: derived from --name)").option(
|
|
25156
25114
|
"--requirements <file-or-json-or-text>",
|
|
25157
25115
|
"What the buyer must provide \u2014 free text or a JSON schema (file path ok)"
|
|
25158
25116
|
).option("--review <duration>", "Buyer's accept/reject window after delivery", "24h").option("--split <bps>", "Buyer's share in bps if they reject (0\u201310000)", "8000").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE6})`).action(
|
|
@@ -25193,7 +25151,7 @@ Examples:
|
|
|
25193
25151
|
printSuccess(`"${payload.name}" is listed \u2014 $${priceUsdc.toFixed(2)} USDC, delivery within ${formatSla(slaMinutes)}`);
|
|
25194
25152
|
printKeyValue("Slug", slug);
|
|
25195
25153
|
printKeyValue("Storefront", `https://agents.t2000.ai/${address}`);
|
|
25196
|
-
printKeyValue("Buyers run", `t2 job create --agent ${address} --
|
|
25154
|
+
printKeyValue("Buyers run", `t2 job create --agent ${address} --service ${slug}`);
|
|
25197
25155
|
printBlank();
|
|
25198
25156
|
printInfo("Watch for incoming jobs with: t2 job watch <jobId> (buyers hand you the job id)");
|
|
25199
25157
|
printBlank();
|
|
@@ -25202,7 +25160,7 @@ Examples:
|
|
|
25202
25160
|
}
|
|
25203
25161
|
}
|
|
25204
25162
|
);
|
|
25205
|
-
group.command("list").argument("[agent]", "Agent address (default: this wallet's)").description("An agent's
|
|
25163
|
+
group.command("list").argument("[agent]", "Agent address (default: this wallet's)").description("An agent's services \u2014 yours by default, retired included").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE6})`).action(async (agentArg, opts) => {
|
|
25206
25164
|
try {
|
|
25207
25165
|
const base = opts.api ?? DEFAULT_API_BASE6;
|
|
25208
25166
|
const agent = agentArg ? validateAddress(agentArg) : (await withAgent({ keyPath: opts.key })).address();
|
|
@@ -25216,7 +25174,7 @@ Examples:
|
|
|
25216
25174
|
}
|
|
25217
25175
|
printBlank();
|
|
25218
25176
|
if (rows.length === 0) {
|
|
25219
|
-
printInfo(`No
|
|
25177
|
+
printInfo(`No services for ${truncateAddress(agent)} \u2014 list one with: t2 service create`);
|
|
25220
25178
|
printBlank();
|
|
25221
25179
|
return;
|
|
25222
25180
|
}
|
|
@@ -25228,7 +25186,7 @@ Examples:
|
|
|
25228
25186
|
handleError(error);
|
|
25229
25187
|
}
|
|
25230
25188
|
});
|
|
25231
|
-
group.command("retire").argument("<slug>", "The
|
|
25189
|
+
group.command("retire").argument("<slug>", "The service slug to retire").description("Take a service off the board (funded jobs still settle on-chain)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE6})`).action(async (slug, opts) => {
|
|
25232
25190
|
try {
|
|
25233
25191
|
const base = opts.api ?? DEFAULT_API_BASE6;
|
|
25234
25192
|
const { address } = await signedOfferingAction({
|
|
@@ -25242,7 +25200,7 @@ Examples:
|
|
|
25242
25200
|
return;
|
|
25243
25201
|
}
|
|
25244
25202
|
printBlank();
|
|
25245
|
-
printSuccess(`
|
|
25203
|
+
printSuccess(`Service "${slug}" retired. Re-run t2 service create with the same slug to relist.`);
|
|
25246
25204
|
printBlank();
|
|
25247
25205
|
} catch (error) {
|
|
25248
25206
|
handleError(error);
|
|
@@ -25250,7 +25208,7 @@ Examples:
|
|
|
25250
25208
|
});
|
|
25251
25209
|
}
|
|
25252
25210
|
function registerBrowse(program3) {
|
|
25253
|
-
program3.command("browse").argument("[query]", "What you need \u2014 free-text search (empty = everything)").description("Browse
|
|
25211
|
+
program3.command("browse").argument("[query]", "What you need \u2014 free-text search (empty = everything)").description("Browse agent services \u2014 find work to buy (t2 ACP)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE6})`).action(async (query, opts) => {
|
|
25254
25212
|
try {
|
|
25255
25213
|
const base = opts.api ?? DEFAULT_API_BASE6;
|
|
25256
25214
|
const params = query ? `?q=${encodeURIComponent(query)}` : "";
|
|
@@ -25262,7 +25220,7 @@ function registerBrowse(program3) {
|
|
|
25262
25220
|
}
|
|
25263
25221
|
printBlank();
|
|
25264
25222
|
if (rows.length === 0) {
|
|
25265
|
-
printInfo(query ? `No
|
|
25223
|
+
printInfo(query ? `No services match "${query}".` : "No services listed yet.");
|
|
25266
25224
|
printBlank();
|
|
25267
25225
|
return;
|
|
25268
25226
|
}
|
|
@@ -25299,8 +25257,8 @@ Examples:
|
|
|
25299
25257
|
$ t2 services search "image" Discover x402 services in the gateway catalog
|
|
25300
25258
|
$ t2 check <url> Validate your paid API against the listing gates (add --list to sell it)
|
|
25301
25259
|
$ t2 job create 5 0xSELLER --spec brief.md --deadline 24h Escrow USDC for deliverable work (A2A)
|
|
25302
|
-
$ t2
|
|
25303
|
-
$ t2 browse "market report" Find
|
|
25260
|
+
$ t2 service create --name "Report" --price 5 --sla 24h ... Sell deliverable work (no server needed)
|
|
25261
|
+
$ t2 browse "market report" Find agent services to buy
|
|
25304
25262
|
$ t2 agents Look up the agent directory (agents.t2000.ai)
|
|
25305
25263
|
$ t2 limit set --daily 100 Change the daily spend cap (default $100/day)
|
|
25306
25264
|
$ t2 mcp install Connect Claude / Cursor / Windsurf
|