@t2000/sdk 10.35.1 → 10.36.1
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 +2 -0
- package/dist/browser.cjs +11 -2
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +11 -2
- package/dist/{commerce-9K049Ggc.d.cts → commerce-C0B4y1uP.d.cts} +36 -5
- package/dist/{commerce-9K049Ggc.d.ts → commerce-C0B4y1uP.d.ts} +36 -5
- package/dist/index.cjs +42 -363
- package/dist/index.d.cts +32 -83
- package/dist/index.d.ts +32 -83
- package/dist/index.js +43 -363
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -13,10 +13,6 @@ var cryptography = require('@mysten/sui/cryptography');
|
|
|
13
13
|
var promises = require('fs/promises');
|
|
14
14
|
var path = require('path');
|
|
15
15
|
var os = require('os');
|
|
16
|
-
var ed25519$1 = require('@noble/curves/ed25519');
|
|
17
|
-
var secp256k1 = require('@noble/curves/secp256k1');
|
|
18
|
-
var sha256 = require('@noble/hashes/sha256');
|
|
19
|
-
var utils$1 = require('@noble/hashes/utils');
|
|
20
16
|
var fs = require('fs');
|
|
21
17
|
var bcs = require('@mysten/sui/bcs');
|
|
22
18
|
var suins = require('@mysten/suins');
|
|
@@ -1427,10 +1423,10 @@ async function finalize(response, opts) {
|
|
|
1427
1423
|
return { status: response.status, body: body2, paid: opts.paid };
|
|
1428
1424
|
}
|
|
1429
1425
|
async function makeGrpcBuildClient(client) {
|
|
1430
|
-
const { SuiGrpcClient:
|
|
1426
|
+
const { SuiGrpcClient: SuiGrpcClient2 } = await import('@mysten/sui/grpc');
|
|
1431
1427
|
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
1432
1428
|
const baseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
1433
|
-
return new
|
|
1429
|
+
return new SuiGrpcClient2({ baseUrl, network });
|
|
1434
1430
|
}
|
|
1435
1431
|
function atomicToHuman(raw, decimals) {
|
|
1436
1432
|
return Number(raw) / 10 ** decimals;
|
|
@@ -2182,8 +2178,7 @@ function body(params, stream) {
|
|
|
2182
2178
|
return JSON.stringify({
|
|
2183
2179
|
model: params.model,
|
|
2184
2180
|
messages: params.messages,
|
|
2185
|
-
// include_usage → the final stream chunk carries usage
|
|
2186
|
-
// (the confidential attestation receipt) so we can surface it after a stream.
|
|
2181
|
+
// include_usage → the final stream chunk carries usage.
|
|
2187
2182
|
...stream ? { stream: true, stream_options: { include_usage: true } } : {},
|
|
2188
2183
|
...params.maxTokens != null ? { max_tokens: params.maxTokens } : {},
|
|
2189
2184
|
...params.temperature != null ? { temperature: params.temperature } : {}
|
|
@@ -2200,14 +2195,12 @@ async function chatCompletion(params) {
|
|
|
2200
2195
|
if (!res.ok) {
|
|
2201
2196
|
await failBody(res);
|
|
2202
2197
|
}
|
|
2203
|
-
const receiptId = res.headers.get("x-receipt-id") ?? void 0;
|
|
2204
2198
|
const raw = await res.json();
|
|
2205
2199
|
const content = raw?.choices?.[0]?.message?.content ?? "";
|
|
2206
2200
|
return {
|
|
2207
2201
|
content,
|
|
2208
2202
|
model: raw?.model ?? params.model,
|
|
2209
2203
|
usage: usageOf(raw),
|
|
2210
|
-
receiptId,
|
|
2211
2204
|
raw
|
|
2212
2205
|
};
|
|
2213
2206
|
}
|
|
@@ -2221,12 +2214,11 @@ async function* chatCompletionStream(params) {
|
|
|
2221
2214
|
});
|
|
2222
2215
|
if (!(res.ok && res.body)) {
|
|
2223
2216
|
await failBody(res);
|
|
2224
|
-
return
|
|
2217
|
+
return;
|
|
2225
2218
|
}
|
|
2226
2219
|
const reader = res.body.getReader();
|
|
2227
2220
|
const decoder = new TextDecoder();
|
|
2228
2221
|
let buffer = "";
|
|
2229
|
-
let receiptId;
|
|
2230
2222
|
while (true) {
|
|
2231
2223
|
const { done, value } = await reader.read();
|
|
2232
2224
|
if (done) {
|
|
@@ -2242,13 +2234,10 @@ async function* chatCompletionStream(params) {
|
|
|
2242
2234
|
}
|
|
2243
2235
|
const data = trimmed.slice(5).trim();
|
|
2244
2236
|
if (data === "[DONE]") {
|
|
2245
|
-
return
|
|
2237
|
+
return;
|
|
2246
2238
|
}
|
|
2247
2239
|
try {
|
|
2248
2240
|
const json = JSON.parse(data);
|
|
2249
|
-
if (json.x_receipt_id) {
|
|
2250
|
-
receiptId = json.x_receipt_id;
|
|
2251
|
-
}
|
|
2252
2241
|
const delta = json.choices?.[0]?.delta?.content;
|
|
2253
2242
|
if (typeof delta === "string" && delta) {
|
|
2254
2243
|
yield delta;
|
|
@@ -2257,7 +2246,6 @@ async function* chatCompletionStream(params) {
|
|
|
2257
2246
|
}
|
|
2258
2247
|
}
|
|
2259
2248
|
}
|
|
2260
|
-
return { receiptId };
|
|
2261
2249
|
}
|
|
2262
2250
|
async function listModels(opts) {
|
|
2263
2251
|
const base = opts?.apiBase ?? DEFAULT_API_BASE;
|
|
@@ -2279,330 +2267,6 @@ async function listModels(opts) {
|
|
|
2279
2267
|
reasoning: m.reasoning
|
|
2280
2268
|
}));
|
|
2281
2269
|
}
|
|
2282
|
-
var RECEIPT_ANCHORED_SUFFIX = "::anchor::ReceiptAnchored";
|
|
2283
|
-
function normalizeClaims(claims) {
|
|
2284
|
-
if (!claims) {
|
|
2285
|
-
return [];
|
|
2286
|
-
}
|
|
2287
|
-
if (Array.isArray(claims)) {
|
|
2288
|
-
return claims.filter((c) => c.name).map((c) => ({
|
|
2289
|
-
name: c.name,
|
|
2290
|
-
status: c.status ?? "unknown",
|
|
2291
|
-
source: c.source
|
|
2292
|
-
}));
|
|
2293
|
-
}
|
|
2294
|
-
return Object.entries(claims).map(([name, v]) => ({
|
|
2295
|
-
name,
|
|
2296
|
-
status: v?.status ?? "unknown",
|
|
2297
|
-
source: v?.source
|
|
2298
|
-
}));
|
|
2299
|
-
}
|
|
2300
|
-
function fullnodeUrl(network) {
|
|
2301
|
-
return network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
2302
|
-
}
|
|
2303
|
-
function jcs(value) {
|
|
2304
|
-
if (value === null) {
|
|
2305
|
-
return "null";
|
|
2306
|
-
}
|
|
2307
|
-
if (typeof value === "boolean") {
|
|
2308
|
-
return value ? "true" : "false";
|
|
2309
|
-
}
|
|
2310
|
-
if (typeof value === "number") {
|
|
2311
|
-
if (!Number.isInteger(value)) {
|
|
2312
|
-
throw new Error("JCS: non-integer number");
|
|
2313
|
-
}
|
|
2314
|
-
return String(value);
|
|
2315
|
-
}
|
|
2316
|
-
if (typeof value === "string") {
|
|
2317
|
-
return JSON.stringify(value);
|
|
2318
|
-
}
|
|
2319
|
-
if (Array.isArray(value)) {
|
|
2320
|
-
return `[${value.map(jcs).join(",")}]`;
|
|
2321
|
-
}
|
|
2322
|
-
const keys = Object.keys(value).sort();
|
|
2323
|
-
return `{${keys.map((k) => `${JSON.stringify(k)}:${jcs(value[k])}`).join(",")}}`;
|
|
2324
|
-
}
|
|
2325
|
-
function verifyReceiptSignature(receipt, signingKeyHex) {
|
|
2326
|
-
try {
|
|
2327
|
-
const sig = receipt.signature;
|
|
2328
|
-
if (!sig?.value) {
|
|
2329
|
-
return false;
|
|
2330
|
-
}
|
|
2331
|
-
const endorsed = utils$1.hexToBytes(signingKeyHex.replace(/^0x/, ""));
|
|
2332
|
-
const sigBytes = utils$1.hexToBytes(sig.value);
|
|
2333
|
-
if (sig.algo === "ed25519") {
|
|
2334
|
-
if (sigBytes.length !== 64 || endorsed.length !== 32) {
|
|
2335
|
-
return false;
|
|
2336
|
-
}
|
|
2337
|
-
const { value: _omitted, ...sigRest } = sig;
|
|
2338
|
-
const canonical2 = {
|
|
2339
|
-
...receipt,
|
|
2340
|
-
signature: sigRest
|
|
2341
|
-
};
|
|
2342
|
-
const msg = new TextEncoder().encode(jcs(canonical2));
|
|
2343
|
-
return ed25519$1.ed25519.verify(sigBytes, msg, endorsed);
|
|
2344
|
-
}
|
|
2345
|
-
if (sig.algo !== "ecdsa-secp256k1") {
|
|
2346
|
-
return false;
|
|
2347
|
-
}
|
|
2348
|
-
const canonical = {
|
|
2349
|
-
api_version: receipt.api_version ?? "",
|
|
2350
|
-
receipt_id: receipt.receipt_id ?? "",
|
|
2351
|
-
chat_id: receipt.chat_id ?? null,
|
|
2352
|
-
workload_id: receipt.workload_id ?? "",
|
|
2353
|
-
workload_keyset_digest: receipt.workload_keyset_digest ?? "",
|
|
2354
|
-
endpoint: receipt.endpoint ?? "",
|
|
2355
|
-
method: receipt.method ?? "",
|
|
2356
|
-
served_at: receipt.served_at ?? 0,
|
|
2357
|
-
event_log: receipt.event_log ?? [],
|
|
2358
|
-
signature: { algo: sig.algo, key_id: sig.key_id ?? "" }
|
|
2359
|
-
};
|
|
2360
|
-
const prehash = sha256.sha256(new TextEncoder().encode(jcs(canonical)));
|
|
2361
|
-
if (sigBytes.length !== 65) {
|
|
2362
|
-
return false;
|
|
2363
|
-
}
|
|
2364
|
-
let v = sigBytes[64];
|
|
2365
|
-
if (v >= 27 && v <= 30) {
|
|
2366
|
-
v -= 27;
|
|
2367
|
-
}
|
|
2368
|
-
if (v > 3) {
|
|
2369
|
-
return false;
|
|
2370
|
-
}
|
|
2371
|
-
const recovered = secp256k1.secp256k1.Signature.fromCompact(sigBytes.slice(0, 64)).addRecoveryBit(v).recoverPublicKey(prehash).toHex(false);
|
|
2372
|
-
return recovered.toLowerCase() === utils$1.bytesToHex(endorsed).toLowerCase();
|
|
2373
|
-
} catch {
|
|
2374
|
-
return false;
|
|
2375
|
-
}
|
|
2376
|
-
}
|
|
2377
|
-
async function verifyTdxQuote(base, model, receiptWorkloadId) {
|
|
2378
|
-
let nonce;
|
|
2379
|
-
try {
|
|
2380
|
-
nonce = utils$1.bytesToHex(globalThis.crypto.getRandomValues(new Uint8Array(32)));
|
|
2381
|
-
} catch {
|
|
2382
|
-
return { status: "skip", detail: "no secure RNG available", forged: false };
|
|
2383
|
-
}
|
|
2384
|
-
let report;
|
|
2385
|
-
try {
|
|
2386
|
-
const res = await fetch(
|
|
2387
|
-
`${base}/aci/attestation?model=${encodeURIComponent(model)}&nonce=${nonce}`
|
|
2388
|
-
);
|
|
2389
|
-
if (res.ok) {
|
|
2390
|
-
report = (await res.json()).report;
|
|
2391
|
-
}
|
|
2392
|
-
} catch {
|
|
2393
|
-
}
|
|
2394
|
-
const quoteHex = report?.attestation?.evidence?.quote;
|
|
2395
|
-
if (!quoteHex) {
|
|
2396
|
-
return {
|
|
2397
|
-
status: "skip",
|
|
2398
|
-
detail: "attestation report (with quote) unavailable \u2014 pass --model?",
|
|
2399
|
-
forged: false
|
|
2400
|
-
};
|
|
2401
|
-
}
|
|
2402
|
-
try {
|
|
2403
|
-
const dcap = await import('@phala/dcap-qvl');
|
|
2404
|
-
const getCollateralAndVerify = dcap.getCollateralAndVerify ?? dcap.default?.getCollateralAndVerify;
|
|
2405
|
-
if (typeof getCollateralAndVerify !== "function") {
|
|
2406
|
-
return {
|
|
2407
|
-
status: "fail",
|
|
2408
|
-
forged: false,
|
|
2409
|
-
detail: "DCAP verifier unavailable in this build"
|
|
2410
|
-
};
|
|
2411
|
-
}
|
|
2412
|
-
const quoteBytes = utils$1.hexToBytes(quoteHex.replace(/^0x/, ""));
|
|
2413
|
-
const vr = await getCollateralAndVerify(quoteBytes);
|
|
2414
|
-
const td = vr.report.asTd10() ?? vr.report.asTd15()?.base ?? null;
|
|
2415
|
-
const reportData = td?.reportData;
|
|
2416
|
-
const signingAddr = report?.signing_address?.replace(/^0x/, "").toLowerCase();
|
|
2417
|
-
const addrBound = Boolean(
|
|
2418
|
-
reportData && signingAddr && utils$1.bytesToHex(reportData.slice(0, 20)) === signingAddr
|
|
2419
|
-
);
|
|
2420
|
-
const workloadMatch = report?.workload_id === receiptWorkloadId;
|
|
2421
|
-
const tcb = vr.status;
|
|
2422
|
-
const tcbBad = tcb === "Revoked" || tcb === "Unknown";
|
|
2423
|
-
const forged = !(addrBound && workloadMatch) || tcbBad;
|
|
2424
|
-
let detail;
|
|
2425
|
-
if (forged && tcbBad) {
|
|
2426
|
-
detail = `genuine TDX but TCB ${tcb}`;
|
|
2427
|
-
} else if (!addrBound) {
|
|
2428
|
-
detail = "report_data does NOT commit the report's signing address";
|
|
2429
|
-
} else if (!workloadMatch) {
|
|
2430
|
-
detail = "quote workload_id does not match the receipt's";
|
|
2431
|
-
} else {
|
|
2432
|
-
detail = `genuine Intel TDX (verified vs Intel collateral), TCB ${tcb}; report_data commits the attested signing address`;
|
|
2433
|
-
}
|
|
2434
|
-
return { status: forged ? "fail" : "pass", forged, tcbStatus: tcb, detail };
|
|
2435
|
-
} catch (e) {
|
|
2436
|
-
return {
|
|
2437
|
-
status: "fail",
|
|
2438
|
-
forged: false,
|
|
2439
|
-
detail: `could not verify the quote: ${e instanceof Error ? e.message : "error"}`
|
|
2440
|
-
};
|
|
2441
|
-
}
|
|
2442
|
-
}
|
|
2443
|
-
async function verifyReceipt(receiptId, opts = {}) {
|
|
2444
|
-
const base = opts.apiBase ?? DEFAULT_API_BASE;
|
|
2445
|
-
const network = opts.network ?? "mainnet";
|
|
2446
|
-
const checks = [];
|
|
2447
|
-
let receipt = null;
|
|
2448
|
-
try {
|
|
2449
|
-
const res = await fetch(`${base}/aci/receipts/${encodeURIComponent(receiptId)}`);
|
|
2450
|
-
if (res.ok) {
|
|
2451
|
-
receipt = await res.json();
|
|
2452
|
-
}
|
|
2453
|
-
} catch {
|
|
2454
|
-
}
|
|
2455
|
-
if (!receipt?.event_log) {
|
|
2456
|
-
checks.push({
|
|
2457
|
-
name: "Receipt",
|
|
2458
|
-
status: "fail",
|
|
2459
|
-
detail: "receipt not found or malformed",
|
|
2460
|
-
trust: "receipt-asserted"
|
|
2461
|
-
});
|
|
2462
|
-
return { receiptId, verified: false, anchorVerified: false, checks };
|
|
2463
|
-
}
|
|
2464
|
-
const wireHash = receipt.event_log.find((e) => e.type === "response.returned")?.wire_hash;
|
|
2465
|
-
const workloadId = receipt.workload_id;
|
|
2466
|
-
checks.push({
|
|
2467
|
-
name: "Receipt",
|
|
2468
|
-
status: wireHash && workloadId ? "pass" : "fail",
|
|
2469
|
-
detail: wireHash ? `well-formed (${receipt.event_log.length} log entries, workload ${workloadId})` : "missing response wire_hash / workload_id",
|
|
2470
|
-
trust: "receipt-asserted"
|
|
2471
|
-
});
|
|
2472
|
-
const upstreamEv = receipt.event_log.find((e) => e.type === "upstream.verified");
|
|
2473
|
-
const upstreamOk = upstreamEv?.result === "verified";
|
|
2474
|
-
const claims = normalizeClaims(upstreamEv?.claims);
|
|
2475
|
-
checks.push({
|
|
2476
|
-
name: "Confidential upstream",
|
|
2477
|
-
status: upstreamEv ? upstreamOk ? "pass" : "fail" : "skip",
|
|
2478
|
-
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?)",
|
|
2479
|
-
trust: "receipt-asserted"
|
|
2480
|
-
});
|
|
2481
|
-
let anchorVerified = false;
|
|
2482
|
-
let anchor;
|
|
2483
|
-
let digest;
|
|
2484
|
-
try {
|
|
2485
|
-
const res = await fetch(`${base}/aci/anchor/${encodeURIComponent(receiptId)}`);
|
|
2486
|
-
if (res.ok) {
|
|
2487
|
-
const j = await res.json();
|
|
2488
|
-
digest = j.txDigest;
|
|
2489
|
-
}
|
|
2490
|
-
} catch {
|
|
2491
|
-
}
|
|
2492
|
-
if (!digest) {
|
|
2493
|
-
checks.push({
|
|
2494
|
-
name: "Sui anchor",
|
|
2495
|
-
status: "fail",
|
|
2496
|
-
detail: `no anchor on record \u2014 POST ${base}/aci/anchor/${receiptId} to create one`,
|
|
2497
|
-
trust: "trustless"
|
|
2498
|
-
});
|
|
2499
|
-
} else {
|
|
2500
|
-
try {
|
|
2501
|
-
const client = new grpc.SuiGrpcClient({ baseUrl: fullnodeUrl(network), network });
|
|
2502
|
-
const tx = await client.core.getTransaction({
|
|
2503
|
-
digest,
|
|
2504
|
-
include: { events: true }
|
|
2505
|
-
});
|
|
2506
|
-
const txn = tx.$kind === "Transaction" ? tx.Transaction : tx.FailedTransaction;
|
|
2507
|
-
const ev = (txn.events ?? []).find(
|
|
2508
|
-
(e) => e.eventType.endsWith(RECEIPT_ANCHORED_SUFFIX)
|
|
2509
|
-
);
|
|
2510
|
-
const data = ev?.json ?? {};
|
|
2511
|
-
const onChainReceipt = String(data.receipt_id ?? "");
|
|
2512
|
-
const onChainWire = String(data.wire_hash ?? "");
|
|
2513
|
-
const onChainWorkload = String(data.workload_id ?? "");
|
|
2514
|
-
const matches = onChainReceipt === receiptId && onChainWire === wireHash && onChainWorkload === workloadId;
|
|
2515
|
-
anchorVerified = matches;
|
|
2516
|
-
anchor = {
|
|
2517
|
-
txDigest: digest,
|
|
2518
|
-
anchoredAtMs: data.anchored_at_ms ? String(data.anchored_at_ms) : void 0,
|
|
2519
|
-
anchoredBy: data.anchored_by ? String(data.anchored_by) : void 0,
|
|
2520
|
-
explorer: `https://suiscan.xyz/${network}/tx/${digest}`
|
|
2521
|
-
};
|
|
2522
|
-
checks.push({
|
|
2523
|
-
name: "Sui anchor",
|
|
2524
|
-
status: matches ? "pass" : "fail",
|
|
2525
|
-
detail: matches ? `on-chain ReceiptAnchored matches (wire_hash + workload_id), tx ${digest}` : `on-chain event does NOT match the receipt (wire ${onChainWire || "absent"})`,
|
|
2526
|
-
trust: "trustless"
|
|
2527
|
-
});
|
|
2528
|
-
} catch (e) {
|
|
2529
|
-
checks.push({
|
|
2530
|
-
name: "Sui anchor",
|
|
2531
|
-
status: "fail",
|
|
2532
|
-
detail: `could not read anchor tx ${digest}: ${e instanceof Error ? e.message : "error"}`,
|
|
2533
|
-
trust: "trustless"
|
|
2534
|
-
});
|
|
2535
|
-
}
|
|
2536
|
-
}
|
|
2537
|
-
let sigStatus = "skip";
|
|
2538
|
-
let sigDetail = "no signature on receipt";
|
|
2539
|
-
if (receipt.signature?.value) {
|
|
2540
|
-
try {
|
|
2541
|
-
const model = opts.model ?? "phala/glm-5.2";
|
|
2542
|
-
const res = await fetch(
|
|
2543
|
-
`${base}/aci/attestation?model=${encodeURIComponent(model)}`
|
|
2544
|
-
);
|
|
2545
|
-
const att = res.ok ? await res.json() : null;
|
|
2546
|
-
if (!att?.signingKey) {
|
|
2547
|
-
sigDetail = "could not fetch the attested keyset to check the signature";
|
|
2548
|
-
} else if (att.workloadId && att.workloadId !== workloadId) {
|
|
2549
|
-
sigDetail = `attested keyset is for a different workload \u2014 pass --model for ${workloadId}`;
|
|
2550
|
-
} else {
|
|
2551
|
-
const ok = verifyReceiptSignature(receipt, att.signingKey);
|
|
2552
|
-
sigStatus = ok ? "pass" : "fail";
|
|
2553
|
-
sigDetail = ok ? `signed by the attested receipt key (${receipt.signature.key_id ?? "key"})` : "signature does NOT recover the attested receipt key \u2014 forged/altered";
|
|
2554
|
-
}
|
|
2555
|
-
} catch {
|
|
2556
|
-
sigDetail = "signature check errored";
|
|
2557
|
-
}
|
|
2558
|
-
}
|
|
2559
|
-
checks.push({
|
|
2560
|
-
name: "Receipt signature",
|
|
2561
|
-
status: sigStatus,
|
|
2562
|
-
detail: sigDetail,
|
|
2563
|
-
trust: sigStatus === "skip" ? "roadmap" : "trustless"
|
|
2564
|
-
});
|
|
2565
|
-
if (opts.skipQuote) {
|
|
2566
|
-
checks.push({
|
|
2567
|
-
name: "TDX quote (DCAP)",
|
|
2568
|
-
status: "skip",
|
|
2569
|
-
detail: "skipped (--quick)",
|
|
2570
|
-
trust: "trustless"
|
|
2571
|
-
});
|
|
2572
|
-
} else {
|
|
2573
|
-
const q = await verifyTdxQuote(
|
|
2574
|
-
base,
|
|
2575
|
-
opts.model ?? "phala/glm-5.2",
|
|
2576
|
-
workloadId ?? ""
|
|
2577
|
-
);
|
|
2578
|
-
checks.push({
|
|
2579
|
-
name: "TDX quote (DCAP)",
|
|
2580
|
-
status: q.status,
|
|
2581
|
-
detail: q.detail,
|
|
2582
|
-
trust: "trustless"
|
|
2583
|
-
});
|
|
2584
|
-
}
|
|
2585
|
-
const trustlessFailed = checks.some(
|
|
2586
|
-
(c) => c.trust === "trustless" && c.status === "fail"
|
|
2587
|
-
);
|
|
2588
|
-
return {
|
|
2589
|
-
receiptId,
|
|
2590
|
-
verified: Boolean(wireHash && workloadId) && !trustlessFailed,
|
|
2591
|
-
anchorVerified,
|
|
2592
|
-
checks,
|
|
2593
|
-
wireHash,
|
|
2594
|
-
workloadId,
|
|
2595
|
-
upstream: upstreamEv ? {
|
|
2596
|
-
provider: upstreamEv.provider ?? upstreamEv.upstream_name,
|
|
2597
|
-
modelId: upstreamEv.model_id,
|
|
2598
|
-
result: upstreamEv.result,
|
|
2599
|
-
tcbStatus: upstreamEv.tcb_status,
|
|
2600
|
-
sessionId: upstreamEv.session_id,
|
|
2601
|
-
claims: claims.length > 0 ? claims : void 0
|
|
2602
|
-
} : void 0,
|
|
2603
|
-
anchor
|
|
2604
|
-
};
|
|
2605
|
-
}
|
|
2606
2270
|
var DEFAULT_CONFIG_DIR = path.join(os.homedir(), ".t2000");
|
|
2607
2271
|
function resolveConfigPath(configDir) {
|
|
2608
2272
|
return path.join(configDir ?? DEFAULT_CONFIG_DIR, "config.json");
|
|
@@ -2926,8 +2590,7 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
2926
2590
|
async chat(params) {
|
|
2927
2591
|
return chatCompletion(params);
|
|
2928
2592
|
}
|
|
2929
|
-
/** Streaming chat completion — async-iterate the assistant text deltas
|
|
2930
|
-
* the generator returns `{ receiptId }` (confidential attestation) at the end. */
|
|
2593
|
+
/** Streaming chat completion — async-iterate the assistant text deltas. */
|
|
2931
2594
|
chatStream(params) {
|
|
2932
2595
|
return chatCompletionStream(params);
|
|
2933
2596
|
}
|
|
@@ -2935,11 +2598,6 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
2935
2598
|
async models(opts) {
|
|
2936
2599
|
return listModels(opts);
|
|
2937
2600
|
}
|
|
2938
|
-
/** Verify a confidential response by receipt id — checks the signed receipt
|
|
2939
|
-
* + its trustless on-chain Sui anchor. Fails closed on any mismatch. */
|
|
2940
|
-
async verify(receiptId, opts) {
|
|
2941
|
-
return verifyReceipt(receiptId, opts);
|
|
2942
|
-
}
|
|
2943
2601
|
// -- Swap --
|
|
2944
2602
|
async swap(params) {
|
|
2945
2603
|
this.limits.assert({
|
|
@@ -3351,7 +3009,7 @@ function feeConfigArg(tx) {
|
|
|
3351
3009
|
mutable: false
|
|
3352
3010
|
});
|
|
3353
3011
|
}
|
|
3354
|
-
function
|
|
3012
|
+
function hexToBytes(hex) {
|
|
3355
3013
|
const clean = hex.replace(/^0x/, "");
|
|
3356
3014
|
const bytes = [];
|
|
3357
3015
|
for (let i = 0; i < clean.length; i += 2) {
|
|
@@ -3430,7 +3088,7 @@ async function buildCreateOpeningTx({
|
|
|
3430
3088
|
typeArguments: [exports.USDC_TYPE],
|
|
3431
3089
|
arguments: [
|
|
3432
3090
|
coin,
|
|
3433
|
-
tx.pure.vector("u8",
|
|
3091
|
+
tx.pure.vector("u8", hexToBytes(terms.specHash)),
|
|
3434
3092
|
tx.pure.u64(terms.openUntilMs),
|
|
3435
3093
|
tx.pure.u64(terms.slaMs),
|
|
3436
3094
|
tx.pure.u64(terms.reviewWindowMs),
|
|
@@ -3481,7 +3139,7 @@ function buildCancelOpeningTx(openingId) {
|
|
|
3481
3139
|
function buildRefundUnclaimedTx(openingId) {
|
|
3482
3140
|
return openingCall(openingId, "refund_unclaimed");
|
|
3483
3141
|
}
|
|
3484
|
-
function
|
|
3142
|
+
function bytesToHex(bytes) {
|
|
3485
3143
|
return `0x${Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
3486
3144
|
}
|
|
3487
3145
|
async function getOpening(client, openingId) {
|
|
@@ -3496,7 +3154,7 @@ async function getOpening(client, openingId) {
|
|
|
3496
3154
|
buyer: String(json.buyer),
|
|
3497
3155
|
amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,
|
|
3498
3156
|
feeBps: Number(json.fee_bps ?? 0),
|
|
3499
|
-
specHash:
|
|
3157
|
+
specHash: bytesToHex(json.spec_hash ?? []),
|
|
3500
3158
|
openUntilMs: Number(json.open_until_ms),
|
|
3501
3159
|
slaMs: Number(json.sla_ms),
|
|
3502
3160
|
reviewWindowMs: Number(json.review_window_ms),
|
|
@@ -3533,7 +3191,7 @@ var JOB_STATES = [
|
|
|
3533
3191
|
"refunded",
|
|
3534
3192
|
"rejected"
|
|
3535
3193
|
];
|
|
3536
|
-
function
|
|
3194
|
+
function hexToBytes2(hex) {
|
|
3537
3195
|
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
3538
3196
|
if (clean.length === 0 || clean.length % 2 !== 0 || /[^0-9a-fA-F]/.test(clean)) {
|
|
3539
3197
|
throw new exports.T2000Error(
|
|
@@ -3547,7 +3205,7 @@ function hexToBytes3(hex) {
|
|
|
3547
3205
|
}
|
|
3548
3206
|
return out;
|
|
3549
3207
|
}
|
|
3550
|
-
function
|
|
3208
|
+
function bytesToHex2(bytes) {
|
|
3551
3209
|
const arr = typeof bytes === "string" ? Array.from(atob(bytes), (c) => c.charCodeAt(0)) : bytes;
|
|
3552
3210
|
let s = "0x";
|
|
3553
3211
|
for (const b of arr) s += b.toString(16).padStart(2, "0");
|
|
@@ -3584,7 +3242,7 @@ function preflightCreateJob(terms) {
|
|
|
3584
3242
|
return preflightFail("INVALID_AMOUNT", "rejectSplitBps must be an integer 0\u201310000.");
|
|
3585
3243
|
}
|
|
3586
3244
|
try {
|
|
3587
|
-
|
|
3245
|
+
hexToBytes2(terms.specHash);
|
|
3588
3246
|
} catch (e) {
|
|
3589
3247
|
return preflightFail("INVALID_AMOUNT", e.message);
|
|
3590
3248
|
}
|
|
@@ -3612,7 +3270,7 @@ async function buildCreateJobTx({
|
|
|
3612
3270
|
arguments: [
|
|
3613
3271
|
tx.pure.address(seller),
|
|
3614
3272
|
coin,
|
|
3615
|
-
tx.pure.vector("u8",
|
|
3273
|
+
tx.pure.vector("u8", hexToBytes2(terms.specHash)),
|
|
3616
3274
|
tx.pure.u64(terms.deliverByMs),
|
|
3617
3275
|
tx.pure.u64(terms.reviewWindowMs),
|
|
3618
3276
|
tx.pure.u64(terms.rejectSplitBps),
|
|
@@ -3683,7 +3341,7 @@ function buildDeliverJobTx(jobId, deliveryHash) {
|
|
|
3683
3341
|
typeArguments: [exports.USDC_TYPE],
|
|
3684
3342
|
arguments: [
|
|
3685
3343
|
tx.object(jobId),
|
|
3686
|
-
tx.pure.vector("u8",
|
|
3344
|
+
tx.pure.vector("u8", hexToBytes2(deliveryHash)),
|
|
3687
3345
|
feeConfigArg2(tx),
|
|
3688
3346
|
tx.object(CLOCK_ID3)
|
|
3689
3347
|
]
|
|
@@ -3720,12 +3378,12 @@ async function getJob(client, jobId) {
|
|
|
3720
3378
|
amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,
|
|
3721
3379
|
escrowUsdc: Number(json.escrow) / 10 ** USDC_DECIMALS,
|
|
3722
3380
|
feeBps: Number(json.fee_bps ?? 0),
|
|
3723
|
-
specHash:
|
|
3381
|
+
specHash: bytesToHex2(json.spec_hash ?? []),
|
|
3724
3382
|
deliverByMs: Number(json.deliver_by_ms),
|
|
3725
3383
|
reviewWindowMs: Number(json.review_window_ms),
|
|
3726
3384
|
rejectSplitBps: Number(json.reject_split_bps),
|
|
3727
3385
|
state,
|
|
3728
|
-
deliveryHash: hasDelivery ?
|
|
3386
|
+
deliveryHash: hasDelivery ? bytesToHex2(deliveryBytes) : null,
|
|
3729
3387
|
deliveredAtMs: hasDelivery ? deliveredAtMs : null,
|
|
3730
3388
|
createdAtMs: Number(json.created_at_ms)
|
|
3731
3389
|
};
|
|
@@ -3952,15 +3610,24 @@ async function listServices(base, filter = {}) {
|
|
|
3952
3610
|
if (filter.agent) params.set("agent", filter.agent);
|
|
3953
3611
|
if (filter.query) params.set("q", filter.query);
|
|
3954
3612
|
if (filter.category) params.set("category", filter.category);
|
|
3613
|
+
if (filter.rail) params.set("rail", filter.rail);
|
|
3955
3614
|
if (filter.limit !== void 0) params.set("limit", String(filter.limit));
|
|
3956
3615
|
if (filter.offset !== void 0) params.set("offset", String(filter.offset));
|
|
3957
3616
|
const qs = params.size > 0 ? `?${params.toString()}` : "";
|
|
3958
3617
|
const json = await commerceFetchJson(`${base}/services${qs}`);
|
|
3959
3618
|
const services = json.services ?? [];
|
|
3960
|
-
return {
|
|
3619
|
+
return {
|
|
3620
|
+
total: json.total ?? services.length,
|
|
3621
|
+
hireTotal: json.hireTotal,
|
|
3622
|
+
apiTotal: json.apiTotal,
|
|
3623
|
+
services
|
|
3624
|
+
};
|
|
3961
3625
|
}
|
|
3962
3626
|
async function fetchService(base, agent, slug) {
|
|
3963
|
-
const { services
|
|
3627
|
+
const { services } = await listServices(base, { agent });
|
|
3628
|
+
const rows = services.filter(
|
|
3629
|
+
(o) => o.kind !== "api"
|
|
3630
|
+
);
|
|
3964
3631
|
const match = rows.find((o) => o.slug === slug.trim().toLowerCase());
|
|
3965
3632
|
if (!match) {
|
|
3966
3633
|
const live = rows.filter((o) => !o.retired).map((o) => o.slug);
|
|
@@ -4119,9 +3786,22 @@ async function listOpenJobs(base, filter = {}) {
|
|
|
4119
3786
|
if (filter.query) params.set("q", filter.query);
|
|
4120
3787
|
if (filter.buyer) params.set("buyer", filter.buyer);
|
|
4121
3788
|
if (filter.limit) params.set("limit", String(filter.limit));
|
|
3789
|
+
if (filter.offset) params.set("offset", String(filter.offset));
|
|
4122
3790
|
const qs = params.size > 0 ? `?${params.toString()}` : "";
|
|
4123
3791
|
const json = await fetchJson(`${base}/open-jobs${qs}`);
|
|
4124
|
-
|
|
3792
|
+
const openJobs = Array.isArray(json.openJobs) ? json.openJobs : [];
|
|
3793
|
+
const returned = openJobs.length;
|
|
3794
|
+
const total = typeof json.total === "number" && json.total >= returned ? json.total : returned;
|
|
3795
|
+
const startAt = filter.offset ?? 0;
|
|
3796
|
+
const truncated = typeof json.truncated === "boolean" ? json.truncated : startAt + returned < total;
|
|
3797
|
+
const nextOffset = typeof json.nextOffset === "number" ? json.nextOffset : truncated ? startAt + returned : void 0;
|
|
3798
|
+
return {
|
|
3799
|
+
total,
|
|
3800
|
+
returned,
|
|
3801
|
+
truncated,
|
|
3802
|
+
...nextOffset === void 0 ? {} : { nextOffset },
|
|
3803
|
+
openJobs
|
|
3804
|
+
};
|
|
4125
3805
|
}
|
|
4126
3806
|
async function getOpenJob(base, id) {
|
|
4127
3807
|
const json = await fetchJson(
|
|
@@ -4822,6 +4502,5 @@ exports.validateAddress = validateAddress;
|
|
|
4822
4502
|
exports.validateLabel = validateLabel;
|
|
4823
4503
|
exports.verifyCetusRouteCoinMatch = verifyCetusRouteCoinMatch;
|
|
4824
4504
|
exports.verifyJobForSeller = verifyJobForSeller;
|
|
4825
|
-
exports.verifyReceipt = verifyReceipt;
|
|
4826
4505
|
exports.walletExists = walletExists;
|
|
4827
4506
|
exports.writeLimitsFile = writeLimitsFile;
|