@t2000/cli 5.15.1 → 5.17.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.
@@ -78831,10 +78831,10 @@ async function finalize(response, opts) {
78831
78831
  return { status: response.status, body: body2, paid: opts.paid };
78832
78832
  }
78833
78833
  async function makeGrpcBuildClient(client) {
78834
- const { SuiGrpcClient: SuiGrpcClient2 } = await Promise.resolve().then(() => (init_grpc(), grpc_exports));
78834
+ const { SuiGrpcClient: SuiGrpcClient3 } = await Promise.resolve().then(() => (init_grpc(), grpc_exports));
78835
78835
  const network = client.network === "testnet" ? "testnet" : "mainnet";
78836
78836
  const baseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
78837
- return new SuiGrpcClient2({ baseUrl, network });
78837
+ return new SuiGrpcClient3({ baseUrl, network });
78838
78838
  }
78839
78839
  function atomicToHuman(raw, decimals) {
78840
78840
  return Number(raw) / 10 ** decimals;
@@ -79385,7 +79385,9 @@ function body(params, stream4) {
79385
79385
  return JSON.stringify({
79386
79386
  model: params.model,
79387
79387
  messages: params.messages,
79388
- ...stream4 ? { stream: true } : {},
79388
+ // include_usage the final stream chunk carries usage + x_receipt_id
79389
+ // (the confidential attestation receipt) so we can surface it after a stream.
79390
+ ...stream4 ? { stream: true, stream_options: { include_usage: true } } : {},
79389
79391
  ...params.maxTokens != null ? { max_tokens: params.maxTokens } : {},
79390
79392
  ...params.temperature != null ? { temperature: params.temperature } : {}
79391
79393
  });
@@ -79401,12 +79403,14 @@ async function chatCompletion(params) {
79401
79403
  if (!res.ok) {
79402
79404
  await failBody(res);
79403
79405
  }
79406
+ const receiptId = res.headers.get("x-receipt-id") ?? void 0;
79404
79407
  const raw = await res.json();
79405
79408
  const content = raw?.choices?.[0]?.message?.content ?? "";
79406
79409
  return {
79407
79410
  content,
79408
79411
  model: raw?.model ?? params.model,
79409
79412
  usage: usageOf(raw),
79413
+ receiptId,
79410
79414
  raw
79411
79415
  };
79412
79416
  }
@@ -79420,11 +79424,12 @@ async function* chatCompletionStream(params) {
79420
79424
  });
79421
79425
  if (!(res.ok && res.body)) {
79422
79426
  await failBody(res);
79423
- return;
79427
+ return {};
79424
79428
  }
79425
79429
  const reader = res.body.getReader();
79426
79430
  const decoder = new TextDecoder();
79427
79431
  let buffer = "";
79432
+ let receiptId;
79428
79433
  while (true) {
79429
79434
  const { done, value } = await reader.read();
79430
79435
  if (done) {
@@ -79440,10 +79445,13 @@ async function* chatCompletionStream(params) {
79440
79445
  }
79441
79446
  const data = trimmed.slice(5).trim();
79442
79447
  if (data === "[DONE]") {
79443
- return;
79448
+ return { receiptId };
79444
79449
  }
79445
79450
  try {
79446
79451
  const json = JSON.parse(data);
79452
+ if (json.x_receipt_id) {
79453
+ receiptId = json.x_receipt_id;
79454
+ }
79447
79455
  const delta = json.choices?.[0]?.delta?.content;
79448
79456
  if (typeof delta === "string" && delta) {
79449
79457
  yield delta;
@@ -79452,6 +79460,7 @@ async function* chatCompletionStream(params) {
79452
79460
  }
79453
79461
  }
79454
79462
  }
79463
+ return { receiptId };
79455
79464
  }
79456
79465
  async function listModels(opts) {
79457
79466
  const base = opts?.apiBase ?? DEFAULT_API_BASE;
@@ -79472,6 +79481,124 @@ async function listModels(opts) {
79472
79481
  privacy: m.privacy ?? m.privacy_tier
79473
79482
  }));
79474
79483
  }
