@t2000/mcp 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.
- package/dist/bin.js +161 -8
- package/dist/bin.js.map +1 -1
- package/dist/index.js +161 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -78816,10 +78816,10 @@ async function finalize(response, opts) {
|
|
|
78816
78816
|
return { status: response.status, body: body2, paid: opts.paid };
|
|
78817
78817
|
}
|
|
78818
78818
|
async function makeGrpcBuildClient(client) {
|
|
78819
|
-
const { SuiGrpcClient:
|
|
78819
|
+
const { SuiGrpcClient: SuiGrpcClient3 } = await Promise.resolve().then(() => (init_grpc(), grpc_exports));
|
|
78820
78820
|
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
78821
78821
|
const baseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
78822
|
-
return new
|
|
78822
|
+
return new SuiGrpcClient3({ baseUrl, network });
|
|
78823
78823
|
}
|
|
78824
78824
|
function atomicToHuman(raw, decimals) {
|
|
78825
78825
|
return Number(raw) / 10 ** decimals;
|
|
@@ -79370,7 +79370,9 @@ function body(params, stream4) {
|
|
|
79370
79370
|
return JSON.stringify({
|
|
79371
79371
|
model: params.model,
|
|
79372
79372
|
messages: params.messages,
|
|
79373
|
-
|
|
79373
|
+
// include_usage → the final stream chunk carries usage + x_receipt_id
|
|
79374
|
+
// (the confidential attestation receipt) so we can surface it after a stream.
|
|
79375
|
+
...stream4 ? { stream: true, stream_options: { include_usage: true } } : {},
|
|
79374
79376
|
...params.maxTokens != null ? { max_tokens: params.maxTokens } : {},
|
|
79375
79377
|
...params.temperature != null ? { temperature: params.temperature } : {}
|
|
79376
79378
|
});
|
|
@@ -79386,12 +79388,14 @@ async function chatCompletion(params) {
|
|
|
79386
79388
|
if (!res.ok) {
|
|
79387
79389
|
await failBody(res);
|
|
79388
79390
|
}
|
|
79391
|
+
const receiptId = res.headers.get("x-receipt-id") ?? void 0;
|
|
79389
79392
|
const raw = await res.json();
|
|
79390
79393
|
const content = raw?.choices?.[0]?.message?.content ?? "";
|
|
79391
79394
|
return {
|
|
79392
79395
|
content,
|
|
79393
79396
|
model: raw?.model ?? params.model,
|
|
79394
79397
|
usage: usageOf(raw),
|
|
79398
|
+
receiptId,
|
|
79395
79399
|
raw
|
|
79396
79400
|
};
|
|
79397
79401
|
}
|
|
@@ -79405,11 +79409,12 @@ async function* chatCompletionStream(params) {
|
|
|
79405
79409
|
});
|
|
79406
79410
|
if (!(res.ok && res.body)) {
|
|
79407
79411
|
await failBody(res);
|
|
79408
|
-
return;
|
|
79412
|
+
return {};
|
|
79409
79413
|
}
|
|
79410
79414
|
const reader = res.body.getReader();
|
|
79411
79415
|
const decoder = new TextDecoder();
|
|
79412
79416
|
let buffer = "";
|
|
79417
|
+
let receiptId;
|
|
79413
79418
|
while (true) {
|
|
79414
79419
|
const { done, value } = await reader.read();
|
|
79415
79420
|
if (done) {
|
|
@@ -79425,10 +79430,13 @@ async function* chatCompletionStream(params) {
|
|
|
79425
79430
|
}
|
|
79426
79431
|
const data = trimmed.slice(5).trim();
|
|
79427
79432
|
if (data === "[DONE]") {
|
|
79428
|
-
return;
|
|
79433
|
+
return { receiptId };
|
|
79429
79434
|
}
|
|
79430
79435
|
try {
|
|
79431
79436
|
const json = JSON.parse(data);
|
|
79437
|
+
if (json.x_receipt_id) {
|
|
79438
|
+
receiptId = json.x_receipt_id;
|
|
79439
|
+
}
|
|
79432
79440
|
const delta = json.choices?.[0]?.delta?.content;
|
|
79433
79441
|
if (typeof delta === "string" && delta) {
|
|
79434
79442
|
yield delta;
|
|
@@ -79437,6 +79445,7 @@ async function* chatCompletionStream(params) {
|
|
|
79437
79445
|
}
|
|
79438
79446
|
}
|
|
79439
79447
|
}
|
|
79448
|
+
return { receiptId };
|
|
79440
79449
|
}
|
|
79441
79450
|
async function listModels(opts) {
|
|
79442
79451
|
const base = opts?.apiBase ?? DEFAULT_API_BASE;
|
|
@@ -79457,6 +79466,124 @@ async function listModels(opts) {
|
|
|
79457
79466
|
privacy: m.privacy ?? m.privacy_tier
|
|
79458
79467
|
}));
|
|
79459
79468
|
}
|
|
79469
|
+
var RECEIPT_ANCHORED_SUFFIX = "::anchor::ReceiptAnchored";
|
|
79470
|
+
function fullnodeUrl(network) {
|
|
79471
|
+
return network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
79472
|
+
}
|
|
79473
|
+
async function verifyReceipt(receiptId, opts = {}) {
|
|
79474
|
+
const base = opts.apiBase ?? DEFAULT_API_BASE;
|
|
79475
|
+
const network = opts.network ?? "mainnet";
|
|
79476
|
+
const checks = [];
|
|
79477
|
+
let receipt = null;
|
|
79478
|
+
try {
|
|
79479
|
+
const res = await fetch(`${base}/aci/receipts/${encodeURIComponent(receiptId)}`);
|
|
79480
|
+
if (res.ok) {
|
|
79481
|
+
receipt = await res.json();
|
|
79482
|
+
}
|
|
79483
|
+
} catch {
|
|
79484
|
+
}
|
|
79485
|
+
if (!receipt?.event_log) {
|
|
79486
|
+
checks.push({
|
|
79487
|
+
name: "Receipt",
|
|
79488
|
+
status: "fail",
|
|
79489
|
+
detail: "receipt not found or malformed",
|
|
79490
|
+
trust: "receipt-asserted"
|
|
79491
|
+
});
|
|
79492
|
+
return { receiptId, verified: false, anchorVerified: false, checks };
|
|
79493
|
+
}
|
|
79494
|
+
const wireHash = receipt.event_log.find((e) => e.type === "response.returned")?.wire_hash;
|
|
79495
|
+
const workloadId = receipt.workload_id;
|
|
79496
|
+
checks.push({
|
|
79497
|
+
name: "Receipt",
|
|
79498
|
+
status: wireHash && workloadId ? "pass" : "fail",
|
|
79499
|
+
detail: wireHash ? `well-formed (${receipt.event_log.length} log entries, workload ${workloadId})` : "missing response wire_hash / workload_id",
|
|
79500
|
+
trust: "receipt-asserted"
|
|
79501
|
+
});
|
|
79502
|
+
const upstreamEv = receipt.event_log.find((e) => e.type === "upstream.verified");
|
|
79503
|
+
const upstreamOk = upstreamEv?.result === "verified";
|
|
79504
|
+
checks.push({
|
|
79505
|
+
name: "Confidential upstream",
|
|
79506
|
+
status: upstreamEv ? upstreamOk ? "pass" : "fail" : "skip",
|
|
79507
|
+
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?)",
|
|
79508
|
+
trust: "receipt-asserted"
|
|
79509
|
+
});
|
|
79510
|
+
let anchorVerified = false;
|
|
79511
|
+
let anchor;
|
|
79512
|
+
let digest;
|
|
79513
|
+
try {
|
|
79514
|
+
const res = await fetch(`${base}/aci/anchor/${encodeURIComponent(receiptId)}`);
|
|
79515
|
+
if (res.ok) {
|
|
79516
|
+
const j = await res.json();
|
|
79517
|
+
digest = j.txDigest;
|
|
79518
|
+
}
|
|
79519
|
+
} catch {
|
|
79520
|
+
}
|
|
79521
|
+
if (!digest) {
|
|
79522
|
+
checks.push({
|
|
79523
|
+
name: "Sui anchor",
|
|
79524
|
+
status: "fail",
|
|
79525
|
+
detail: `no anchor on record \u2014 POST ${base}/aci/anchor/${receiptId} to create one`,
|
|
79526
|
+
trust: "trustless"
|
|
79527
|
+
});
|
|
79528
|
+
} else {
|
|
79529
|
+
try {
|
|
79530
|
+
const client = new SuiGrpcClient({ baseUrl: fullnodeUrl(network), network });
|
|
79531
|
+
const tx = await client.core.getTransaction({
|
|
79532
|
+
digest,
|
|
79533
|
+
include: { events: true }
|
|
79534
|
+
});
|
|
79535
|
+
const txn = tx.$kind === "Transaction" ? tx.Transaction : tx.FailedTransaction;
|
|
79536
|
+
const ev = (txn.events ?? []).find(
|
|
79537
|
+
(e) => e.eventType.endsWith(RECEIPT_ANCHORED_SUFFIX)
|
|
79538
|
+
);
|
|
79539
|
+
const data = ev?.json ?? {};
|
|
79540
|
+
const onChainReceipt = String(data.receipt_id ?? "");
|
|
79541
|
+
const onChainWire = String(data.wire_hash ?? "");
|
|
79542
|
+
const onChainWorkload = String(data.workload_id ?? "");
|
|
79543
|
+
const matches = onChainReceipt === receiptId && onChainWire === wireHash && onChainWorkload === workloadId;
|
|
79544
|
+
anchorVerified = matches;
|
|
79545
|
+
anchor = {
|
|
79546
|
+
txDigest: digest,
|
|
79547
|
+
anchoredAtMs: data.anchored_at_ms ? String(data.anchored_at_ms) : void 0,
|
|
79548
|
+
anchoredBy: data.anchored_by ? String(data.anchored_by) : void 0,
|
|
79549
|
+
explorer: `https://suiscan.xyz/${network}/tx/${digest}`
|
|
79550
|
+
};
|
|
79551
|
+
checks.push({
|
|
79552
|
+
name: "Sui anchor",
|
|
79553
|
+
status: matches ? "pass" : "fail",
|
|
79554
|
+
detail: matches ? `on-chain ReceiptAnchored matches (wire_hash + workload_id), tx ${digest}` : `on-chain event does NOT match the receipt (wire ${onChainWire || "absent"})`,
|
|
79555
|
+
trust: "trustless"
|
|
79556
|
+
});
|
|
79557
|
+
} catch (e) {
|
|
79558
|
+
checks.push({
|
|
79559
|
+
name: "Sui anchor",
|
|
79560
|
+
status: "fail",
|
|
79561
|
+
detail: `could not read anchor tx ${digest}: ${e instanceof Error ? e.message : "error"}`,
|
|
79562
|
+
trust: "trustless"
|
|
79563
|
+
});
|
|
79564
|
+
}
|
|
79565
|
+
}
|
|
79566
|
+
checks.push({
|
|
79567
|
+
name: "Receipt signature",
|
|
79568
|
+
status: "skip",
|
|
79569
|
+
detail: receipt.signature ? "present (local recompute via RedPill keyset canonicalization = roadmap)" : "no signature on receipt",
|
|
79570
|
+
trust: "roadmap"
|
|
79571
|
+
});
|
|
79572
|
+
return {
|
|
79573
|
+
receiptId,
|
|
79574
|
+
verified: Boolean(wireHash && workloadId) && anchorVerified,
|
|
79575
|
+
anchorVerified,
|
|
79576
|
+
checks,
|
|
79577
|
+
wireHash,
|
|
79578
|
+
workloadId,
|
|
79579
|
+
upstream: upstreamEv ? {
|
|
79580
|
+
provider: upstreamEv.provider ?? upstreamEv.upstream_name,
|
|
79581
|
+
result: upstreamEv.result,
|
|
79582
|
+
tcbStatus: upstreamEv.tcb_status
|
|
79583
|
+
} : void 0,
|
|
79584
|
+
anchor
|
|
79585
|
+
};
|
|
79586
|
+
}
|
|
79460
79587
|
var DEFAULT_CONFIG_DIR = join$1(homedir(), ".t2000");
|
|
79461
79588
|
function resolveConfigPath(configDir) {
|
|
79462
79589
|
return join$1(configDir ?? DEFAULT_CONFIG_DIR, "config.json");
|
|
@@ -79729,7 +79856,8 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
79729
79856
|
async chat(params) {
|
|
79730
79857
|
return chatCompletion(params);
|
|
79731
79858
|
}
|
|
79732
|
-
/** Streaming chat completion — async-iterate the assistant text deltas
|
|
79859
|
+
/** Streaming chat completion — async-iterate the assistant text deltas;
|
|
79860
|
+
* the generator returns `{ receiptId }` (confidential attestation) at the end. */
|
|
79733
79861
|
chatStream(params) {
|
|
79734
79862
|
return chatCompletionStream(params);
|
|
79735
79863
|
}
|
|
@@ -79737,6 +79865,11 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
79737
79865
|
async models(opts) {
|
|
79738
79866
|
return listModels(opts);
|
|
79739
79867
|
}
|
|
79868
|
+
/** Verify a confidential response by receipt id — checks the signed receipt
|
|
79869
|
+
* + its trustless on-chain Sui anchor. Fails closed on any mismatch. */
|
|
79870
|
+
async verify(receiptId, opts) {
|
|
79871
|
+
return verifyReceipt(receiptId, opts);
|
|
79872
|
+
}
|
|
79740
79873
|
// -- Swap --
|
|
79741
79874
|
async swap(params) {
|
|
79742
79875
|
this.limits.assert({
|
|
@@ -80456,7 +80589,10 @@ function registerChatTools(server) {
|
|
|
80456
80589
|
text: JSON.stringify({
|
|
80457
80590
|
model: res.model,
|
|
80458
80591
|
content: res.content,
|
|
80459
|
-
usage: res.usage
|
|
80592
|
+
usage: res.usage,
|
|
80593
|
+
// Confidential (phala/*) → a TEE attestation receipt id,
|
|
80594
|
+
// verifiable at /v1/aci/receipts/{id}.
|
|
80595
|
+
receiptId: res.receiptId
|
|
80460
80596
|
})
|
|
80461
80597
|
}
|
|
80462
80598
|
]
|
|
@@ -80479,6 +80615,23 @@ function registerChatTools(server) {
|
|
|
80479
80615
|
}
|
|
80480
80616
|
}
|
|
80481
80617
|
);
|
|
80618
|
+
server.tool(
|
|
80619
|
+
"t2000_verify",
|
|
80620
|
+
"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.",
|
|
80621
|
+
{
|
|
80622
|
+
receiptId: external_exports.string().describe("A confidential receipt id (rcpt-\u2026)")
|
|
80623
|
+
},
|
|
80624
|
+
async ({ receiptId }) => {
|
|
80625
|
+
try {
|
|
80626
|
+
const result = await verifyReceipt(receiptId);
|
|
80627
|
+
return {
|
|
80628
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
80629
|
+
};
|
|
80630
|
+
} catch (err) {
|
|
80631
|
+
return errorResult(err);
|
|
80632
|
+
}
|
|
80633
|
+
}
|
|
80634
|
+
);
|
|
80482
80635
|
}
|
|
80483
80636
|
|
|
80484
80637
|
// src/skills-prompts.ts
|
|
@@ -80552,7 +80705,7 @@ CRITICAL: When the user asks to use any external or paid API, names a provider (
|
|
|
80552
80705
|
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.`;
|
|
80553
80706
|
|
|
80554
80707
|
// src/index.ts
|
|
80555
|
-
var PKG_VERSION = "5.
|
|
80708
|
+
var PKG_VERSION = "5.17.0" ;
|
|
80556
80709
|
console.log = (...args) => console.error("[log]", ...args);
|
|
80557
80710
|
console.warn = (...args) => console.error("[warn]", ...args);
|
|
80558
80711
|
async function startMcpServer(opts) {
|