@t2000/sdk 10.36.0 → 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/index.cjs +31 -361
- package/dist/index.d.cts +27 -78
- package/dist/index.d.ts +27 -78
- package/dist/index.js +32 -361
- 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
|
};
|
|
@@ -4122,9 +3780,22 @@ async function listOpenJobs(base, filter = {}) {
|
|
|
4122
3780
|
if (filter.query) params.set("q", filter.query);
|
|
4123
3781
|
if (filter.buyer) params.set("buyer", filter.buyer);
|
|
4124
3782
|
if (filter.limit) params.set("limit", String(filter.limit));
|
|
3783
|
+
if (filter.offset) params.set("offset", String(filter.offset));
|
|
4125
3784
|
const qs = params.size > 0 ? `?${params.toString()}` : "";
|
|
4126
3785
|
const json = await fetchJson(`${base}/open-jobs${qs}`);
|
|
4127
|
-
|
|
3786
|
+
const openJobs = Array.isArray(json.openJobs) ? json.openJobs : [];
|
|
3787
|
+
const returned = openJobs.length;
|
|
3788
|
+
const total = typeof json.total === "number" && json.total >= returned ? json.total : returned;
|
|
3789
|
+
const startAt = filter.offset ?? 0;
|
|
3790
|
+
const truncated = typeof json.truncated === "boolean" ? json.truncated : startAt + returned < total;
|
|
3791
|
+
const nextOffset = typeof json.nextOffset === "number" ? json.nextOffset : truncated ? startAt + returned : void 0;
|
|
3792
|
+
return {
|
|
3793
|
+
total,
|
|
3794
|
+
returned,
|
|
3795
|
+
truncated,
|
|
3796
|
+
...nextOffset === void 0 ? {} : { nextOffset },
|
|
3797
|
+
openJobs
|
|
3798
|
+
};
|
|
4128
3799
|
}
|
|
4129
3800
|
async function getOpenJob(base, id) {
|
|
4130
3801
|
const json = await fetchJson(
|
|
@@ -4622,4 +4293,4 @@ function displayHandle(label, parentName = AUDRIC_PARENT_NAME) {
|
|
|
4622
4293
|
// src/index.ts
|
|
4623
4294
|
init_preflight();
|
|
4624
4295
|
|
|
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,
|
|
4296
|
+
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, walletExists, writeLimitsFile };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t2000/sdk",
|
|
3
|
-
"version": "10.36.
|
|
3
|
+
"version": "10.36.1",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20"
|
|
6
6
|
},
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@phala/dcap-qvl": "^0.5.2",
|
|
56
56
|
"bn.js": "^5.2.1",
|
|
57
57
|
"eventemitter3": "^5",
|
|
58
|
-
"@t2000/sui-x402": "10.36.
|
|
58
|
+
"@t2000/sui-x402": "10.36.1"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/bn.js": "^5.1.5",
|