79484
+ var RECEIPT_ANCHORED_SUFFIX = "::anchor::ReceiptAnchored";
79485
+ function fullnodeUrl(network) {
79486
+ return network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
79487
+ }
79488
+ async function verifyReceipt(receiptId, opts = {}) {
79489
+ const base = opts.apiBase ?? DEFAULT_API_BASE;
79490
+ const network = opts.network ?? "mainnet";
79491
+ const checks = [];
79492
+ let receipt = null;
79493
+ try {
79494
+ const res = await fetch(`${base}/aci/receipts/${encodeURIComponent(receiptId)}`);
79495
+ if (res.ok) {
79496
+ receipt = await res.json();
79497
+ }
79498
+ } catch {
79499
+ }
79500
+ if (!receipt?.event_log) {
79501
+ checks.push({
79502
+ name: "Receipt",
79503
+ status: "fail",
79504
+ detail: "receipt not found or malformed",
79505
+ trust: "receipt-asserted"
79506
+ });
79507
+ return { receiptId, verified: false, anchorVerified: false, checks };
79508
+ }
79509
+ const wireHash = receipt.event_log.find((e) => e.type === "response.returned")?.wire_hash;
79510
+ const workloadId = receipt.workload_id;
79511
+ checks.push({
79512
+ name: "Receipt",
79513
+ status: wireHash && workloadId ? "pass" : "fail",
79514
+ detail: wireHash ? `well-formed (${receipt.event_log.length} log entries, workload ${workloadId})` : "missing response wire_hash / workload_id",
79515
+ trust: "receipt-asserted"
79516
+ });
79517
+ const upstreamEv = receipt.event_log.find((e) => e.type === "upstream.verified");
79518
+ const upstreamOk = upstreamEv?.result === "verified";
79519
+ checks.push({
79520
+ name: "Confidential upstream",
79521
+ status: upstreamEv ? upstreamOk ? "pass" : "fail" : "skip",
79522
+ 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?)",
79523
+ trust: "receipt-asserted"
79524
+ });
79525
+ let anchorVerified = false;
79526
+ let anchor;
79527
+ let digest;
79528
+ try {
79529
+ const res = await fetch(`${base}/aci/anchor/${encodeURIComponent(receiptId)}`);
79530
+ if (res.ok) {
79531
+ const j = await res.json();
79532
+ digest = j.txDigest;
79533
+ }
79534
+ } catch {
79535
+ }
79536
+ if (!digest) {
79537
+ checks.push({
79538
+ name: "Sui anchor",
79539
+ status: "fail",
79540
+ detail: `no anchor on record \u2014 POST ${base}/aci/anchor/${receiptId} to create one`,
79541
+ trust: "trustless"
79542
+ });
79543
+ } else {
79544
+ try {
79545
+ const client = new SuiGrpcClient({ baseUrl: fullnodeUrl(network), network });
79546
+ const tx = await client.core.getTransaction({
79547
+ digest,
79548
+ include: { events: true }
79549
+ });
79550
+ const txn = tx.$kind === "Transaction" ? tx.Transaction : tx.FailedTransaction;
79551
+ const ev = (txn.events ?? []).find(
79552
+ (e) => e.eventType.endsWith(RECEIPT_ANCHORED_SUFFIX)
79553
+ );
79554
+ const data = ev?.json ?? {};
79555
+ const onChainReceipt = String(data.receipt_id ?? "");
79556
+ const onChainWire = String(data.wire_hash ?? "");
79557
+ const onChainWorkload = String(data.workload_id ?? "");
79558
+ const matches = onChainReceipt === receiptId && onChainWire === wireHash && onChainWorkload === workloadId;
79559
+ anchorVerified = matches;
79560
+ anchor = {
79561
+ txDigest: digest,
79562
+ anchoredAtMs: data.anchored_at_ms ? String(data.anchored_at_ms) : void 0,
79563
+ anchoredBy: data.anchored_by ? String(data.anchored_by) : void 0,
79564
+ explorer: `https://suiscan.xyz/${network}/tx/${digest}`
79565
+ };
79566
+ checks.push({
79567
+ name: "Sui anchor",
79568
+ status: matches ? "pass" : "fail",
79569
+ detail: matches ? `on-chain ReceiptAnchored matches (wire_hash + workload_id), tx ${digest}` : `on-chain event does NOT match the receipt (wire ${onChainWire || "absent"})`,
79570
+ trust: "trustless"
79571
+ });
79572
+ } catch (e) {
79573
+ checks.push({
79574
+ name: "Sui anchor",
79575
+ status: "fail",
79576
+ detail: `could not read anchor tx ${digest}: ${e instanceof Error ? e.message : "error"}`,
79577
+ trust: "trustless"
79578
+ });
79579
+ }
79580
+ }
79581
+ checks.push({
79582
+ name: "Receipt signature",
79583
+ status: "skip",
79584
+ detail: receipt.signature ? "present (local recompute via RedPill keyset canonicalization = roadmap)" : "no signature on receipt",
79585
+ trust: "roadmap"
79586
+ });
79587
+ return {
79588
+ receiptId,
79589
+ verified: Boolean(wireHash && workloadId) && anchorVerified,
79590
+ anchorVerified,
79591
+ checks,
79592
+ wireHash,
79593
+ workloadId,
79594
+ upstream: upstreamEv ? {
79595
+ provider: upstreamEv.provider ?? upstreamEv.upstream_name,
79596
+ result: upstreamEv.result,
79597
+ tcbStatus: upstreamEv.tcb_status
79598
+ } : void 0,
79599
+ anchor
79600
+ };
79601
+ }
79475
79602
  var DEFAULT_CONFIG_DIR = join$1(homedir(), ".t2000");
