@t2000/sdk 10.36.0 → 10.37.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 -0
- package/dist/index.cjs +563 -367
- package/dist/index.d.cts +309 -92
- package/dist/index.d.ts +309 -92
- package/dist/index.js +534 -367
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11,10 +11,6 @@ import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
|
|
|
11
11
|
import { access, mkdir, writeFile, readFile } from 'fs/promises';
|
|
12
12
|
import { join, dirname, resolve } from 'path';
|
|
13
13
|
import { homedir } from 'os';
|
|
14
|
-
import { ed25519 } from '@noble/curves/ed25519';
|
|
15
|
-
import { secp256k1 } from '@noble/curves/secp256k1';
|
|
16
|
-
import { sha256 } from '@noble/hashes/sha256';
|
|
17
|
-
import { hexToBytes, bytesToHex } from '@noble/hashes/utils';
|
|
18
14
|
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
19
15
|
import { bcs } from '@mysten/sui/bcs';
|
|
20
16
|
import { SuinsTransaction } from '@mysten/suins';
|
|
@@ -1421,10 +1417,10 @@ async function finalize(response, opts) {
|
|
|
1421
1417
|
return { status: response.status, body: body2, paid: opts.paid };
|
|
1422
1418
|
}
|
|
1423
1419
|
async function makeGrpcBuildClient(client) {
|
|
1424
|
-
const { SuiGrpcClient:
|
|
1420
|
+
const { SuiGrpcClient: SuiGrpcClient2 } = await import('@mysten/sui/grpc');
|
|
1425
1421
|
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
1426
1422
|
const baseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
1427
|
-
return new
|
|
1423
|
+
return new SuiGrpcClient2({ baseUrl, network });
|
|
1428
1424
|
}
|
|
1429
1425
|
function atomicToHuman(raw, decimals) {
|
|
1430
1426
|
return Number(raw) / 10 ** decimals;
|
|
@@ -2176,8 +2172,7 @@ function body(params, stream) {
|
|
|
2176
2172
|
return JSON.stringify({
|
|
2177
2173
|
model: params.model,
|
|
2178
2174
|
messages: params.messages,
|
|
2179
|
-
// include_usage → the final stream chunk carries usage
|
|
2180
|
-
// (the confidential attestation receipt) so we can surface it after a stream.
|
|
2175
|
+
// include_usage → the final stream chunk carries usage.
|
|
2181
2176
|
...stream ? { stream: true, stream_options: { include_usage: true } } : {},
|
|
2182
2177
|
...params.maxTokens != null ? { max_tokens: params.maxTokens } : {},
|
|
2183
2178
|
...params.temperature != null ? { temperature: params.temperature } : {}
|
|
@@ -2194,14 +2189,12 @@ async function chatCompletion(params) {
|
|
|
2194
2189
|
if (!res.ok) {
|
|
2195
2190
|
await failBody(res);
|
|
2196
2191
|
}
|
|
2197
|
-
const receiptId = res.headers.get("x-receipt-id") ?? void 0;
|
|
2198
2192
|
const raw = await res.json();
|
|
2199
2193
|
const content = raw?.choices?.[0]?.message?.content ?? "";
|
|
2200
2194
|
return {
|
|
2201
2195
|
content,
|
|
2202
2196
|
model: raw?.model ?? params.model,
|
|
2203
2197
|
usage: usageOf(raw),
|
|
2204
|
-
receiptId,
|
|
2205
2198
|
raw
|
|
2206
2199
|
};
|
|
2207
2200
|
}
|
|
@@ -2215,12 +2208,11 @@ async function* chatCompletionStream(params) {
|
|
|
2215
2208
|
});
|
|
2216
2209
|
if (!(res.ok && res.body)) {
|
|
2217
2210
|
await failBody(res);
|
|
2218
|
-
return
|
|
2211
|
+
return;
|
|
2219
2212
|
}
|
|
2220
2213
|
const reader = res.body.getReader();
|
|
2221
2214
|
const decoder = new TextDecoder();
|
|
2222
2215
|
let buffer = "";
|
|
2223
|
-
let receiptId;
|
|
2224
2216
|
while (true) {
|
|
2225
2217
|
const { done, value } = await reader.read();
|
|
2226
2218
|
if (done) {
|
|
@@ -2236,13 +2228,10 @@ async function* chatCompletionStream(params) {
|
|
|
2236
2228
|
}
|
|
2237
2229
|
const data = trimmed.slice(5).trim();
|
|
2238
2230
|
if (data === "[DONE]") {
|
|
2239
|
-
return
|
|
2231
|
+
return;
|
|
2240
2232
|
}
|
|
2241
2233
|
try {
|
|
2242
2234
|
const json = JSON.parse(data);
|
|
2243
|
-
if (json.x_receipt_id) {
|
|
2244
|
-
receiptId = json.x_receipt_id;
|
|
2245
|
-
}
|
|
2246
2235
|
const delta = json.choices?.[0]?.delta?.content;
|
|
2247
2236
|
if (typeof delta === "string" && delta) {
|
|
2248
2237
|
yield delta;
|
|
@@ -2251,7 +2240,6 @@ async function* chatCompletionStream(params) {
|
|
|
2251
2240
|
}
|
|
2252
2241
|
}
|
|
2253
2242
|
}
|
|
2254
|
-
return { receiptId };
|
|
2255
2243
|
}
|
|
2256
2244
|
async function listModels(opts) {
|
|
2257
2245
|
const base = opts?.apiBase ?? DEFAULT_API_BASE;
|
|
@@ -2273,330 +2261,6 @@ async function listModels(opts) {
|
|
|
2273
2261
|
reasoning: m.reasoning
|
|
2274
2262
|
}));
|
|
2275
2263
|
}
|
|
2276
|
-
var RECEIPT_ANCHORED_SUFFIX = "::anchor::ReceiptAnchored";
|
|
2277
|
-
function normalizeClaims(claims) {
|
|
2278
|
-
if (!claims) {
|
|
2279
|
-
return [];
|
|
2280
|
-
}
|
|
2281
|
-
if (Array.isArray(claims)) {
|
|
2282
|
-
return claims.filter((c) => c.name).map((c) => ({
|
|
2283
|
-
name: c.name,
|
|
2284
|
-
status: c.status ?? "unknown",
|
|
2285
|
-
source: c.source
|
|
2286
|
-
}));
|
|
2287
|
-
}
|
|
2288
|
-
return Object.entries(claims).map(([name, v]) => ({
|
|
2289
|
-
name,
|
|
2290
|
-
status: v?.status ?? "unknown",
|
|
2291
|
-
source: v?.source
|
|
2292
|
-
}));
|
|
2293
|
-
}
|
|
2294
|
-
function fullnodeUrl(network) {
|
|
2295
|
-
return network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
2296
|
-
}
|
|
2297
|
-
function jcs(value) {
|
|
2298
|
-
if (value === null) {
|
|
2299
|
-
return "null";
|
|
2300
|
-
}
|
|
2301
|
-
if (typeof value === "boolean") {
|
|
2302
|
-
return value ? "true" : "false";
|
|
2303
|
-
}
|
|
2304
|
-
if (typeof value === "number") {
|
|
2305
|
-
if (!Number.isInteger(value)) {
|
|
2306
|
-
throw new Error("JCS: non-integer number");
|
|
2307
|
-
}
|
|
2308
|
-
return String(value);
|
|
2309
|
-
}
|
|
2310
|
-
if (typeof value === "string") {
|
|
2311
|
-
return JSON.stringify(value);
|
|
2312
|
-
}
|
|
2313
|
-
if (Array.isArray(value)) {
|
|
2314
|
-
return `[${value.map(jcs).join(",")}]`;
|
|
2315
|
-
}
|
|
2316
|
-
const keys = Object.keys(value).sort();
|
|
2317
|
-
return `{${keys.map((k) => `${JSON.stringify(k)}:${jcs(value[k])}`).join(",")}}`;
|
|
2318
|
-
}
|
|
2319
|
-
function verifyReceiptSignature(receipt, signingKeyHex) {
|
|
2320
|
-
try {
|
|
2321
|
-
const sig = receipt.signature;
|
|
2322
|
-
if (!sig?.value) {
|
|
2323
|
-
return false;
|
|
2324
|
-
}
|
|
2325
|
-
const endorsed = hexToBytes(signingKeyHex.replace(/^0x/, ""));
|
|
2326
|
-
const sigBytes = hexToBytes(sig.value);
|
|
2327
|
-
if (sig.algo === "ed25519") {
|
|
2328
|
-
if (sigBytes.length !== 64 || endorsed.length !== 32) {
|
|
2329
|
-
return false;
|
|
2330
|
-
}
|
|
2331
|
-
const { value: _omitted, ...sigRest } = sig;
|
|
2332
|
-
const canonical2 = {
|
|
2333
|
-
...receipt,
|
|
2334
|
-
signature: sigRest
|
|
2335
|
-
};
|
|
2336
|
-
const msg = new TextEncoder().encode(jcs(canonical2));
|
|
2337
|
-
return ed25519.verify(sigBytes, msg, endorsed);
|
|
2338
|
-
}
|
|
2339
|
-
if (sig.algo !== "ecdsa-secp256k1") {
|
|
2340
|
-
return false;
|
|
2341
|
-
}
|
|
2342
|
-
const canonical = {
|
|
2343
|
-
api_version: receipt.api_version ?? "",
|
|
2344
|
-
receipt_id: receipt.receipt_id ?? "",
|
|
2345
|
-
chat_id: receipt.chat_id ?? null,
|
|
2346
|
-
workload_id: receipt.workload_id ?? "",
|
|
2347
|
-
workload_keyset_digest: receipt.workload_keyset_digest ?? "",
|
|
2348
|
-
endpoint: receipt.endpoint ?? "",
|
|
2349
|
-
method: receipt.method ?? "",
|
|
2350
|
-
served_at: receipt.served_at ?? 0,
|
|
2351
|
-
event_log: receipt.event_log ?? [],
|
|
2352
|
-
signature: { algo: sig.algo, key_id: sig.key_id ?? "" }
|
|
2353
|
-
};
|
|
2354
|
-
const prehash = sha256(new TextEncoder().encode(jcs(canonical)));
|
|
2355
|
-
if (sigBytes.length !== 65) {
|
|
2356
|
-
return false;
|
|
2357
|
-
}
|
|
2358
|
-
let v = sigBytes[64];
|
|
2359
|
-
if (v >= 27 && v <= 30) {
|
|
2360
|
-
v -= 27;
|
|
2361
|
-
}
|
|
2362
|
-
if (v > 3) {
|
|
2363
|
-
return false;
|
|
2364
|
-
}
|
|
2365
|
-
const recovered = secp256k1.Signature.fromCompact(sigBytes.slice(0, 64)).addRecoveryBit(v).recoverPublicKey(prehash).toHex(false);
|
|
2366
|
-
return recovered.toLowerCase() === bytesToHex(endorsed).toLowerCase();
|
|
2367
|
-
} catch {
|
|
2368
|
-
return false;
|
|
2369
|
-
}
|
|
2370
|
-
}
|
|
2371
|
-
async function verifyTdxQuote(base, model, receiptWorkloadId) {
|
|
2372
|
-
let nonce;
|
|
2373
|
-
try {
|
|
2374
|
-
nonce = bytesToHex(globalThis.crypto.getRandomValues(new Uint8Array(32)));
|
|
2375
|
-
} catch {
|
|
2376
|
-
return { status: "skip", detail: "no secure RNG available", forged: false };
|
|
2377
|
-
}
|
|
2378
|
-
let report;
|
|
2379
|
-
try {
|
|
2380
|
-
const res = await fetch(
|
|
2381
|
-
`${base}/aci/attestation?model=${encodeURIComponent(model)}&nonce=${nonce}`
|
|
2382
|
-
);
|
|
2383
|
-
if (res.ok) {
|
|
2384
|
-
report = (await res.json()).report;
|
|
2385
|
-
}
|
|
2386
|
-
} catch {
|
|
2387
|
-
}
|
|
2388
|
-
const quoteHex = report?.attestation?.evidence?.quote;
|
|
2389
|
-
if (!quoteHex) {
|
|
2390
|
-
return {
|
|
2391
|
-
status: "skip",
|
|
2392
|
-
detail: "attestation report (with quote) unavailable \u2014 pass --model?",
|
|
2393
|
-
forged: false
|
|
2394
|
-
};
|
|
2395
|
-
}
|
|
2396
|
-
try {
|
|
2397
|
-
const dcap = await import('@phala/dcap-qvl');
|
|
2398
|
-
const getCollateralAndVerify = dcap.getCollateralAndVerify ?? dcap.default?.getCollateralAndVerify;
|
|
2399
|
-
if (typeof getCollateralAndVerify !== "function") {
|
|
2400
|
-
return {
|
|
2401
|
-
status: "fail",
|
|
2402
|
-
forged: false,
|
|
2403
|
-
detail: "DCAP verifier unavailable in this build"
|
|
2404
|
-
};
|
|
2405
|
-
}
|
|
2406
|
-
const quoteBytes = hexToBytes(quoteHex.replace(/^0x/, ""));
|
|
2407
|
-
const vr = await getCollateralAndVerify(quoteBytes);
|
|
2408
|
-
const td = vr.report.asTd10() ?? vr.report.asTd15()?.base ?? null;
|
|
2409
|
-
const reportData = td?.reportData;
|
|
2410
|
-
const signingAddr = report?.signing_address?.replace(/^0x/, "").toLowerCase();
|
|
2411
|
-
const addrBound = Boolean(
|
|
2412
|
-
reportData && signingAddr && bytesToHex(reportData.slice(0, 20)) === signingAddr
|
|
2413
|
-
);
|
|
2414
|
-
const workloadMatch = report?.workload_id === receiptWorkloadId;
|
|
2415
|
-
const tcb = vr.status;
|
|
2416
|
-
const tcbBad = tcb === "Revoked" || tcb === "Unknown";
|
|
2417
|
-
const forged = !(addrBound && workloadMatch) || tcbBad;
|
|
2418
|
-
let detail;
|
|
2419
|
-
if (forged && tcbBad) {
|
|
2420
|
-
detail = `genuine TDX but TCB ${tcb}`;
|
|
2421
|
-
} else if (!addrBound) {
|
|
2422
|
-
detail = "report_data does NOT commit the report's signing address";
|
|
2423
|
-
} else if (!workloadMatch) {
|
|
2424
|
-
detail = "quote workload_id does not match the receipt's";
|
|
2425
|
-
} else {
|
|
2426
|
-
detail = `genuine Intel TDX (verified vs Intel collateral), TCB ${tcb}; report_data commits the attested signing address`;
|
|
2427
|
-
}
|
|
2428
|
-
return { status: forged ? "fail" : "pass", forged, tcbStatus: tcb, detail };
|
|
2429
|
-
} catch (e) {
|
|
2430
|
-
return {
|
|
2431
|
-
status: "fail",
|
|
2432
|
-
forged: false,
|
|
2433
|
-
detail: `could not verify the quote: ${e instanceof Error ? e.message : "error"}`
|
|
2434
|
-
};
|
|
2435
|
-
}
|
|
2436
|
-
}
|
|
2437
|
-
async function verifyReceipt(receiptId, opts = {}) {
|
|
2438
|
-
const base = opts.apiBase ?? DEFAULT_API_BASE;
|
|
2439
|
-
const network = opts.network ?? "mainnet";
|
|
2440
|
-
const checks = [];
|
|
2441
|
-
let receipt = null;
|
|
2442
|
-
try {
|
|
2443
|
-
const res = await fetch(`${base}/aci/receipts/${encodeURIComponent(receiptId)}`);
|
|
2444
|
-
if (res.ok) {
|
|
2445
|
-
receipt = await res.json();
|
|
2446
|
-
}
|
|
2447
|
-
} catch {
|
|
2448
|
-
}
|
|
2449
|
-
if (!receipt?.event_log) {
|
|
2450
|
-
checks.push({
|
|
2451
|
-
name: "Receipt",
|
|
2452
|
-
status: "fail",
|
|
2453
|
-
detail: "receipt not found or malformed",
|
|
2454
|
-
trust: "receipt-asserted"
|
|
2455
|
-
});
|
|
2456
|
-
return { receiptId, verified: false, anchorVerified: false, checks };
|
|
2457
|
-
}
|
|
2458
|
-
const wireHash = receipt.event_log.find((e) => e.type === "response.returned")?.wire_hash;
|
|
2459
|
-
const workloadId = receipt.workload_id;
|
|
2460
|
-
checks.push({
|
|
2461
|
-
name: "Receipt",
|
|
2462
|
-
status: wireHash && workloadId ? "pass" : "fail",
|
|
2463
|
-
detail: wireHash ? `well-formed (${receipt.event_log.length} log entries, workload ${workloadId})` : "missing response wire_hash / workload_id",
|
|
2464
|
-
trust: "receipt-asserted"
|
|
2465
|
-
});
|
|
2466
|
-
const upstreamEv = receipt.event_log.find((e) => e.type === "upstream.verified");
|
|
2467
|
-
const upstreamOk = upstreamEv?.result === "verified";
|
|
2468
|
-
const claims = normalizeClaims(upstreamEv?.claims);
|
|
2469
|
-
checks.push({
|
|
2470
|
-
name: "Confidential upstream",
|
|
2471
|
-
status: upstreamEv ? upstreamOk ? "pass" : "fail" : "skip",
|
|
2472
|
-
detail: upstreamEv ? `${upstreamEv.provider ?? upstreamEv.upstream_name ?? "upstream"}: ${upstreamEv.result ?? "unknown"}${upstreamEv.tcb_status ? ` (TCB ${upstreamEv.tcb_status})` : ""}` : "no upstream.verified event (routed/non-confidential?)",
|
|
2473
|
-
trust: "receipt-asserted"
|
|
2474
|
-
});
|
|
2475
|
-
let anchorVerified = false;
|
|
2476
|
-
let anchor;
|
|
2477
|
-
let digest;
|
|
2478
|
-
try {
|
|
2479
|
-
const res = await fetch(`${base}/aci/anchor/${encodeURIComponent(receiptId)}`);
|
|
2480
|
-
if (res.ok) {
|
|
2481
|
-
const j = await res.json();
|
|
2482
|
-
digest = j.txDigest;
|
|
2483
|
-
}
|
|
2484
|
-
} catch {
|
|
2485
|
-
}
|
|
2486
|
-
if (!digest) {
|
|
2487
|
-
checks.push({
|
|
2488
|
-
name: "Sui anchor",
|
|
2489
|
-
status: "fail",
|
|
2490
|
-
detail: `no anchor on record \u2014 POST ${base}/aci/anchor/${receiptId} to create one`,
|
|
2491
|
-
trust: "trustless"
|
|
2492
|
-
});
|
|
2493
|
-
} else {
|
|
2494
|
-
try {
|
|
2495
|
-
const client = new SuiGrpcClient({ baseUrl: fullnodeUrl(network), network });
|
|
2496
|
-
const tx = await client.core.getTransaction({
|
|
2497
|
-
digest,
|
|
2498
|
-
include: { events: true }
|
|
2499
|
-
});
|
|
2500
|
-
const txn = tx.$kind === "Transaction" ? tx.Transaction : tx.FailedTransaction;
|
|
2501
|
-
const ev = (txn.events ?? []).find(
|
|
2502
|
-
(e) => e.eventType.endsWith(RECEIPT_ANCHORED_SUFFIX)
|
|
2503
|
-
);
|
|
2504
|
-
const data = ev?.json ?? {};
|
|
2505
|
-
const onChainReceipt = String(data.receipt_id ?? "");
|
|
2506
|
-
const onChainWire = String(data.wire_hash ?? "");
|
|
2507
|
-
const onChainWorkload = String(data.workload_id ?? "");
|
|
2508
|
-
const matches = onChainReceipt === receiptId && onChainWire === wireHash && onChainWorkload === workloadId;
|
|
2509
|
-
anchorVerified = matches;
|
|
2510
|
-
anchor = {
|
|
2511
|
-
txDigest: digest,
|
|
2512
|
-
anchoredAtMs: data.anchored_at_ms ? String(data.anchored_at_ms) : void 0,
|
|
2513
|
-
anchoredBy: data.anchored_by ? String(data.anchored_by) : void 0,
|
|
2514
|
-
explorer: `https://suiscan.xyz/${network}/tx/${digest}`
|
|
2515
|
-
};
|
|
2516
|
-
checks.push({
|
|
2517
|
-
name: "Sui anchor",
|
|
2518
|
-
status: matches ? "pass" : "fail",
|
|
2519
|
-
detail: matches ? `on-chain ReceiptAnchored matches (wire_hash + workload_id), tx ${digest}` : `on-chain event does NOT match the receipt (wire ${onChainWire || "absent"})`,
|
|
2520
|
-
trust: "trustless"
|
|
2521
|
-
});
|
|
2522
|
-
} catch (e) {
|
|
2523
|
-
checks.push({
|
|
2524
|
-
name: "Sui anchor",
|
|
2525
|
-
status: "fail",
|
|
2526
|
-
detail: `could not read anchor tx ${digest}: ${e instanceof Error ? e.message : "error"}`,
|
|
2527
|
-
trust: "trustless"
|
|
2528
|
-
});
|
|
2529
|
-
}
|
|
2530
|
-
}
|
|
2531
|
-
let sigStatus = "skip";
|
|
2532
|
-
let sigDetail = "no signature on receipt";
|
|
2533
|
-
if (receipt.signature?.value) {
|
|
2534
|
-
try {
|
|
2535
|
-
const model = opts.model ?? "phala/glm-5.2";
|
|
2536
|
-
const res = await fetch(
|
|
2537
|
-
`${base}/aci/attestation?model=${encodeURIComponent(model)}`
|
|
2538
|
-
);
|
|
2539
|
-
const att = res.ok ? await res.json() : null;
|
|
2540
|
-
if (!att?.signingKey) {
|
|
2541
|
-
sigDetail = "could not fetch the attested keyset to check the signature";
|
|
2542
|
-
} else if (att.workloadId && att.workloadId !== workloadId) {
|
|
2543
|
-
sigDetail = `attested keyset is for a different workload \u2014 pass --model for ${workloadId}`;
|
|
2544
|
-
} else {
|
|
2545
|
-
const ok = verifyReceiptSignature(receipt, att.signingKey);
|
|
2546
|
-
sigStatus = ok ? "pass" : "fail";
|
|
2547
|
-
sigDetail = ok ? `signed by the attested receipt key (${receipt.signature.key_id ?? "key"})` : "signature does NOT recover the attested receipt key \u2014 forged/altered";
|
|
2548
|
-
}
|
|
2549
|
-
} catch {
|
|
2550
|
-
sigDetail = "signature check errored";
|
|
2551
|
-
}
|
|
2552
|
-
}
|
|
2553
|
-
checks.push({
|
|
2554
|
-
name: "Receipt signature",
|
|
2555
|
-
status: sigStatus,
|
|
2556
|
-
detail: sigDetail,
|
|
2557
|
-
trust: sigStatus === "skip" ? "roadmap" : "trustless"
|
|
2558
|
-
});
|
|
2559
|
-
if (opts.skipQuote) {
|
|
2560
|
-
checks.push({
|
|
2561
|
-
name: "TDX quote (DCAP)",
|
|
2562
|
-
status: "skip",
|
|
2563
|
-
detail: "skipped (--quick)",
|
|
2564
|
-
trust: "trustless"
|
|
2565
|
-
});
|
|
2566
|
-
} else {
|
|
2567
|
-
const q = await verifyTdxQuote(
|
|
2568
|
-
base,
|
|
2569
|
-
opts.model ?? "phala/glm-5.2",
|
|
2570
|
-
workloadId ?? ""
|
|
2571
|
-
);
|
|
2572
|
-
checks.push({
|
|
2573
|
-
name: "TDX quote (DCAP)",
|
|
2574
|
-
status: q.status,
|
|
2575
|
-
detail: q.detail,
|
|
2576
|
-
trust: "trustless"
|
|
2577
|
-
});
|
|
2578
|
-
}
|
|
2579
|
-
const trustlessFailed = checks.some(
|
|
2580
|
-
(c) => c.trust === "trustless" && c.status === "fail"
|
|
2581
|
-
);
|
|
2582
|
-
return {
|
|
2583
|
-
receiptId,
|
|
2584
|
-
verified: Boolean(wireHash && workloadId) && !trustlessFailed,
|
|
2585
|
-
anchorVerified,
|
|
2586
|
-
checks,
|
|
2587
|
-
wireHash,
|
|
2588
|
-
workloadId,
|
|
2589
|
-
upstream: upstreamEv ? {
|
|
2590
|
-
provider: upstreamEv.provider ?? upstreamEv.upstream_name,
|
|
2591
|
-
modelId: upstreamEv.model_id,
|
|
2592
|
-
result: upstreamEv.result,
|
|
2593
|
-
tcbStatus: upstreamEv.tcb_status,
|
|
2594
|
-
sessionId: upstreamEv.session_id,
|
|
2595
|
-
claims: claims.length > 0 ? claims : void 0
|
|
2596
|
-
} : void 0,
|
|
2597
|
-
anchor
|
|
2598
|
-
};
|
|
2599
|
-
}
|
|
2600
2264
|
var DEFAULT_CONFIG_DIR = join(homedir(), ".t2000");
|
|
2601
2265
|
function resolveConfigPath(configDir) {
|
|
2602
2266
|
return join(configDir ?? DEFAULT_CONFIG_DIR, "config.json");
|
|
@@ -2920,8 +2584,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2920
2584
|
async chat(params) {
|
|
2921
2585
|
return chatCompletion(params);
|
|
2922
2586
|
}
|
|
2923
|
-
/** Streaming chat completion — async-iterate the assistant text deltas
|
|
2924
|
-
* the generator returns `{ receiptId }` (confidential attestation) at the end. */
|
|
2587
|
+
/** Streaming chat completion — async-iterate the assistant text deltas. */
|
|
2925
2588
|
chatStream(params) {
|
|
2926
2589
|
return chatCompletionStream(params);
|
|
2927
2590
|
}
|
|
@@ -2929,11 +2592,6 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2929
2592
|
async models(opts) {
|
|
2930
2593
|
return listModels(opts);
|
|
2931
2594
|
}
|
|
2932
|
-
/** Verify a confidential response by receipt id — checks the signed receipt
|
|
2933
|
-
* + its trustless on-chain Sui anchor. Fails closed on any mismatch. */
|
|
2934
|
-
async verify(receiptId, opts) {
|
|
2935
|
-
return verifyReceipt(receiptId, opts);
|
|
2936
|
-
}
|
|
2937
2595
|
// -- Swap --
|
|
2938
2596
|
async swap(params) {
|
|
2939
2597
|
this.limits.assert({
|
|
@@ -3345,7 +3003,7 @@ function feeConfigArg(tx) {
|
|
|
3345
3003
|
mutable: false
|
|
3346
3004
|
});
|
|
3347
3005
|
}
|
|
3348
|
-
function
|
|
3006
|
+
function hexToBytes(hex) {
|
|
3349
3007
|
const clean = hex.replace(/^0x/, "");
|
|
3350
3008
|
const bytes = [];
|
|
3351
3009
|
for (let i = 0; i < clean.length; i += 2) {
|
|
@@ -3424,7 +3082,7 @@ async function buildCreateOpeningTx({
|
|
|
3424
3082
|
typeArguments: [USDC_TYPE],
|
|
3425
3083
|
arguments: [
|
|
3426
3084
|
coin,
|
|
3427
|
-
tx.pure.vector("u8",
|
|
3085
|
+
tx.pure.vector("u8", hexToBytes(terms.specHash)),
|
|
3428
3086
|
tx.pure.u64(terms.openUntilMs),
|
|
3429
3087
|
tx.pure.u64(terms.slaMs),
|
|
3430
3088
|
tx.pure.u64(terms.reviewWindowMs),
|
|
@@ -3475,7 +3133,7 @@ function buildCancelOpeningTx(openingId) {
|
|
|
3475
3133
|
function buildRefundUnclaimedTx(openingId) {
|
|
3476
3134
|
return openingCall(openingId, "refund_unclaimed");
|
|
3477
3135
|
}
|
|
3478
|
-
function
|
|
3136
|
+
function bytesToHex(bytes) {
|
|
3479
3137
|
return `0x${Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
3480
3138
|
}
|
|
3481
3139
|
async function getOpening(client, openingId) {
|
|
@@ -3490,7 +3148,7 @@ async function getOpening(client, openingId) {
|
|
|
3490
3148
|
buyer: String(json.buyer),
|
|
3491
3149
|
amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,
|
|
3492
3150
|
feeBps: Number(json.fee_bps ?? 0),
|
|
3493
|
-
specHash:
|
|
3151
|
+
specHash: bytesToHex(json.spec_hash ?? []),
|
|
3494
3152
|
openUntilMs: Number(json.open_until_ms),
|
|
3495
3153
|
slaMs: Number(json.sla_ms),
|
|
3496
3154
|
reviewWindowMs: Number(json.review_window_ms),
|
|
@@ -3527,7 +3185,7 @@ var JOB_STATES = [
|
|
|
3527
3185
|
"refunded",
|
|
3528
3186
|
"rejected"
|
|
3529
3187
|
];
|
|
3530
|
-
function
|
|
3188
|
+
function hexToBytes2(hex) {
|
|
3531
3189
|
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
3532
3190
|
if (clean.length === 0 || clean.length % 2 !== 0 || /[^0-9a-fA-F]/.test(clean)) {
|
|
3533
3191
|
throw new T2000Error(
|
|
@@ -3541,7 +3199,7 @@ function hexToBytes3(hex) {
|
|
|
3541
3199
|
}
|
|
3542
3200
|
return out;
|
|
3543
3201
|
}
|
|
3544
|
-
function
|
|
3202
|
+
function bytesToHex2(bytes) {
|
|
3545
3203
|
const arr = typeof bytes === "string" ? Array.from(atob(bytes), (c) => c.charCodeAt(0)) : bytes;
|
|
3546
3204
|
let s = "0x";
|
|
3547
3205
|
for (const b of arr) s += b.toString(16).padStart(2, "0");
|
|
@@ -3578,7 +3236,7 @@ function preflightCreateJob(terms) {
|
|
|
3578
3236
|
return preflightFail("INVALID_AMOUNT", "rejectSplitBps must be an integer 0\u201310000.");
|
|
3579
3237
|
}
|
|
3580
3238
|
try {
|
|
3581
|
-
|
|
3239
|
+
hexToBytes2(terms.specHash);
|
|
3582
3240
|
} catch (e) {
|
|
3583
3241
|
return preflightFail("INVALID_AMOUNT", e.message);
|
|
3584
3242
|
}
|
|
@@ -3606,7 +3264,7 @@ async function buildCreateJobTx({
|
|
|
3606
3264
|
arguments: [
|
|
3607
3265
|
tx.pure.address(seller),
|
|
3608
3266
|
coin,
|
|
3609
|
-
tx.pure.vector("u8",
|
|
3267
|
+
tx.pure.vector("u8", hexToBytes2(terms.specHash)),
|
|
3610
3268
|
tx.pure.u64(terms.deliverByMs),
|
|
3611
3269
|
tx.pure.u64(terms.reviewWindowMs),
|
|
3612
3270
|
tx.pure.u64(terms.rejectSplitBps),
|
|
@@ -3677,7 +3335,7 @@ function buildDeliverJobTx(jobId, deliveryHash) {
|
|
|
3677
3335
|
typeArguments: [USDC_TYPE],
|
|
3678
3336
|
arguments: [
|
|
3679
3337
|
tx.object(jobId),
|
|
3680
|
-
tx.pure.vector("u8",
|
|
3338
|
+
tx.pure.vector("u8", hexToBytes2(deliveryHash)),
|
|
3681
3339
|
feeConfigArg2(tx),
|
|
3682
3340
|
tx.object(CLOCK_ID3)
|
|
3683
3341
|
]
|
|
@@ -3714,12 +3372,12 @@ async function getJob(client, jobId) {
|
|
|
3714
3372
|
amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,
|
|
3715
3373
|
escrowUsdc: Number(json.escrow) / 10 ** USDC_DECIMALS,
|
|
3716
3374
|
feeBps: Number(json.fee_bps ?? 0),
|
|
3717
|
-
specHash:
|
|
3375
|
+
specHash: bytesToHex2(json.spec_hash ?? []),
|
|
3718
3376
|
deliverByMs: Number(json.deliver_by_ms),
|
|
3719
3377
|
reviewWindowMs: Number(json.review_window_ms),
|
|
3720
3378
|
rejectSplitBps: Number(json.reject_split_bps),
|
|
3721
3379
|
state,
|
|
3722
|
-
deliveryHash: hasDelivery ?
|
|
3380
|
+
deliveryHash: hasDelivery ? bytesToHex2(deliveryBytes) : null,
|
|
3723
3381
|
deliveredAtMs: hasDelivery ? deliveredAtMs : null,
|
|
3724
3382
|
createdAtMs: Number(json.created_at_ms)
|
|
3725
3383
|
};
|
|
@@ -4098,6 +3756,17 @@ function isCustomHireEnvelope(text) {
|
|
|
4098
3756
|
return false;
|
|
4099
3757
|
}
|
|
4100
3758
|
}
|
|
3759
|
+
|
|
3760
|
+
// src/sponsored-guard.ts
|
|
3761
|
+
var sponsoredTxGuard = null;
|
|
3762
|
+
function setSponsoredTxGuard(guard) {
|
|
3763
|
+
sponsoredTxGuard = guard;
|
|
3764
|
+
}
|
|
3765
|
+
function runSponsoredTxGuard(ctx) {
|
|
3766
|
+
sponsoredTxGuard?.(ctx);
|
|
3767
|
+
}
|
|
3768
|
+
|
|
3769
|
+
// src/open-jobs.ts
|
|
4101
3770
|
async function fetchJson(url, init) {
|
|
4102
3771
|
const res = await fetch(url, {
|
|
4103
3772
|
method: init?.method ?? "GET",
|
|
@@ -4112,19 +3781,28 @@ async function fetchJson(url, init) {
|
|
|
4112
3781
|
}
|
|
4113
3782
|
return json;
|
|
4114
3783
|
}
|
|
4115
|
-
var sponsoredTxGuard = null;
|
|
4116
|
-
function setSponsoredTxGuard(guard) {
|
|
4117
|
-
sponsoredTxGuard = guard;
|
|
4118
|
-
}
|
|
4119
3784
|
async function listOpenJobs(base, filter = {}) {
|
|
4120
3785
|
const params = new URLSearchParams();
|
|
4121
3786
|
if (filter.status) params.set("status", filter.status);
|
|
4122
3787
|
if (filter.query) params.set("q", filter.query);
|
|
4123
3788
|
if (filter.buyer) params.set("buyer", filter.buyer);
|
|
4124
3789
|
if (filter.limit) params.set("limit", String(filter.limit));
|
|
3790
|
+
if (filter.offset) params.set("offset", String(filter.offset));
|
|
4125
3791
|
const qs = params.size > 0 ? `?${params.toString()}` : "";
|
|
4126
3792
|
const json = await fetchJson(`${base}/open-jobs${qs}`);
|
|
4127
|
-
|
|
3793
|
+
const openJobs = Array.isArray(json.openJobs) ? json.openJobs : [];
|
|
3794
|
+
const returned = openJobs.length;
|
|
3795
|
+
const total = typeof json.total === "number" && json.total >= returned ? json.total : returned;
|
|
3796
|
+
const startAt = filter.offset ?? 0;
|
|
3797
|
+
const truncated = typeof json.truncated === "boolean" ? json.truncated : startAt + returned < total;
|
|
3798
|
+
const nextOffset = typeof json.nextOffset === "number" ? json.nextOffset : truncated ? startAt + returned : void 0;
|
|
3799
|
+
return {
|
|
3800
|
+
total,
|
|
3801
|
+
returned,
|
|
3802
|
+
truncated,
|
|
3803
|
+
...nextOffset === void 0 ? {} : { nextOffset },
|
|
3804
|
+
openJobs
|
|
3805
|
+
};
|
|
4128
3806
|
}
|
|
4129
3807
|
async function getOpenJob(base, id) {
|
|
4130
3808
|
const json = await fetchJson(
|
|
@@ -4134,7 +3812,7 @@ async function getOpenJob(base, id) {
|
|
|
4134
3812
|
}
|
|
4135
3813
|
async function sponsoredOpeningVerb(base, signer, action, params) {
|
|
4136
3814
|
const address = signer.getAddress();
|
|
4137
|
-
|
|
3815
|
+
runSponsoredTxGuard({ base, action });
|
|
4138
3816
|
const prep = await fetchJson(`${base}/job/prepare`, {
|
|
4139
3817
|
method: "POST",
|
|
4140
3818
|
body: { address, action, params }
|
|
@@ -4144,7 +3822,7 @@ async function sponsoredOpeningVerb(base, signer, action, params) {
|
|
|
4144
3822
|
if (!(nonce && txBytes)) {
|
|
4145
3823
|
throw new Error("Failed to prepare the transaction.");
|
|
4146
3824
|
}
|
|
4147
|
-
|
|
3825
|
+
runSponsoredTxGuard({ base, action, txBytes });
|
|
4148
3826
|
const { signature } = await signer.signTransaction(fromBase64(txBytes));
|
|
4149
3827
|
const json = await fetchJson(`${base}/job/submit`, {
|
|
4150
3828
|
method: "POST",
|
|
@@ -4181,6 +3859,495 @@ function refundOpenJob(base, signer, openingId) {
|
|
|
4181
3859
|
});
|
|
4182
3860
|
}
|
|
4183
3861
|
|
|
3862
|
+
// src/commerce/endpoint.ts
|
|
3863
|
+
init_errors();
|
|
3864
|
+
|
|
3865
|
+
// src/commerce/http.ts
|
|
3866
|
+
init_errors();
|
|
3867
|
+
var DEFAULT_COMMERCE_API_BASE2 = "https://api.t2000.ai/v1";
|
|
3868
|
+
function codeForStatus(status) {
|
|
3869
|
+
if (status === 400 || status === 409 || status === 422) {
|
|
3870
|
+
return "INVALID_INPUT";
|
|
3871
|
+
}
|
|
3872
|
+
if (status === 429 || status >= 500) {
|
|
3873
|
+
return "RPC_ERROR";
|
|
3874
|
+
}
|
|
3875
|
+
return "UNKNOWN";
|
|
3876
|
+
}
|
|
3877
|
+
function apiErrorMessage(json, status) {
|
|
3878
|
+
const err = json.error;
|
|
3879
|
+
if (typeof err === "string") {
|
|
3880
|
+
return err;
|
|
3881
|
+
}
|
|
3882
|
+
const msg = err?.message;
|
|
3883
|
+
return typeof msg === "string" ? msg : `HTTP ${status}`;
|
|
3884
|
+
}
|
|
3885
|
+
async function apiRequest(url, init) {
|
|
3886
|
+
const res = await fetch(url, {
|
|
3887
|
+
method: init?.method ?? (init?.body === void 0 ? "GET" : "POST"),
|
|
3888
|
+
headers: {
|
|
3889
|
+
accept: "application/json",
|
|
3890
|
+
...init?.body === void 0 ? {} : { "Content-Type": "application/json" }
|
|
3891
|
+
},
|
|
3892
|
+
body: init?.body === void 0 ? void 0 : JSON.stringify(init.body)
|
|
3893
|
+
});
|
|
3894
|
+
const json = await res.json().catch(() => ({}));
|
|
3895
|
+
return { ok: res.ok, status: res.status, json };
|
|
3896
|
+
}
|
|
3897
|
+
async function apiJson(url, init) {
|
|
3898
|
+
const res = await apiRequest(url, init);
|
|
3899
|
+
if (!res.ok) {
|
|
3900
|
+
throw new T2000Error(codeForStatus(res.status), apiErrorMessage(res.json, res.status), {
|
|
3901
|
+
status: res.status,
|
|
3902
|
+
...res.json.error && typeof res.json.error === "object" ? { api: res.json.error } : {}
|
|
3903
|
+
});
|
|
3904
|
+
}
|
|
3905
|
+
return res.json;
|
|
3906
|
+
}
|
|
3907
|
+
function invalidInput(message) {
|
|
3908
|
+
return new T2000Error("INVALID_INPUT", message);
|
|
3909
|
+
}
|
|
3910
|
+
async function signPreparedTx(base, action, signer, txBytes) {
|
|
3911
|
+
runSponsoredTxGuard({ base, action, txBytes });
|
|
3912
|
+
const { signature } = await signer.signTransaction(fromBase64(txBytes));
|
|
3913
|
+
return signature;
|
|
3914
|
+
}
|
|
3915
|
+
|
|
3916
|
+
// src/commerce/endpoint.ts
|
|
3917
|
+
function endpointIssueLines(prep) {
|
|
3918
|
+
const lines = (prep.probe?.issues ?? []).map(
|
|
3919
|
+
(i) => ` \u2717 ${i.message ?? i.code}`
|
|
3920
|
+
);
|
|
3921
|
+
for (const r of prep.routes ?? []) {
|
|
3922
|
+
if (r.probeOk === false) {
|
|
3923
|
+
lines.push(` \u2717 ${r.method ?? "POST"} ${r.path}`);
|
|
3924
|
+
for (const i of r.issues ?? []) {
|
|
3925
|
+
lines.push(` ${i.message ?? i.code}`);
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
}
|
|
3929
|
+
return lines;
|
|
3930
|
+
}
|
|
3931
|
+
async function setEndpoint(apiBase, signer, endpoint, primary) {
|
|
3932
|
+
const address = signer.getAddress();
|
|
3933
|
+
runSponsoredTxGuard({ base: apiBase, action: "update" });
|
|
3934
|
+
const res = await apiRequest(`${apiBase}/agent/endpoint/prepare`, {
|
|
3935
|
+
method: "POST",
|
|
3936
|
+
body: { address, endpoint, ...primary ? { primary } : {} }
|
|
3937
|
+
});
|
|
3938
|
+
const prep = res.json;
|
|
3939
|
+
if (!res.ok) {
|
|
3940
|
+
const msg = apiErrorMessage(prep, res.status);
|
|
3941
|
+
const detail = endpointIssueLines(prep).join("\n");
|
|
3942
|
+
throw new T2000Error(
|
|
3943
|
+
"INVALID_INPUT",
|
|
3944
|
+
detail ? `${msg}
|
|
3945
|
+
${detail}` : msg,
|
|
3946
|
+
{ status: res.status, probe: prep.probe ?? null, routes: prep.routes ?? [] }
|
|
3947
|
+
);
|
|
3948
|
+
}
|
|
3949
|
+
if (!(typeof prep.nonce === "string" && typeof prep.txBytes === "string")) {
|
|
3950
|
+
throw invalidInput("Failed to prepare the listing.");
|
|
3951
|
+
}
|
|
3952
|
+
const signature = await signPreparedTx(apiBase, "update", signer, prep.txBytes);
|
|
3953
|
+
const sub = await apiJson(`${apiBase}/agent/endpoint/submit`, {
|
|
3954
|
+
method: "POST",
|
|
3955
|
+
body: { nonce: prep.nonce, address, signature }
|
|
3956
|
+
});
|
|
3957
|
+
const listed = endpoint !== "";
|
|
3958
|
+
return {
|
|
3959
|
+
address,
|
|
3960
|
+
endpoint: listed ? prep.primary?.url ?? endpoint : null,
|
|
3961
|
+
listed,
|
|
3962
|
+
probe: prep.probe ?? null,
|
|
3963
|
+
origin: prep.origin ?? null,
|
|
3964
|
+
primary: prep.primary ?? null,
|
|
3965
|
+
routes: prep.routes ?? [],
|
|
3966
|
+
...typeof sub.digest === "string" ? { digest: sub.digest } : {}
|
|
3967
|
+
};
|
|
3968
|
+
}
|
|
3969
|
+
function listEndpoint(apiBase, signer, endpoint, opts = {}) {
|
|
3970
|
+
const target = endpoint.trim();
|
|
3971
|
+
if (!target) {
|
|
3972
|
+
throw invalidInput("Provide your x402 endpoint URL.");
|
|
3973
|
+
}
|
|
3974
|
+
return setEndpoint(apiBase, signer, target, opts.primary);
|
|
3975
|
+
}
|
|
3976
|
+
function removeEndpoint(apiBase, signer) {
|
|
3977
|
+
return setEndpoint(apiBase, signer, "");
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3980
|
+
// src/commerce/types.ts
|
|
3981
|
+
var AGENT_CATEGORIES = [
|
|
3982
|
+
"ai-models",
|
|
3983
|
+
"data-feeds",
|
|
3984
|
+
"finance",
|
|
3985
|
+
"research",
|
|
3986
|
+
"dev-tools",
|
|
3987
|
+
"creative",
|
|
3988
|
+
"travel",
|
|
3989
|
+
"comms",
|
|
3990
|
+
"other"
|
|
3991
|
+
];
|
|
3992
|
+
var SERVICE_TIERS = ["basic", "standard", "premium"];
|
|
3993
|
+
|
|
3994
|
+
// src/commerce/package-slug.ts
|
|
3995
|
+
var SERVICE_SLUG_RE = /^[a-z0-9][a-z0-9-]{1,47}$/;
|
|
3996
|
+
function trimDashes(s) {
|
|
3997
|
+
let start = 0;
|
|
3998
|
+
let end = s.length;
|
|
3999
|
+
while (start < end && s.charCodeAt(start) === 45) start += 1;
|
|
4000
|
+
while (end > start && s.charCodeAt(end - 1) === 45) end -= 1;
|
|
4001
|
+
return s.slice(start, end);
|
|
4002
|
+
}
|
|
4003
|
+
function slugify(name) {
|
|
4004
|
+
return trimDashes(name.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-")).slice(0, 48);
|
|
4005
|
+
}
|
|
4006
|
+
var TIER_SLUG_RE = /^(.+)-(basic|standard|premium)$/;
|
|
4007
|
+
var MAX_TIER_BASE_LENGTH = 48 - "-standard".length;
|
|
4008
|
+
function parseServiceTierSlug(slug) {
|
|
4009
|
+
const m = TIER_SLUG_RE.exec(slug);
|
|
4010
|
+
if (!m) {
|
|
4011
|
+
return null;
|
|
4012
|
+
}
|
|
4013
|
+
return { base: m[1], tier: m[2] };
|
|
4014
|
+
}
|
|
4015
|
+
function packageBaseSlug(slugified) {
|
|
4016
|
+
const cut = slugified.slice(0, MAX_TIER_BASE_LENGTH);
|
|
4017
|
+
let end = cut.length;
|
|
4018
|
+
while (end > 0 && cut.charCodeAt(end - 1) === 45) end -= 1;
|
|
4019
|
+
return cut.slice(0, end);
|
|
4020
|
+
}
|
|
4021
|
+
function packageTierSlugs(base) {
|
|
4022
|
+
return SERVICE_TIERS.map((tier) => ({ tier, slug: `${base}-${tier}` }));
|
|
4023
|
+
}
|
|
4024
|
+
|
|
4025
|
+
// src/commerce/challenge.ts
|
|
4026
|
+
async function sha256Hex2(content) {
|
|
4027
|
+
const digest = await crypto.subtle.digest(
|
|
4028
|
+
"SHA-256",
|
|
4029
|
+
new TextEncoder().encode(content)
|
|
4030
|
+
);
|
|
4031
|
+
return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
4032
|
+
}
|
|
4033
|
+
function servicePayloadSha256(payload) {
|
|
4034
|
+
return sha256Hex2(JSON.stringify(payload));
|
|
4035
|
+
}
|
|
4036
|
+
function profileChallengeMessage(nonce) {
|
|
4037
|
+
return `t2000-agent-profile:${nonce}`;
|
|
4038
|
+
}
|
|
4039
|
+
function serviceChallengeMessage(nonce, payloadHash) {
|
|
4040
|
+
return `t2000-agent-service:${nonce}:${payloadHash}`;
|
|
4041
|
+
}
|
|
4042
|
+
async function fetchChallengeNonce(apiBase, address) {
|
|
4043
|
+
const challenge = await apiJson(`${apiBase}/agent/challenge`, {
|
|
4044
|
+
method: "POST",
|
|
4045
|
+
body: { address }
|
|
4046
|
+
});
|
|
4047
|
+
const nonce = challenge.nonce;
|
|
4048
|
+
if (typeof nonce !== "string" || !nonce) {
|
|
4049
|
+
throw invalidInput("Failed to get a challenge nonce.");
|
|
4050
|
+
}
|
|
4051
|
+
return nonce;
|
|
4052
|
+
}
|
|
4053
|
+
async function signChallenge(apiBase, signer, message) {
|
|
4054
|
+
const nonce = await fetchChallengeNonce(apiBase, signer.getAddress());
|
|
4055
|
+
const text = await message(nonce);
|
|
4056
|
+
const { signature } = await signer.signPersonalMessage(
|
|
4057
|
+
new TextEncoder().encode(text)
|
|
4058
|
+
);
|
|
4059
|
+
return { nonce, signature };
|
|
4060
|
+
}
|
|
4061
|
+
|
|
4062
|
+
// src/commerce/service.ts
|
|
4063
|
+
function serviceUpsertPayload(input) {
|
|
4064
|
+
const slug = input.slug.trim().toLowerCase();
|
|
4065
|
+
if (!SERVICE_SLUG_RE.test(slug)) {
|
|
4066
|
+
throw invalidInput(
|
|
4067
|
+
"slug must be 2-48 chars of [a-z0-9-], starting alphanumeric."
|
|
4068
|
+
);
|
|
4069
|
+
}
|
|
4070
|
+
return {
|
|
4071
|
+
...input.mode ? { mode: input.mode } : {},
|
|
4072
|
+
slug,
|
|
4073
|
+
name: input.name.trim(),
|
|
4074
|
+
description: input.description.trim(),
|
|
4075
|
+
priceUsdc: input.priceUsdc,
|
|
4076
|
+
slaMinutes: input.slaMinutes,
|
|
4077
|
+
reviewWindowMinutes: input.reviewWindowMinutes ?? 1440,
|
|
4078
|
+
rejectSplitBps: input.rejectSplitBps ?? 8e3,
|
|
4079
|
+
requirements: input.requirements,
|
|
4080
|
+
deliverable: input.deliverable.trim(),
|
|
4081
|
+
...input.examples === void 0 ? {} : { examples: input.examples }
|
|
4082
|
+
};
|
|
4083
|
+
}
|
|
4084
|
+
async function signedServiceAction(apiBase, signer, action, payload) {
|
|
4085
|
+
const address = signer.getAddress();
|
|
4086
|
+
const { nonce, signature } = await signChallenge(
|
|
4087
|
+
apiBase,
|
|
4088
|
+
signer,
|
|
4089
|
+
async (n) => serviceChallengeMessage(n, await servicePayloadSha256(payload))
|
|
4090
|
+
);
|
|
4091
|
+
return apiJson(`${apiBase}/agent/service`, {
|
|
4092
|
+
method: "POST",
|
|
4093
|
+
body: { address, nonce, signature, action, payload }
|
|
4094
|
+
});
|
|
4095
|
+
}
|
|
4096
|
+
async function upsertService(apiBase, signer, input) {
|
|
4097
|
+
const payload = serviceUpsertPayload(input);
|
|
4098
|
+
const response = await signedServiceAction(apiBase, signer, "upsert", payload);
|
|
4099
|
+
return { address: signer.getAddress(), slug: payload.slug, response };
|
|
4100
|
+
}
|
|
4101
|
+
async function retireService(apiBase, signer, slug) {
|
|
4102
|
+
const clean = slug.trim().toLowerCase();
|
|
4103
|
+
if (!SERVICE_SLUG_RE.test(clean)) {
|
|
4104
|
+
throw invalidInput("slug must be 2-48 chars of [a-z0-9-], starting alphanumeric.");
|
|
4105
|
+
}
|
|
4106
|
+
const response = await signedServiceAction(apiBase, signer, "retire", {
|
|
4107
|
+
slug: clean
|
|
4108
|
+
});
|
|
4109
|
+
return { address: signer.getAddress(), slug: clean, response };
|
|
4110
|
+
}
|
|
4111
|
+
|
|
4112
|
+
// src/commerce/package.ts
|
|
4113
|
+
function planPackage(input) {
|
|
4114
|
+
const name = input.name.trim();
|
|
4115
|
+
if (!name) {
|
|
4116
|
+
throw invalidInput("name is required.");
|
|
4117
|
+
}
|
|
4118
|
+
const base = packageBaseSlug((input.baseSlug ?? slugify(name)).trim().toLowerCase());
|
|
4119
|
+
if (!base || !SERVICE_SLUG_RE.test(`${base}-basic`)) {
|
|
4120
|
+
throw invalidInput(
|
|
4121
|
+
"Could not derive a package slug from the name \u2014 pass baseSlug (a-z, 0-9, dashes)."
|
|
4122
|
+
);
|
|
4123
|
+
}
|
|
4124
|
+
const byTier = /* @__PURE__ */ new Map();
|
|
4125
|
+
for (const t of input.tiers) {
|
|
4126
|
+
if (!SERVICE_TIERS.includes(t.tier)) {
|
|
4127
|
+
throw invalidInput(`Unknown tier "${t.tier}" \u2014 use basic, standard, premium.`);
|
|
4128
|
+
}
|
|
4129
|
+
if (byTier.has(t.tier)) {
|
|
4130
|
+
throw invalidInput(`Tier "${t.tier}" given twice.`);
|
|
4131
|
+
}
|
|
4132
|
+
byTier.set(t.tier, t);
|
|
4133
|
+
}
|
|
4134
|
+
const missing = SERVICE_TIERS.filter((t) => !byTier.has(t));
|
|
4135
|
+
if (missing.length > 0) {
|
|
4136
|
+
throw invalidInput(
|
|
4137
|
+
`A package needs all three tiers \u2014 missing: ${missing.join(", ")}.`
|
|
4138
|
+
);
|
|
4139
|
+
}
|
|
4140
|
+
return {
|
|
4141
|
+
base,
|
|
4142
|
+
tiers: packageTierSlugs(base).map(({ tier, slug }) => {
|
|
4143
|
+
const t = byTier.get(tier);
|
|
4144
|
+
return {
|
|
4145
|
+
tier,
|
|
4146
|
+
slug,
|
|
4147
|
+
input: {
|
|
4148
|
+
mode: "create",
|
|
4149
|
+
slug,
|
|
4150
|
+
name,
|
|
4151
|
+
description: (t.description ?? input.description).trim(),
|
|
4152
|
+
priceUsdc: t.priceUsdc,
|
|
4153
|
+
slaMinutes: t.slaMinutes ?? input.slaMinutes,
|
|
4154
|
+
deliverable: t.deliverable,
|
|
4155
|
+
requirements: input.requirements,
|
|
4156
|
+
reviewWindowMinutes: t.reviewWindowMinutes ?? input.reviewWindowMinutes,
|
|
4157
|
+
rejectSplitBps: t.rejectSplitBps ?? input.rejectSplitBps
|
|
4158
|
+
}
|
|
4159
|
+
};
|
|
4160
|
+
})
|
|
4161
|
+
};
|
|
4162
|
+
}
|
|
4163
|
+
async function createPackage(apiBase, signer, input) {
|
|
4164
|
+
const plan = planPackage(input);
|
|
4165
|
+
const tiers = [];
|
|
4166
|
+
for (const t of plan.tiers) {
|
|
4167
|
+
await upsertService(apiBase, signer, t.input);
|
|
4168
|
+
tiers.push({ tier: t.tier, slug: t.slug, priceUsdc: t.input.priceUsdc });
|
|
4169
|
+
}
|
|
4170
|
+
return { address: signer.getAddress(), base: plan.base, tiers };
|
|
4171
|
+
}
|
|
4172
|
+
|
|
4173
|
+
// src/commerce/resolve.ts
|
|
4174
|
+
init_errors();
|
|
4175
|
+
var FALLBACK_MISS = "Use an Agent ID (#93), @handle, or full 0x\u2026 address.";
|
|
4176
|
+
function agentResolveUrl(q, apiBase = DEFAULT_COMMERCE_API_BASE2) {
|
|
4177
|
+
return `${apiBase}/agents/resolve?q=${encodeURIComponent(q.trim())}`;
|
|
4178
|
+
}
|
|
4179
|
+
async function resolveAgentRef(q, apiBase = DEFAULT_COMMERCE_API_BASE2) {
|
|
4180
|
+
const res = await apiRequest(agentResolveUrl(q, apiBase));
|
|
4181
|
+
const json = res.json;
|
|
4182
|
+
if (!(res.ok && typeof json.address === "string")) {
|
|
4183
|
+
throw new T2000Error(
|
|
4184
|
+
"CONTACT_NOT_FOUND",
|
|
4185
|
+
typeof json.error === "string" ? json.error : FALLBACK_MISS,
|
|
4186
|
+
{ ref: q }
|
|
4187
|
+
);
|
|
4188
|
+
}
|
|
4189
|
+
return {
|
|
4190
|
+
address: json.address,
|
|
4191
|
+
...typeof json.numericId === "number" || json.numericId === null ? { numericId: json.numericId } : {},
|
|
4192
|
+
...typeof json.name === "string" ? { name: json.name } : {}
|
|
4193
|
+
};
|
|
4194
|
+
}
|
|
4195
|
+
async function getAgentProfile(address, apiBase = DEFAULT_COMMERCE_API_BASE2) {
|
|
4196
|
+
const res = await apiRequest(`${apiBase}/agents/${encodeURIComponent(address)}`);
|
|
4197
|
+
if (!res.ok) {
|
|
4198
|
+
return null;
|
|
4199
|
+
}
|
|
4200
|
+
return { ...res.json, address };
|
|
4201
|
+
}
|
|
4202
|
+
|
|
4203
|
+
// src/commerce/profile.ts
|
|
4204
|
+
function parseAgentCategory(raw) {
|
|
4205
|
+
const c = raw.trim().toLowerCase();
|
|
4206
|
+
if (!AGENT_CATEGORIES.includes(c)) {
|
|
4207
|
+
throw invalidInput(
|
|
4208
|
+
`category must be one of: ${AGENT_CATEGORIES.join(", ")} (got "${raw}").`
|
|
4209
|
+
);
|
|
4210
|
+
}
|
|
4211
|
+
return c;
|
|
4212
|
+
}
|
|
4213
|
+
async function updateProfile(apiBase, signer, input) {
|
|
4214
|
+
const hasField = input.name !== void 0 || input.imageUrl !== void 0 || input.description !== void 0 || input.category !== void 0 || input.website !== void 0 || input.twitter !== void 0 || input.github !== void 0;
|
|
4215
|
+
if (!hasField) {
|
|
4216
|
+
throw invalidInput(
|
|
4217
|
+
"Provide at least one of name, imageUrl, description, category, website, twitter, github."
|
|
4218
|
+
);
|
|
4219
|
+
}
|
|
4220
|
+
const category = input.category === void 0 ? void 0 : parseAgentCategory(input.category);
|
|
4221
|
+
const address = signer.getAddress();
|
|
4222
|
+
const { nonce, signature } = await signChallenge(
|
|
4223
|
+
apiBase,
|
|
4224
|
+
signer,
|
|
4225
|
+
profileChallengeMessage
|
|
4226
|
+
);
|
|
4227
|
+
await apiJson(`${apiBase}/agent/profile`, {
|
|
4228
|
+
method: "POST",
|
|
4229
|
+
body: {
|
|
4230
|
+
address,
|
|
4231
|
+
nonce,
|
|
4232
|
+
signature,
|
|
4233
|
+
displayName: input.name,
|
|
4234
|
+
imageUrl: input.imageUrl,
|
|
4235
|
+
description: input.description,
|
|
4236
|
+
category,
|
|
4237
|
+
website: input.website,
|
|
4238
|
+
twitter: input.twitter,
|
|
4239
|
+
github: input.github
|
|
4240
|
+
}
|
|
4241
|
+
});
|
|
4242
|
+
return { address };
|
|
4243
|
+
}
|
|
4244
|
+
async function ensureCategory(apiBase, signer, category) {
|
|
4245
|
+
if (category !== void 0) {
|
|
4246
|
+
const parsed = parseAgentCategory(category);
|
|
4247
|
+
await updateProfile(apiBase, signer, { category: parsed });
|
|
4248
|
+
return parsed;
|
|
4249
|
+
}
|
|
4250
|
+
const profile = await getAgentProfile(signer.getAddress(), apiBase).catch(
|
|
4251
|
+
() => null
|
|
4252
|
+
);
|
|
4253
|
+
const existing = typeof profile?.category === "string" && profile.category ? profile.category : null;
|
|
4254
|
+
if (!existing) {
|
|
4255
|
+
throw invalidInput(
|
|
4256
|
+
`Pick a directory category first \u2014 buyers browse listings by category. Set one of ${AGENT_CATEGORIES.join(" | ")} (updateProfile({ category }) / t2 agent profile --category).`
|
|
4257
|
+
);
|
|
4258
|
+
}
|
|
4259
|
+
return existing;
|
|
4260
|
+
}
|
|
4261
|
+
|
|
4262
|
+
// src/commerce/register.ts
|
|
4263
|
+
async function registerAgent(apiBase, signer) {
|
|
4264
|
+
const address = signer.getAddress();
|
|
4265
|
+
runSponsoredTxGuard({ base: apiBase, action: "register" });
|
|
4266
|
+
const prep = await apiJson(`${apiBase}/agent/register/prepare`, {
|
|
4267
|
+
method: "POST",
|
|
4268
|
+
body: { address }
|
|
4269
|
+
});
|
|
4270
|
+
if (prep.alreadyRegistered === true) {
|
|
4271
|
+
return { address, alreadyRegistered: true };
|
|
4272
|
+
}
|
|
4273
|
+
const regNonce = prep.regNonce;
|
|
4274
|
+
const txBytes = prep.txBytes;
|
|
4275
|
+
if (!(typeof regNonce === "string" && typeof txBytes === "string")) {
|
|
4276
|
+
throw invalidInput("Failed to prepare registration.");
|
|
4277
|
+
}
|
|
4278
|
+
const signature = await signPreparedTx(apiBase, "register", signer, txBytes);
|
|
4279
|
+
const res = await apiJson(`${apiBase}/agent/register/submit`, {
|
|
4280
|
+
method: "POST",
|
|
4281
|
+
body: { regNonce, address, agentSignature: signature }
|
|
4282
|
+
});
|
|
4283
|
+
return {
|
|
4284
|
+
address,
|
|
4285
|
+
alreadyRegistered: res.alreadyRegistered === true,
|
|
4286
|
+
...typeof res.digest === "string" ? { digest: res.digest } : {}
|
|
4287
|
+
};
|
|
4288
|
+
}
|
|
4289
|
+
|
|
4290
|
+
// src/commerce/client.ts
|
|
4291
|
+
var CommerceClient = class {
|
|
4292
|
+
signer;
|
|
4293
|
+
apiBase;
|
|
4294
|
+
constructor(options) {
|
|
4295
|
+
this.signer = options.signer;
|
|
4296
|
+
let base = options.apiBase ?? DEFAULT_COMMERCE_API_BASE2;
|
|
4297
|
+
while (base.endsWith("/")) base = base.slice(0, -1);
|
|
4298
|
+
this.apiBase = base;
|
|
4299
|
+
}
|
|
4300
|
+
/** This signer's wallet address. */
|
|
4301
|
+
get address() {
|
|
4302
|
+
return this.signer.getAddress();
|
|
4303
|
+
}
|
|
4304
|
+
/** Register the wallet as an on-chain Agent ID (sponsored; idempotent). */
|
|
4305
|
+
register() {
|
|
4306
|
+
return registerAgent(this.apiBase, this.signer);
|
|
4307
|
+
}
|
|
4308
|
+
/** Set public profile fields (signed, no gas). */
|
|
4309
|
+
updateProfile(input) {
|
|
4310
|
+
return updateProfile(this.apiBase, this.signer, input);
|
|
4311
|
+
}
|
|
4312
|
+
/** The sell gate — set `category` or confirm the live one; throws when
|
|
4313
|
+
* neither exists. Returns the category in force. */
|
|
4314
|
+
ensureCategory(category) {
|
|
4315
|
+
return ensureCategory(this.apiBase, this.signer, category);
|
|
4316
|
+
}
|
|
4317
|
+
/** This seller's public profile (null when unregistered). */
|
|
4318
|
+
profile() {
|
|
4319
|
+
return getAgentProfile(this.address, this.apiBase);
|
|
4320
|
+
}
|
|
4321
|
+
/** List (or fully re-write) one service — `mode: "create"` refuses a live slug. */
|
|
4322
|
+
upsertService(input) {
|
|
4323
|
+
return upsertService(this.apiBase, this.signer, input);
|
|
4324
|
+
}
|
|
4325
|
+
/** Take a service off the board (funded jobs keep settling on-chain). */
|
|
4326
|
+
retireService(input) {
|
|
4327
|
+
return retireService(
|
|
4328
|
+
this.apiBase,
|
|
4329
|
+
this.signer,
|
|
4330
|
+
typeof input === "string" ? input : input.slug
|
|
4331
|
+
);
|
|
4332
|
+
}
|
|
4333
|
+
/** Three tiers under one name — `{base}-basic|standard|premium`. */
|
|
4334
|
+
createPackage(input) {
|
|
4335
|
+
return createPackage(this.apiBase, this.signer, input);
|
|
4336
|
+
}
|
|
4337
|
+
/** Sell an x402 API (origin or one 402 URL) — live-probed, sponsored. */
|
|
4338
|
+
listEndpoint(endpoint, opts = {}) {
|
|
4339
|
+
return listEndpoint(this.apiBase, this.signer, endpoint, opts);
|
|
4340
|
+
}
|
|
4341
|
+
/** Clear the x402 listing. */
|
|
4342
|
+
removeEndpoint() {
|
|
4343
|
+
return removeEndpoint(this.apiBase, this.signer);
|
|
4344
|
+
}
|
|
4345
|
+
/** `#93` · `@handle` · `name.sui` · `0x…` → wallet (marketplace refs only). */
|
|
4346
|
+
resolveRef(q) {
|
|
4347
|
+
return resolveAgentRef(q, this.apiBase);
|
|
4348
|
+
}
|
|
4349
|
+
};
|
|
4350
|
+
|
|
4184
4351
|
// src/utils/resolve-created.ts
|
|
4185
4352
|
var OPENING_TYPE_MARKER = "::opening::Opening<";
|
|
4186
4353
|
var ESCROW_JOB_TYPE_MARKER = "::escrow::Job<";
|
|
@@ -4622,4 +4789,4 @@ function displayHandle(label, parentName = AUDRIC_PARENT_NAME) {
|
|
|
4622
4789
|
// src/index.ts
|
|
4623
4790
|
init_preflight();
|
|
4624
4791
|
|
|
4625
|
-
export { A2A_ESCROW_FEE_CONFIG_ID, A2A_ESCROW_LATEST_PACKAGE_ID, A2A_ESCROW_OPENING_PACKAGE_ID, A2A_ESCROW_PACKAGE_ID, A2A_ESCROW_PACKAGE_V2_ID, A2A_ESCROW_PACKAGE_V3_ID, A2A_ESCROW_PACKAGE_V6_ID, A2A_ESCROW_PACKAGE_V7_ID, A2A_ESCROW_PACKAGE_V8_ID, A2A_SCORE_BOARD_ID, AUDRIC_PARENT, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, CETUS_USDC_SUI_POOL, CLOCK_ID, COIN_REGISTRY, DEFAULT_ACTIVITY_REPORT_URL, DEFAULT_API_BASE, DEFAULT_COMMERCE_API_BASE, DEFAULT_GRPC_URL, DEFAULT_NETWORK, ESCROW_JOB_TYPE_MARKER, ETH_TYPE, GASLESS_MIN_STABLE_AMOUNT, GASLESS_STABLE_TYPES, GAS_RESERVE_MIN, IKA_TYPE, InvalidAddressError, JOB_STATES, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, LimitEnforcer, LimitExceededError, MAINNET_A2A_ESCROW_LATEST_PACKAGE_ID, MAINNET_A2A_ESCROW_OPENING_PACKAGE_ID, MAINNET_A2A_ESCROW_PACKAGE_ID, MAINNET_A2A_SCORE_BOARD_ID, MANIFEST_TYPE, MAX_DELIVER_HORIZON_MS, MAX_JOB_USDC, MAX_OPEN_WINDOW_MS, MAX_REVIEW_WINDOW_MS, MIN_JOB_USDC, MIST_PER_SUI, NAVX_TYPE, OPENING_CLAIM_POLICIES, OPENING_CLAIM_POLICY_ANY_ACTIVE, OPENING_CLAIM_POLICY_PROVEN, OPENING_CLAIM_POLICY_PROVEN_4STAR, OPENING_TYPE_MARKER, OPERATION_ASSETS, OVERLAY_FEE_RATE, PREFLIGHT_MAX_AMOUNT, PREFLIGHT_OK, PROVEN_MIN_AVG_STARS_X10, PROVEN_MIN_REVIEWS, REVIEW_MAX_STARS, REVIEW_MIN_STARS, SENDABLE_ASSETS, SPONSORED_PYTH_DEPENDENT_PROVIDERS, STABLE_ASSETS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, SuinsNotRegisteredError, SuinsRpcError, T2000, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, WAL_TYPE, WBTC_TYPE, WRITE_APPENDER_REGISTRY, ZkLoginSigner, addSendToTx, addSwapToTx, approxUsdValue, assertAllowedAsset, assertBuyerRequirements, assertLimitConfig, buildAddLeafTx, buildCancelOpeningTx, buildClaimOpeningTx, buildCreateEmptyScoreTx, buildCreateJobTx, buildCreateOpeningTx, buildDeclineJobTx, buildDeliverJobTx, buildRefundJobTx, buildRefundUnclaimedTx, buildRejectJobTx, buildReleaseJobTx, buildRevokeLeafTx, buildSendTx, buildSubmitFirstReviewTx, buildSubmitReviewTx, buildSwapTx, cancelOpenJob, canonicalizeRecipientInput, chatCompletion, chatCompletionStream, checkPositiveAmount, checkSuiAddress, claimOpenJob, claimPolicyLabel, claimPolicyRequirement, classifyAction, classifyLabel, classifySendAsset, classifyTransaction, clearLimits, composeTx, customHireEnvelope, dailySpentToday, deriveAgentScoreId, deriveAllowedAddressesFromPtb, deserializeCetusRoute, displayHandle, executeTx, exportPrivateKey, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, fetchAllCoins, fetchService, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fullHandle, generateKeypair, getAddress, getAgentScore, getCoinMeta, getDecimals, getDecimalsForCoinType, getJob, getJobSpec, getLimits, getOpenJob, getOpening, getSponsoredSwapProviders, getSuiClient, getSuiGrpcClient, getSwapQuote, hasLimits, invalidSendAssetMessage, isAllowedAsset, isCetusRouteFresh, isCustomHireEnvelope, isInRegistry, jobActionsFor, keypairFromPrivateKey, listModels, listOpenJobs, listServices, loadKey, looksLikeSuiNs, mapMoveAbortCode, mapWalletError, meetsClaimPolicy, mistToSui, normalizeAddressInput, normalizeAsset, normalizeCoinType, parseSuiRpcTx, payWithX402, postOpenJob, preflightCreateJob, preflightCreateOpening, preflightFail, preflightPay, preflightSend, preflightSwap, probeX402, putJobSpec, queryBalance, queryHistory, queryTransaction, rawToStable, rawToUsdc, readLimitsFile, recordDailySpend, refineLendingLabel, refundOpenJob, reportX402Activity, resolveAddressToSuinsViaRpc, resolveCreatedObjectId, resolveSuinsViaRpc, resolveSymbol, resolveTokenType, saveBech32, saveKey, selectAndSplitCoin, selectSuiCoin, serializeCetusRoute, setLimits, setSponsoredTxGuard, simulateTransaction, stableToRaw, submitJobReview, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, validateLabel, verifyCetusRouteCoinMatch, verifyJobForSeller,
|
|
4792
|
+
export { A2A_ESCROW_FEE_CONFIG_ID, A2A_ESCROW_LATEST_PACKAGE_ID, A2A_ESCROW_OPENING_PACKAGE_ID, A2A_ESCROW_PACKAGE_ID, A2A_ESCROW_PACKAGE_V2_ID, A2A_ESCROW_PACKAGE_V3_ID, A2A_ESCROW_PACKAGE_V6_ID, A2A_ESCROW_PACKAGE_V7_ID, A2A_ESCROW_PACKAGE_V8_ID, A2A_SCORE_BOARD_ID, AGENT_CATEGORIES, AUDRIC_PARENT, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, CETUS_USDC_SUI_POOL, CLOCK_ID, COIN_REGISTRY, CommerceClient, DEFAULT_ACTIVITY_REPORT_URL, DEFAULT_API_BASE, DEFAULT_COMMERCE_API_BASE, DEFAULT_GRPC_URL, DEFAULT_NETWORK, ESCROW_JOB_TYPE_MARKER, ETH_TYPE, GASLESS_MIN_STABLE_AMOUNT, GASLESS_STABLE_TYPES, GAS_RESERVE_MIN, IKA_TYPE, InvalidAddressError, JOB_STATES, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, LimitEnforcer, LimitExceededError, MAINNET_A2A_ESCROW_LATEST_PACKAGE_ID, MAINNET_A2A_ESCROW_OPENING_PACKAGE_ID, MAINNET_A2A_ESCROW_PACKAGE_ID, MAINNET_A2A_SCORE_BOARD_ID, MANIFEST_TYPE, MAX_DELIVER_HORIZON_MS, MAX_JOB_USDC, MAX_OPEN_WINDOW_MS, MAX_REVIEW_WINDOW_MS, MAX_TIER_BASE_LENGTH, MIN_JOB_USDC, MIST_PER_SUI, NAVX_TYPE, OPENING_CLAIM_POLICIES, OPENING_CLAIM_POLICY_ANY_ACTIVE, OPENING_CLAIM_POLICY_PROVEN, OPENING_CLAIM_POLICY_PROVEN_4STAR, OPENING_TYPE_MARKER, OPERATION_ASSETS, OVERLAY_FEE_RATE, PREFLIGHT_MAX_AMOUNT, PREFLIGHT_OK, PROVEN_MIN_AVG_STARS_X10, PROVEN_MIN_REVIEWS, REVIEW_MAX_STARS, REVIEW_MIN_STARS, SENDABLE_ASSETS, SERVICE_SLUG_RE, SERVICE_TIERS, SPONSORED_PYTH_DEPENDENT_PROVIDERS, STABLE_ASSETS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, SuinsNotRegisteredError, SuinsRpcError, T2000, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, WAL_TYPE, WBTC_TYPE, WRITE_APPENDER_REGISTRY, ZkLoginSigner, addSendToTx, addSwapToTx, agentResolveUrl, approxUsdValue, assertAllowedAsset, assertBuyerRequirements, assertLimitConfig, buildAddLeafTx, buildCancelOpeningTx, buildClaimOpeningTx, buildCreateEmptyScoreTx, buildCreateJobTx, buildCreateOpeningTx, buildDeclineJobTx, buildDeliverJobTx, buildRefundJobTx, buildRefundUnclaimedTx, buildRejectJobTx, buildReleaseJobTx, buildRevokeLeafTx, buildSendTx, buildSubmitFirstReviewTx, buildSubmitReviewTx, buildSwapTx, cancelOpenJob, canonicalizeRecipientInput, chatCompletion, chatCompletionStream, checkPositiveAmount, checkSuiAddress, claimOpenJob, claimPolicyLabel, claimPolicyRequirement, classifyAction, classifyLabel, classifySendAsset, classifyTransaction, clearLimits, composeTx, createPackage, customHireEnvelope, dailySpentToday, deriveAgentScoreId, deriveAllowedAddressesFromPtb, deserializeCetusRoute, displayHandle, endpointIssueLines, ensureCategory, executeTx, exportPrivateKey, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, fetchAllCoins, fetchChallengeNonce, fetchService, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fullHandle, generateKeypair, getAddress, getAgentProfile, getAgentScore, getCoinMeta, getDecimals, getDecimalsForCoinType, getJob, getJobSpec, getLimits, getOpenJob, getOpening, getSponsoredSwapProviders, getSuiClient, getSuiGrpcClient, getSwapQuote, hasLimits, invalidSendAssetMessage, isAllowedAsset, isCetusRouteFresh, isCustomHireEnvelope, isInRegistry, jobActionsFor, keypairFromPrivateKey, listEndpoint, listModels, listOpenJobs, listServices, loadKey, looksLikeSuiNs, mapMoveAbortCode, mapWalletError, meetsClaimPolicy, mistToSui, normalizeAddressInput, normalizeAsset, normalizeCoinType, packageBaseSlug, packageTierSlugs, parseAgentCategory, parseServiceTierSlug, parseSuiRpcTx, payWithX402, planPackage, postOpenJob, preflightCreateJob, preflightCreateOpening, preflightFail, preflightPay, preflightSend, preflightSwap, probeX402, profileChallengeMessage, putJobSpec, queryBalance, queryHistory, queryTransaction, rawToStable, rawToUsdc, readLimitsFile, recordDailySpend, refineLendingLabel, refundOpenJob, registerAgent, removeEndpoint, reportX402Activity, resolveAddressToSuinsViaRpc, resolveAgentRef, resolveCreatedObjectId, resolveSuinsViaRpc, resolveSymbol, resolveTokenType, retireService, saveBech32, saveKey, selectAndSplitCoin, selectSuiCoin, serializeCetusRoute, serviceChallengeMessage, servicePayloadSha256, serviceUpsertPayload, setLimits, setSponsoredTxGuard, signChallenge, simulateTransaction, slugify, stableToRaw, submitJobReview, suiToMist, throwIfSimulationFailed, trimDashes, truncateAddress, updateProfile, upsertService, usdcToRaw, validateAddress, validateLabel, verifyCetusRouteCoinMatch, verifyJobForSeller, walletExists, writeLimitsFile };
|