@t2000/sdk 5.17.0 → 5.19.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/index.cjs +112 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -6
- package/dist/index.d.ts +21 -6
- package/dist/index.js +112 -5
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/dist/index.d.cts
CHANGED
|
@@ -76,6 +76,22 @@ interface VerifyAnchor {
|
|
|
76
76
|
anchoredBy?: string;
|
|
77
77
|
explorer: string;
|
|
78
78
|
}
|
|
79
|
+
/** A typed TCB claim from the attested upstream (dstack ACI §tcb-and-claims). */
|
|
80
|
+
interface UpstreamClaim {
|
|
81
|
+
name: string;
|
|
82
|
+
status: string;
|
|
83
|
+
source?: string;
|
|
84
|
+
}
|
|
85
|
+
interface VerifyUpstream {
|
|
86
|
+
provider?: string;
|
|
87
|
+
modelId?: string;
|
|
88
|
+
result?: string;
|
|
89
|
+
tcbStatus?: string;
|
|
90
|
+
/** The attested-session id (`as_…`) — resolve at GET /v1/aci/sessions/{id}. */
|
|
91
|
+
sessionId?: string;
|
|
92
|
+
/** Typed TCB claims (tee_attested, tcb_up_to_date, gpu_attested, …). */
|
|
93
|
+
claims?: UpstreamClaim[];
|
|
94
|
+
}
|
|
79
95
|
interface VerifyResult {
|
|
80
96
|
receiptId: string;
|
|
81
97
|
/** True iff the receipt resolved AND its on-chain Sui anchor matches. */
|
|
@@ -85,11 +101,7 @@ interface VerifyResult {
|
|
|
85
101
|
checks: VerifyCheck[];
|
|
86
102
|
wireHash?: string;
|
|
87
103
|
workloadId?: string;
|
|
88
|
-
upstream?:
|
|
89
|
-
provider?: string;
|
|
90
|
-
result?: string;
|
|
91
|
-
tcbStatus?: string;
|
|
92
|
-
};
|
|
104
|
+
upstream?: VerifyUpstream;
|
|
93
105
|
anchor?: VerifyAnchor;
|
|
94
106
|
}
|
|
95
107
|
interface VerifyOptions {
|
|
@@ -97,6 +109,9 @@ interface VerifyOptions {
|
|
|
97
109
|
apiBase?: string;
|
|
98
110
|
/** Sui network for the trustless anchor read (default `mainnet`). */
|
|
99
111
|
network?: 'mainnet' | 'testnet';
|
|
112
|
+
/** Confidential model id for fetching the attested receipt-signing key
|
|
113
|
+
* (default `phala/glm-5.2`; the gateway key is workload-wide). */
|
|
114
|
+
model?: string;
|
|
100
115
|
}
|
|
101
116
|
/**
|
|
102
117
|
* Verify a confidential response by its receipt id. Reads the signed receipt
|
|
@@ -1067,4 +1082,4 @@ declare function fullHandle(label: string, parentName?: string): string;
|
|
|
1067
1082
|
*/
|
|
1068
1083
|
declare function displayHandle(label: string, parentName?: string): string;
|
|
1069
1084
|
|
|
1070
|
-
export { AGENT_ID_PARENT, AGENT_ID_PARENT_NAME, AGENT_ID_PARENT_NFT_ID, AUDRIC_PARENT, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, type ApiModel, type AppenderContext, BalanceResponse, type BuildAddLeafParams, type BuildRevokeLeafParams, type ChatMessage, type ChatParams, type ChatResult, type ChatUsage, type CheckStatus, type ComposeTxOptions, type ComposeTxResult, DEFAULT_API_BASE, type DailySpend, DepositInfo, InvalidAddressError, type LabelValidationResult, type LimitAssertInput, LimitEnforcer, LimitExceededError, type LimitKind, type LimitOperation, type LimitsConfig, type LimitsFile, type NormalizedAddress, OverlayFeeConfig, PayOptions, PayResult, PaymentRequest, SPONSORED_PYTH_DEPENDENT_PROVIDERS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SendResult, type SendTransferInput, SendableAsset, type StepPreview, SuinsNotRegisteredError, type SuinsParent, SuinsRpcError, SupportedAsset, type SwapExecuteInput, SwapQuoteResult, SwapResult, SwapRouteResult, T2000, T2000Error, T2000Options, TransactionRecord, TransactionSigner, type TrustMode, type VerifyAnchor, type VerifyCheck, type VerifyOptions, type VerifyResult, WRITE_APPENDER_REGISTRY, type WriteStep, type WriteToolName, ZkLoginProof, approxUsdValue, assertLimitConfig, buildAddLeafTx, buildRevokeLeafTx, chatCompletion, chatCompletionStream, clearLimits, composeTx, dailySpentToday, deriveAllowedAddressesFromPtb, displayHandle, exportPrivateKey, fullHandle, generateKeypair, getAddress, getLimits, getSponsoredSwapProviders, getSwapQuote, hasLimits, keypairFromPrivateKey, listModels, loadKey, looksLikeSuiNs, normalizeAddressInput, queryBalance, readLimitsFile, recordDailySpend, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, saveBech32, saveKey, setLimits, validateLabel, verifyReceipt, walletExists, writeLimitsFile };
|
|
1085
|
+
export { AGENT_ID_PARENT, AGENT_ID_PARENT_NAME, AGENT_ID_PARENT_NFT_ID, AUDRIC_PARENT, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, type ApiModel, type AppenderContext, BalanceResponse, type BuildAddLeafParams, type BuildRevokeLeafParams, type ChatMessage, type ChatParams, type ChatResult, type ChatUsage, type CheckStatus, type ComposeTxOptions, type ComposeTxResult, DEFAULT_API_BASE, type DailySpend, DepositInfo, InvalidAddressError, type LabelValidationResult, type LimitAssertInput, LimitEnforcer, LimitExceededError, type LimitKind, type LimitOperation, type LimitsConfig, type LimitsFile, type NormalizedAddress, OverlayFeeConfig, PayOptions, PayResult, PaymentRequest, SPONSORED_PYTH_DEPENDENT_PROVIDERS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SendResult, type SendTransferInput, SendableAsset, type StepPreview, SuinsNotRegisteredError, type SuinsParent, SuinsRpcError, SupportedAsset, type SwapExecuteInput, SwapQuoteResult, SwapResult, SwapRouteResult, T2000, T2000Error, T2000Options, TransactionRecord, TransactionSigner, type TrustMode, type UpstreamClaim, type VerifyAnchor, type VerifyCheck, type VerifyOptions, type VerifyResult, type VerifyUpstream, WRITE_APPENDER_REGISTRY, type WriteStep, type WriteToolName, ZkLoginProof, approxUsdValue, assertLimitConfig, buildAddLeafTx, buildRevokeLeafTx, chatCompletion, chatCompletionStream, clearLimits, composeTx, dailySpentToday, deriveAllowedAddressesFromPtb, displayHandle, exportPrivateKey, fullHandle, generateKeypair, getAddress, getLimits, getSponsoredSwapProviders, getSwapQuote, hasLimits, keypairFromPrivateKey, listModels, loadKey, looksLikeSuiNs, normalizeAddressInput, queryBalance, readLimitsFile, recordDailySpend, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, saveBech32, saveKey, setLimits, validateLabel, verifyReceipt, walletExists, writeLimitsFile };
|
package/dist/index.d.ts
CHANGED
|
@@ -76,6 +76,22 @@ interface VerifyAnchor {
|
|
|
76
76
|
anchoredBy?: string;
|
|
77
77
|
explorer: string;
|
|
78
78
|
}
|
|
79
|
+
/** A typed TCB claim from the attested upstream (dstack ACI §tcb-and-claims). */
|
|
80
|
+
interface UpstreamClaim {
|
|
81
|
+
name: string;
|
|
82
|
+
status: string;
|
|
83
|
+
source?: string;
|
|
84
|
+
}
|
|
85
|
+
interface VerifyUpstream {
|
|
86
|
+
provider?: string;
|
|
87
|
+
modelId?: string;
|
|
88
|
+
result?: string;
|
|
89
|
+
tcbStatus?: string;
|
|
90
|
+
/** The attested-session id (`as_…`) — resolve at GET /v1/aci/sessions/{id}. */
|
|
91
|
+
sessionId?: string;
|
|
92
|
+
/** Typed TCB claims (tee_attested, tcb_up_to_date, gpu_attested, …). */
|
|
93
|
+
claims?: UpstreamClaim[];
|
|
94
|
+
}
|
|
79
95
|
interface VerifyResult {
|
|
80
96
|
receiptId: string;
|
|
81
97
|
/** True iff the receipt resolved AND its on-chain Sui anchor matches. */
|
|
@@ -85,11 +101,7 @@ interface VerifyResult {
|
|
|
85
101
|
checks: VerifyCheck[];
|
|
86
102
|
wireHash?: string;
|
|
87
103
|
workloadId?: string;
|
|
88
|
-
upstream?:
|
|
89
|
-
provider?: string;
|
|
90
|
-
result?: string;
|
|
91
|
-
tcbStatus?: string;
|
|
92
|
-
};
|
|
104
|
+
upstream?: VerifyUpstream;
|
|
93
105
|
anchor?: VerifyAnchor;
|
|
94
106
|
}
|
|
95
107
|
interface VerifyOptions {
|
|
@@ -97,6 +109,9 @@ interface VerifyOptions {
|
|
|
97
109
|
apiBase?: string;
|
|
98
110
|
/** Sui network for the trustless anchor read (default `mainnet`). */
|
|
99
111
|
network?: 'mainnet' | 'testnet';
|
|
112
|
+
/** Confidential model id for fetching the attested receipt-signing key
|
|
113
|
+
* (default `phala/glm-5.2`; the gateway key is workload-wide). */
|
|
114
|
+
model?: string;
|
|
100
115
|
}
|
|
101
116
|
/**
|
|
102
117
|
* Verify a confidential response by its receipt id. Reads the signed receipt
|
|
@@ -1067,4 +1082,4 @@ declare function fullHandle(label: string, parentName?: string): string;
|
|
|
1067
1082
|
*/
|
|
1068
1083
|
declare function displayHandle(label: string, parentName?: string): string;
|
|
1069
1084
|
|
|
1070
|
-
export { AGENT_ID_PARENT, AGENT_ID_PARENT_NAME, AGENT_ID_PARENT_NFT_ID, AUDRIC_PARENT, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, type ApiModel, type AppenderContext, BalanceResponse, type BuildAddLeafParams, type BuildRevokeLeafParams, type ChatMessage, type ChatParams, type ChatResult, type ChatUsage, type CheckStatus, type ComposeTxOptions, type ComposeTxResult, DEFAULT_API_BASE, type DailySpend, DepositInfo, InvalidAddressError, type LabelValidationResult, type LimitAssertInput, LimitEnforcer, LimitExceededError, type LimitKind, type LimitOperation, type LimitsConfig, type LimitsFile, type NormalizedAddress, OverlayFeeConfig, PayOptions, PayResult, PaymentRequest, SPONSORED_PYTH_DEPENDENT_PROVIDERS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SendResult, type SendTransferInput, SendableAsset, type StepPreview, SuinsNotRegisteredError, type SuinsParent, SuinsRpcError, SupportedAsset, type SwapExecuteInput, SwapQuoteResult, SwapResult, SwapRouteResult, T2000, T2000Error, T2000Options, TransactionRecord, TransactionSigner, type TrustMode, type VerifyAnchor, type VerifyCheck, type VerifyOptions, type VerifyResult, WRITE_APPENDER_REGISTRY, type WriteStep, type WriteToolName, ZkLoginProof, approxUsdValue, assertLimitConfig, buildAddLeafTx, buildRevokeLeafTx, chatCompletion, chatCompletionStream, clearLimits, composeTx, dailySpentToday, deriveAllowedAddressesFromPtb, displayHandle, exportPrivateKey, fullHandle, generateKeypair, getAddress, getLimits, getSponsoredSwapProviders, getSwapQuote, hasLimits, keypairFromPrivateKey, listModels, loadKey, looksLikeSuiNs, normalizeAddressInput, queryBalance, readLimitsFile, recordDailySpend, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, saveBech32, saveKey, setLimits, validateLabel, verifyReceipt, walletExists, writeLimitsFile };
|
|
1085
|
+
export { AGENT_ID_PARENT, AGENT_ID_PARENT_NAME, AGENT_ID_PARENT_NFT_ID, AUDRIC_PARENT, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, type ApiModel, type AppenderContext, BalanceResponse, type BuildAddLeafParams, type BuildRevokeLeafParams, type ChatMessage, type ChatParams, type ChatResult, type ChatUsage, type CheckStatus, type ComposeTxOptions, type ComposeTxResult, DEFAULT_API_BASE, type DailySpend, DepositInfo, InvalidAddressError, type LabelValidationResult, type LimitAssertInput, LimitEnforcer, LimitExceededError, type LimitKind, type LimitOperation, type LimitsConfig, type LimitsFile, type NormalizedAddress, OverlayFeeConfig, PayOptions, PayResult, PaymentRequest, SPONSORED_PYTH_DEPENDENT_PROVIDERS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SendResult, type SendTransferInput, SendableAsset, type StepPreview, SuinsNotRegisteredError, type SuinsParent, SuinsRpcError, SupportedAsset, type SwapExecuteInput, SwapQuoteResult, SwapResult, SwapRouteResult, T2000, T2000Error, T2000Options, TransactionRecord, TransactionSigner, type TrustMode, type UpstreamClaim, type VerifyAnchor, type VerifyCheck, type VerifyOptions, type VerifyResult, type VerifyUpstream, WRITE_APPENDER_REGISTRY, type WriteStep, type WriteToolName, ZkLoginProof, approxUsdValue, assertLimitConfig, buildAddLeafTx, buildRevokeLeafTx, chatCompletion, chatCompletionStream, clearLimits, composeTx, dailySpentToday, deriveAllowedAddressesFromPtb, displayHandle, exportPrivateKey, fullHandle, generateKeypair, getAddress, getLimits, getSponsoredSwapProviders, getSwapQuote, hasLimits, keypairFromPrivateKey, listModels, loadKey, looksLikeSuiNs, normalizeAddressInput, queryBalance, readLimitsFile, recordDailySpend, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, saveBech32, saveKey, setLimits, validateLabel, verifyReceipt, walletExists, writeLimitsFile };
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,9 @@ 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 { secp256k1 } from '@noble/curves/secp256k1';
|
|
15
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
16
|
+
import { hexToBytes, bytesToHex } from '@noble/hashes/utils';
|
|
14
17
|
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
15
18
|
import { SuinsTransaction } from '@mysten/suins';
|
|
16
19
|
|
|
@@ -2025,9 +2028,85 @@ async function listModels(opts) {
|
|
|
2025
2028
|
}));
|
|
2026
2029
|
}
|
|
2027
2030
|
var RECEIPT_ANCHORED_SUFFIX = "::anchor::ReceiptAnchored";
|
|
2031
|
+
function normalizeClaims(claims) {
|
|
2032
|
+
if (!claims) {
|
|
2033
|
+
return [];
|
|
2034
|
+
}
|
|
2035
|
+
if (Array.isArray(claims)) {
|
|
2036
|
+
return claims.filter((c) => c.name).map((c) => ({
|
|
2037
|
+
name: c.name,
|
|
2038
|
+
status: c.status ?? "unknown",
|
|
2039
|
+
source: c.source
|
|
2040
|
+
}));
|
|
2041
|
+
}
|
|
2042
|
+
return Object.entries(claims).map(([name, v]) => ({
|
|
2043
|
+
name,
|
|
2044
|
+
status: v?.status ?? "unknown",
|
|
2045
|
+
source: v?.source
|
|
2046
|
+
}));
|
|
2047
|
+
}
|
|
2028
2048
|
function fullnodeUrl(network) {
|
|
2029
2049
|
return network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
2030
2050
|
}
|
|
2051
|
+
function jcs(value) {
|
|
2052
|
+
if (value === null) {
|
|
2053
|
+
return "null";
|
|
2054
|
+
}
|
|
2055
|
+
if (typeof value === "boolean") {
|
|
2056
|
+
return value ? "true" : "false";
|
|
2057
|
+
}
|
|
2058
|
+
if (typeof value === "number") {
|
|
2059
|
+
if (!Number.isInteger(value)) {
|
|
2060
|
+
throw new Error("JCS: non-integer number");
|
|
2061
|
+
}
|
|
2062
|
+
return String(value);
|
|
2063
|
+
}
|
|
2064
|
+
if (typeof value === "string") {
|
|
2065
|
+
return JSON.stringify(value);
|
|
2066
|
+
}
|
|
2067
|
+
if (Array.isArray(value)) {
|
|
2068
|
+
return `[${value.map(jcs).join(",")}]`;
|
|
2069
|
+
}
|
|
2070
|
+
const keys = Object.keys(value).sort();
|
|
2071
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${jcs(value[k])}`).join(",")}}`;
|
|
2072
|
+
}
|
|
2073
|
+
function verifyReceiptSignature(receipt, signingKeyHex) {
|
|
2074
|
+
try {
|
|
2075
|
+
const sig = receipt.signature;
|
|
2076
|
+
if (sig?.algo !== "ecdsa-secp256k1" || !sig.value) {
|
|
2077
|
+
return false;
|
|
2078
|
+
}
|
|
2079
|
+
const canonical = {
|
|
2080
|
+
api_version: receipt.api_version ?? "",
|
|
2081
|
+
receipt_id: receipt.receipt_id ?? "",
|
|
2082
|
+
chat_id: receipt.chat_id ?? null,
|
|
2083
|
+
workload_id: receipt.workload_id ?? "",
|
|
2084
|
+
workload_keyset_digest: receipt.workload_keyset_digest ?? "",
|
|
2085
|
+
endpoint: receipt.endpoint ?? "",
|
|
2086
|
+
method: receipt.method ?? "",
|
|
2087
|
+
served_at: receipt.served_at ?? 0,
|
|
2088
|
+
event_log: receipt.event_log ?? [],
|
|
2089
|
+
signature: { algo: sig.algo, key_id: sig.key_id ?? "" }
|
|
2090
|
+
};
|
|
2091
|
+
const prehash = sha256(new TextEncoder().encode(jcs(canonical)));
|
|
2092
|
+
const sigBytes = hexToBytes(sig.value);
|
|
2093
|
+
if (sigBytes.length !== 65) {
|
|
2094
|
+
return false;
|
|
2095
|
+
}
|
|
2096
|
+
let v = sigBytes[64];
|
|
2097
|
+
if (v >= 27 && v <= 30) {
|
|
2098
|
+
v -= 27;
|
|
2099
|
+
}
|
|
2100
|
+
if (v > 3) {
|
|
2101
|
+
return false;
|
|
2102
|
+
}
|
|
2103
|
+
const recovered = secp256k1.Signature.fromCompact(sigBytes.slice(0, 64)).addRecoveryBit(v).recoverPublicKey(prehash).toHex(false);
|
|
2104
|
+
const endorsed = bytesToHex(hexToBytes(signingKeyHex.replace(/^0x/, "")));
|
|
2105
|
+
return recovered.toLowerCase() === endorsed.toLowerCase();
|
|
2106
|
+
} catch {
|
|
2107
|
+
return false;
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2031
2110
|
async function verifyReceipt(receiptId, opts = {}) {
|
|
2032
2111
|
const base = opts.apiBase ?? DEFAULT_API_BASE;
|
|
2033
2112
|
const network = opts.network ?? "mainnet";
|
|
@@ -2059,6 +2138,7 @@ async function verifyReceipt(receiptId, opts = {}) {
|
|
|
2059
2138
|
});
|
|
2060
2139
|
const upstreamEv = receipt.event_log.find((e) => e.type === "upstream.verified");
|
|
2061
2140
|
const upstreamOk = upstreamEv?.result === "verified";
|
|
2141
|
+
const claims = normalizeClaims(upstreamEv?.claims);
|
|
2062
2142
|
checks.push({
|
|
2063
2143
|
name: "Confidential upstream",
|
|
2064
2144
|
status: upstreamEv ? upstreamOk ? "pass" : "fail" : "skip",
|
|
@@ -2121,23 +2201,50 @@ async function verifyReceipt(receiptId, opts = {}) {
|
|
|
2121
2201
|
});
|
|
2122
2202
|
}
|
|
2123
2203
|
}
|
|
2204
|
+
let signatureForged = false;
|
|
2205
|
+
let sigStatus = "skip";
|
|
2206
|
+
let sigDetail = "no signature on receipt";
|
|
2207
|
+
if (receipt.signature?.value) {
|
|
2208
|
+
try {
|
|
2209
|
+
const model = opts.model ?? "phala/glm-5.2";
|
|
2210
|
+
const res = await fetch(
|
|
2211
|
+
`${base}/aci/attestation?model=${encodeURIComponent(model)}`
|
|
2212
|
+
);
|
|
2213
|
+
const att = res.ok ? await res.json() : null;
|
|
2214
|
+
if (!att?.signingKey) {
|
|
2215
|
+
sigDetail = "could not fetch the attested keyset to check the signature";
|
|
2216
|
+
} else if (att.workloadId && att.workloadId !== workloadId) {
|
|
2217
|
+
sigDetail = `attested keyset is for a different workload \u2014 pass --model for ${workloadId}`;
|
|
2218
|
+
} else {
|
|
2219
|
+
const ok = verifyReceiptSignature(receipt, att.signingKey);
|
|
2220
|
+
sigStatus = ok ? "pass" : "fail";
|
|
2221
|
+
signatureForged = !ok;
|
|
2222
|
+
sigDetail = ok ? `signed by the attested receipt key (${receipt.signature.key_id ?? "key"})` : "signature does NOT recover the attested receipt key \u2014 forged/altered";
|
|
2223
|
+
}
|
|
2224
|
+
} catch {
|
|
2225
|
+
sigDetail = "signature check errored";
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2124
2228
|
checks.push({
|
|
2125
2229
|
name: "Receipt signature",
|
|
2126
|
-
status:
|
|
2127
|
-
detail:
|
|
2128
|
-
trust: "roadmap"
|
|
2230
|
+
status: sigStatus,
|
|
2231
|
+
detail: sigDetail,
|
|
2232
|
+
trust: sigStatus === "skip" ? "roadmap" : "trustless"
|
|
2129
2233
|
});
|
|
2130
2234
|
return {
|
|
2131
2235
|
receiptId,
|
|
2132
|
-
verified: Boolean(wireHash && workloadId) && anchorVerified,
|
|
2236
|
+
verified: Boolean(wireHash && workloadId) && anchorVerified && !signatureForged,
|
|
2133
2237
|
anchorVerified,
|
|
2134
2238
|
checks,
|
|
2135
2239
|
wireHash,
|
|
2136
2240
|
workloadId,
|
|
2137
2241
|
upstream: upstreamEv ? {
|
|
2138
2242
|
provider: upstreamEv.provider ?? upstreamEv.upstream_name,
|
|
2243
|
+
modelId: upstreamEv.model_id,
|
|
2139
2244
|
result: upstreamEv.result,
|
|
2140
|
-
tcbStatus: upstreamEv.tcb_status
|
|
2245
|
+
tcbStatus: upstreamEv.tcb_status,
|
|
2246
|
+
sessionId: upstreamEv.session_id,
|
|
2247
|
+
claims: claims.length > 0 ? claims : void 0
|
|
2141
2248
|
} : void 0,
|
|
2142
2249
|
anchor
|
|
2143
2250
|
};
|