79476
79603
  function resolveConfigPath(configDir) {
79477
79604
  return join$1(configDir ?? DEFAULT_CONFIG_DIR, "config.json");
@@ -79744,7 +79871,8 @@ var T2000 = class _T2000 extends import_index2.default {
79744
79871
  async chat(params) {
79745
79872
  return chatCompletion(params);
79746
79873
  }
79747
- /** Streaming chat completion — async-iterate the assistant text deltas. */
79874
+ /** Streaming chat completion — async-iterate the assistant text deltas;
79875
+ * the generator returns `{ receiptId }` (confidential attestation) at the end. */
79748
79876
  chatStream(params) {
79749
79877
  return chatCompletionStream(params);
79750
79878
  }
@@ -79752,6 +79880,11 @@ var T2000 = class _T2000 extends import_index2.default {
79752
79880
  async models(opts) {
79753
79881
  return listModels(opts);
79754
79882
  }
79883
+ /** Verify a confidential response by receipt id — checks the signed receipt
79884
+ * + its trustless on-chain Sui anchor. Fails closed on any mismatch. */
79885
+ async verify(receiptId, opts) {
79886
+ return verifyReceipt(receiptId, opts);
79887
+ }
79755
79888
  // -- Swap --
79756
79889
  async swap(params) {
79757
79890
  this.limits.assert({
@@ -80453,7 +80586,10 @@ function registerChatTools(server) {
80453
80586
  text: JSON.stringify({
80454
80587
  model: res.model,
80455
80588
  content: res.content,
80456
- usage: res.usage
80589
+ usage: res.usage,
80590
+ // Confidential (phala/*) → a TEE attestation receipt id,
80591
+ // verifiable at /v1/aci/receipts/{id}.
80592
+ receiptId: res.receiptId
80457
80593
  })
80458
80594
  }
80459
80595
  ]
@@ -80476,6 +80612,23 @@ function registerChatTools(server) {
80476
80612
  }
80477
80613
  }
80478
80614
  );
80615
+ server.tool(
80616
+ "t2000_verify",
80617
+ "Verify a confidential response by its receipt id (the `receiptId` from a confidential t2000_chat). Checks the signed receipt + its trustless on-chain Sui anchor (reads the ReceiptAnchored event straight from a fullnode) and returns a per-check result that's `verified:false` on any forgery/mismatch. No key required.",
80618
+ {
80619
+ receiptId: external_exports.string().describe("A confidential receipt id (rcpt-\u2026)")
80620
+ },
80621
+ async ({ receiptId }) => {
80622
+ try {
80623
+ const result = await verifyReceipt(receiptId);
80624
+ return {
80625
+ content: [{ type: "text", text: JSON.stringify(result) }]
80626
+ };
80627
+ } catch (err) {
80628
+ return errorResult(err);
80629
+ }
80630
+ }
80631
+ );
80479
80632
  }
80480
80633
  var cachedSkills = null;
80481
80634
  function getBakedSkills() {
@@ -80543,7 +80696,7 @@ Through this wallet you can reach essentially any major external API, billed to
80543
80696
  CRITICAL: When the user asks to use any external or paid API, names a provider (e.g. "via fal.ai", "with ElevenLabs"), or requests a capability one of the services above provides, DO NOT say you cannot reach that service, that it isn't on an allowlist, or that there's no connector \u2014 and do NOT fall back to writing a script for the user to run. You CAN do it directly through this wallet. Use t2000_services to discover the endpoint and request shape, then t2000_pay to execute, then show the user the result (display image/audio URLs returned in the response).
80544
80697
 
80545
80698
  Spending is the user's own USDC and every t2000_pay call is bounded by maxPrice. For larger or multi-step spends, state the estimated cost first and proceed once the user is happy. Use t2000_balance to check funds. The v4 wallet is payments-only; savings / lending live on audric.ai.`;
80546
- var PKG_VERSION = "5.15.1";
80699
+ var PKG_VERSION = "5.17.0";
80547
80700
  console.log = (...args) => console.error("[log]", ...args);
80548
80701
  console.warn = (...args) => console.error("[warn]", ...args);
80549
80702
  async function startMcpServer(opts) {
@@ -80610,4 +80763,4 @@ mime-types/index.js:
80610
80763
  @scure/bip39/index.js:
80611
80764
  (*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
80612
80765
  */
80613
- //# sourceMappingURL=dist-JDPHHZMS.js.map
80766
+ //# sourceMappingURL=dist-7QRKMV5A.js.map