@reclaimprotocol/attestor-core 5.0.1-beta.2 → 5.0.1-beta.21

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.
Files changed (131) hide show
  1. package/browser/resources/attestor-browser.min.mjs +4512 -0
  2. package/lib/external-rpc/index.js +10399 -3
  3. package/lib/index.js +8323 -10
  4. package/package.json +9 -4
  5. package/lib/avs/abis/avsDirectoryABI.js +0 -343
  6. package/lib/avs/abis/delegationABI.js +0 -4
  7. package/lib/avs/abis/registryABI.js +0 -728
  8. package/lib/avs/client/create-claim-on-avs.js +0 -168
  9. package/lib/avs/config.js +0 -26
  10. package/lib/avs/contracts/ReclaimServiceManager.js +0 -0
  11. package/lib/avs/contracts/common.js +0 -0
  12. package/lib/avs/contracts/factories/ReclaimServiceManager__factory.js +0 -1183
  13. package/lib/avs/contracts/factories/index.js +0 -4
  14. package/lib/avs/contracts/index.js +0 -6
  15. package/lib/avs/types/index.js +0 -0
  16. package/lib/avs/utils/contracts.js +0 -53
  17. package/lib/avs/utils/register.js +0 -74
  18. package/lib/avs/utils/tasks.js +0 -48
  19. package/lib/client/create-claim.js +0 -461
  20. package/lib/client/index.js +0 -3
  21. package/lib/client/tunnels/make-rpc-tcp-tunnel.js +0 -53
  22. package/lib/client/tunnels/make-rpc-tls-tunnel.js +0 -127
  23. package/lib/client/utils/attestor-pool.js +0 -24
  24. package/lib/client/utils/client-socket.js +0 -120
  25. package/lib/client/utils/message-handler.js +0 -97
  26. package/lib/config/index.js +0 -62
  27. package/lib/external-rpc/benchmark.js +0 -82
  28. package/lib/external-rpc/event-bus.js +0 -17
  29. package/lib/external-rpc/global.d.js +0 -0
  30. package/lib/external-rpc/handle-incoming-msg.js +0 -241
  31. package/lib/external-rpc/jsc-polyfills/1.js +0 -80
  32. package/lib/external-rpc/jsc-polyfills/2.js +0 -15
  33. package/lib/external-rpc/jsc-polyfills/event.js +0 -19
  34. package/lib/external-rpc/jsc-polyfills/index.js +0 -2
  35. package/lib/external-rpc/jsc-polyfills/ws.js +0 -83
  36. package/lib/external-rpc/setup-browser.js +0 -33
  37. package/lib/external-rpc/setup-jsc.js +0 -22
  38. package/lib/external-rpc/types.js +0 -0
  39. package/lib/external-rpc/utils.js +0 -100
  40. package/lib/external-rpc/zk.js +0 -58
  41. package/lib/mechain/abis/governanceABI.js +0 -461
  42. package/lib/mechain/abis/taskABI.js +0 -512
  43. package/lib/mechain/client/create-claim-on-mechain.js +0 -33
  44. package/lib/mechain/client/index.js +0 -1
  45. package/lib/mechain/constants/index.js +0 -8
  46. package/lib/mechain/index.js +0 -2
  47. package/lib/mechain/types/index.js +0 -0
  48. package/lib/proto/api.js +0 -4250
  49. package/lib/proto/tee-bundle.js +0 -1296
  50. package/lib/providers/http/index.js +0 -640
  51. package/lib/providers/http/patch-parse5-tree.js +0 -34
  52. package/lib/providers/http/utils.js +0 -283
  53. package/lib/providers/index.js +0 -7
  54. package/lib/scripts/check-avs-registration.js +0 -28
  55. package/lib/scripts/fallbacks/crypto.js +0 -4
  56. package/lib/scripts/fallbacks/empty.js +0 -4
  57. package/lib/scripts/fallbacks/re2.js +0 -7
  58. package/lib/scripts/fallbacks/snarkjs.js +0 -10
  59. package/lib/scripts/fallbacks/stwo.js +0 -159
  60. package/lib/scripts/generate-provider-types.js +0 -101
  61. package/lib/scripts/generate-receipt.js +0 -101
  62. package/lib/scripts/generate-toprf-keys.js +0 -24
  63. package/lib/scripts/jsc-cli-rpc.js +0 -35
  64. package/lib/scripts/register-avs-operator.js +0 -3
  65. package/lib/scripts/start-server.js +0 -11
  66. package/lib/scripts/update-avs-metadata.js +0 -20
  67. package/lib/scripts/utils.js +0 -10
  68. package/lib/scripts/whitelist-operator.js +0 -16
  69. package/lib/server/create-server.js +0 -105
  70. package/lib/server/handlers/claimTeeBundle.js +0 -232
  71. package/lib/server/handlers/claimTunnel.js +0 -80
  72. package/lib/server/handlers/completeClaimOnChain.js +0 -29
  73. package/lib/server/handlers/createClaimOnChain.js +0 -32
  74. package/lib/server/handlers/createTaskOnMechain.js +0 -57
  75. package/lib/server/handlers/createTunnel.js +0 -98
  76. package/lib/server/handlers/disconnectTunnel.js +0 -8
  77. package/lib/server/handlers/fetchCertificateBytes.js +0 -57
  78. package/lib/server/handlers/index.js +0 -25
  79. package/lib/server/handlers/init.js +0 -33
  80. package/lib/server/handlers/toprf.js +0 -19
  81. package/lib/server/index.js +0 -4
  82. package/lib/server/socket.js +0 -112
  83. package/lib/server/tunnels/make-tcp-tunnel.js +0 -202
  84. package/lib/server/utils/apm.js +0 -29
  85. package/lib/server/utils/assert-valid-claim-request.js +0 -354
  86. package/lib/server/utils/config-env.js +0 -4
  87. package/lib/server/utils/dns.js +0 -24
  88. package/lib/server/utils/gcp-attestation.js +0 -237
  89. package/lib/server/utils/generics.js +0 -45
  90. package/lib/server/utils/iso.js +0 -259
  91. package/lib/server/utils/keep-alive.js +0 -38
  92. package/lib/server/utils/nitro-attestation.js +0 -249
  93. package/lib/server/utils/oprf-raw.js +0 -61
  94. package/lib/server/utils/process-handshake.js +0 -233
  95. package/lib/server/utils/proxy-session.js +0 -6
  96. package/lib/server/utils/tee-oprf-mpc-verification.js +0 -86
  97. package/lib/server/utils/tee-oprf-verification.js +0 -151
  98. package/lib/server/utils/tee-transcript-reconstruction.js +0 -140
  99. package/lib/server/utils/tee-verification.js +0 -358
  100. package/lib/server/utils/validation.js +0 -45
  101. package/lib/types/bgp.js +0 -0
  102. package/lib/types/claims.js +0 -0
  103. package/lib/types/client.js +0 -0
  104. package/lib/types/general.js +0 -0
  105. package/lib/types/handlers.js +0 -0
  106. package/lib/types/index.js +0 -10
  107. package/lib/types/providers.gen.js +0 -16
  108. package/lib/types/providers.js +0 -0
  109. package/lib/types/rpc.js +0 -0
  110. package/lib/types/signatures.js +0 -0
  111. package/lib/types/tunnel.js +0 -0
  112. package/lib/types/zk.js +0 -0
  113. package/lib/utils/auth.js +0 -71
  114. package/lib/utils/b64-json.js +0 -17
  115. package/lib/utils/bgp-listener.js +0 -123
  116. package/lib/utils/claims.js +0 -89
  117. package/lib/utils/env.js +0 -19
  118. package/lib/utils/error.js +0 -54
  119. package/lib/utils/generics.js +0 -268
  120. package/lib/utils/http-parser.js +0 -201
  121. package/lib/utils/index.js +0 -13
  122. package/lib/utils/logger.js +0 -82
  123. package/lib/utils/prepare-packets.js +0 -69
  124. package/lib/utils/redactions.js +0 -135
  125. package/lib/utils/retries.js +0 -26
  126. package/lib/utils/signatures/eth.js +0 -31
  127. package/lib/utils/signatures/index.js +0 -12
  128. package/lib/utils/socket-base.js +0 -96
  129. package/lib/utils/tls.js +0 -58
  130. package/lib/utils/ws.js +0 -22
  131. package/lib/utils/zk.js +0 -625
@@ -1,101 +0,0 @@
1
- import "../server/utils/config-env.js";
2
- import { setCryptoImplementation } from "@reclaimprotocol/tls";
3
- import { webcryptoCrypto } from "@reclaimprotocol/tls/webcrypto";
4
- import { readFile } from "fs/promises";
5
- import {
6
- API_SERVER_PORT,
7
- createClaimOnAttestor,
8
- getAttestorClientFromPool,
9
- getTranscriptString,
10
- logger,
11
- providers,
12
- WS_PATHNAME
13
- } from "../index.js";
14
- import { getCliArgument } from "../scripts/utils.js";
15
- import { createServer, decryptTranscript } from "../server/index.js";
16
- import { assertValidateProviderParams } from "../server/utils/validation.js";
17
- import { getEnvVariable } from "../utils/env.js";
18
- setCryptoImplementation(webcryptoCrypto);
19
- const DEFAULT_ATTESTOR_HOST_PORT = "wss://eu.attestor.reclaimprotocol.org/ws";
20
- const PRIVATE_KEY_HEX = getEnvVariable("PRIVATE_KEY_HEX") || "0x0123788edad59d7c013cdc85e4372f350f828e2cec62d9a2de4560e69aec7f89";
21
- let server;
22
- async function main(receiptParams) {
23
- const paramsJson = receiptParams ?? await getInputParameters();
24
- if (!(paramsJson.name in providers)) {
25
- throw new Error(`Unknown provider "${paramsJson.name}"`);
26
- }
27
- assertValidateProviderParams(paramsJson.name, paramsJson.params);
28
- let attestorHostPort = getCliArgument("attestor") || DEFAULT_ATTESTOR_HOST_PORT;
29
- if (attestorHostPort === "local") {
30
- console.log("starting local attestor server...");
31
- server = await createServer();
32
- attestorHostPort = `ws://localhost:${API_SERVER_PORT}${WS_PATHNAME}`;
33
- }
34
- globalThis.ATTESTOR_BASE_URL = attestorHostPort.replace("ws://", "http://").replace("wss://", "https://");
35
- const zkEngine = getCliArgument("zk") === "gnark" ? "gnark" : "stwo";
36
- const { request, error, claim } = await createClaimOnAttestor({
37
- name: paramsJson.name,
38
- secretParams: paramsJson.secretParams,
39
- params: paramsJson.params,
40
- ownerPrivateKey: PRIVATE_KEY_HEX,
41
- client: { url: attestorHostPort },
42
- logger,
43
- zkEngine
44
- });
45
- if (error) {
46
- console.error("claim creation failed:", error);
47
- } else {
48
- const ctx = claim?.context ? JSON.parse(claim.context) : {};
49
- console.log(`receipt is valid for ${paramsJson.name} provider`);
50
- if (ctx.extractedParameters) {
51
- console.log("extracted params:", ctx.extractedParameters);
52
- }
53
- }
54
- if (!request) {
55
- throw new Error("Missing request in claim");
56
- }
57
- const decTranscript = await decryptTranscript(
58
- request?.transcript,
59
- logger,
60
- zkEngine,
61
- request?.fixedServerIV,
62
- request?.fixedClientIV
63
- );
64
- const transcriptStr = getTranscriptString(decTranscript);
65
- console.log("receipt:\n", transcriptStr);
66
- console.log("claim:\n", claim);
67
- const client = getAttestorClientFromPool(attestorHostPort);
68
- await client.terminateConnection();
69
- }
70
- async function getInputParameters() {
71
- const paramsJsonFile = getCliArgument("json");
72
- if (!paramsJsonFile) {
73
- const name = getCliArgument("name");
74
- const paramsStr = getCliArgument("params");
75
- const secretParamsStr = getCliArgument("secretParams");
76
- if (!name || !paramsStr || !secretParamsStr) {
77
- throw new Error("Either provide --json argument for parameters JSON or provide separately with --name, --params & --secretParams");
78
- }
79
- return {
80
- name,
81
- params: JSON.parse(paramsStr),
82
- secretParams: JSON.parse(secretParamsStr)
83
- };
84
- }
85
- let fileContents = await readFile(paramsJsonFile, "utf8");
86
- for (const variable in process.env) {
87
- fileContents = fileContents.replace(
88
- `{{${variable}}}`,
89
- process.env[variable]
90
- );
91
- }
92
- return JSON.parse(fileContents);
93
- }
94
- main().catch((err) => {
95
- console.error("error in receipt gen", err);
96
- }).finally(() => {
97
- server?.close();
98
- });
99
- export {
100
- main
101
- };
@@ -1,24 +0,0 @@
1
- import { hexlify } from "ethers";
2
- import { logger, makeDefaultOPRFOperator } from "../utils/index.js";
3
- const ENGINE = "gnark";
4
- const TOTAL_KEYS = 10;
5
- const THRESHOLD = 1;
6
- async function main() {
7
- const op = makeDefaultOPRFOperator("chacha20", ENGINE, logger);
8
- const {
9
- publicKey,
10
- privateKey,
11
- shares
12
- } = await op.generateThresholdKeys(TOTAL_KEYS, THRESHOLD);
13
- logEnvValue("TOPRF_PUBLIC_KEY", publicKey);
14
- logEnvValue("TOPRF_PRIVATE_KEY", privateKey);
15
- for (const [i, share] of shares.entries()) {
16
- console.log(`# Share ${i}`);
17
- logEnvValue("TOPRF_SHARE_PUBLIC_KEY", share.publicKey);
18
- logEnvValue("TOPRF_SHARE_PRIVATE_KEY", share.privateKey);
19
- }
20
- }
21
- function logEnvValue(name, value) {
22
- console.log(`${name}=${hexlify(value)}`);
23
- }
24
- void main();
@@ -1,35 +0,0 @@
1
- import "../external-rpc/jsc-polyfills/index.js";
2
- import { setCryptoImplementation } from "@reclaimprotocol/tls";
3
- import { pureJsCrypto } from "@reclaimprotocol/tls/purejs-crypto";
4
- import { handleIncomingMessage } from "../external-rpc/index.js";
5
- import { B64_JSON_REVIVER } from "../utils/b64-json.js";
6
- function readIncomingMsg() {
7
- const cmd2 = readline();
8
- return JSON.parse(cmd2, B64_JSON_REVIVER);
9
- }
10
- setCryptoImplementation(pureJsCrypto);
11
- print("Input base URL for attestor");
12
- const initCmd = readIncomingMsg();
13
- if (initCmd.type !== "init") {
14
- throw new Error("Expected init command");
15
- }
16
- globalThis.RPC_CHANNEL_NAME = "cli";
17
- globalThis.ATTESTOR_BASE_URL = initCmd.attestorBaseUrl;
18
- const channel = {
19
- postMessage(message) {
20
- print(message);
21
- }
22
- };
23
- globalThis[RPC_CHANNEL_NAME] = channel;
24
- print("reading RPC messages...");
25
- let cmd;
26
- while (cmd = readIncomingMsg(), cmd.type !== "quit") {
27
- if (cmd.type === "init") {
28
- continue;
29
- }
30
- handleIncomingMessage(cmd);
31
- await new Promise((resolve) => {
32
- setTimeout(resolve, 500);
33
- });
34
- }
35
- print("done");
@@ -1,3 +0,0 @@
1
- import "src/server/utils/config-env";
2
- import { registerOperator } from "../avs/utils/register.js";
3
- void registerOperator();
@@ -1,11 +0,0 @@
1
- import "../server/utils/config-env.js";
2
- import { setCryptoImplementation } from "@reclaimprotocol/tls";
3
- import { webcryptoCrypto } from "@reclaimprotocol/tls/webcrypto";
4
- import { getApm } from "../server/utils/apm.js";
5
- getApm();
6
- setCryptoImplementation(webcryptoCrypto);
7
- async function main() {
8
- const { createServer } = await import("../server/index.js");
9
- return createServer();
10
- }
11
- main();
@@ -1,20 +0,0 @@
1
- import "src/server/utils/config-env";
2
- import { getContracts } from "../avs/utils/contracts.js";
3
- import { getCliArgument } from "../scripts/utils.js";
4
- async function main() {
5
- const { contract } = getContracts();
6
- const minSignaturesPerTask = getCliArgument("minSignaturesPerTask");
7
- if (!minSignaturesPerTask) {
8
- throw new Error(
9
- "Provide operator address via --minSignaturesPerTask <num>"
10
- );
11
- }
12
- const tx = await contract.updateTaskCreationMetadata({
13
- minSignaturesPerTask: +(minSignaturesPerTask || 0),
14
- maxTaskCreationDelayS: 0,
15
- maxTaskLifetimeS: 0
16
- });
17
- await tx.wait();
18
- console.log("Updated task creation metadata");
19
- }
20
- void main();
@@ -1,10 +0,0 @@
1
- function getCliArgument(arg) {
2
- const index = process.argv.indexOf(`--${arg}`);
3
- if (index === -1) {
4
- return void 0;
5
- }
6
- return process.argv[index + 1];
7
- }
8
- export {
9
- getCliArgument
10
- };
@@ -1,16 +0,0 @@
1
- import "src/server/utils/config-env";
2
- import { getContracts } from "../avs/utils/contracts.js";
3
- import { getCliArgument } from "../scripts/utils.js";
4
- async function main() {
5
- const { contract } = getContracts();
6
- const address = getCliArgument("address");
7
- if (!address) {
8
- throw new Error(
9
- "Provide operator address via --address <addr>"
10
- );
11
- }
12
- const tx = await contract.whitelistAddressAsOperator(address, true);
13
- await tx.wait();
14
- console.log("Whitelisted address:", address);
15
- }
16
- void main();
@@ -1,105 +0,0 @@
1
- import { createServer as createHttpServer } from "http";
2
- import serveStatic from "serve-static";
3
- import { WebSocketServer } from "ws";
4
- import { API_SERVER_PORT, ATTESTOR_ADDRESS_PATHNAME, BROWSER_RPC_PATHNAME, WS_PATHNAME } from "../config/index.js";
5
- import { AttestorServerSocket } from "../server/socket.js";
6
- import { getAttestorAddress } from "../server/utils/generics.js";
7
- import { addKeepAlive } from "../server/utils/keep-alive.js";
8
- import { createBgpListener } from "../utils/bgp-listener.js";
9
- import { getEnvVariable } from "../utils/env.js";
10
- import { logger as LOGGER } from "../utils/index.js";
11
- import { SelectedServiceSignatureType } from "../utils/signatures/index.js";
12
- import { promisifySend } from "../utils/ws.js";
13
- const PORT = +(getEnvVariable("PORT") || API_SERVER_PORT);
14
- const DISABLE_BGP_CHECKS = getEnvVariable("DISABLE_BGP_CHECKS") === "1";
15
- const ATTESTOR_ADDRESS_JSON_RES = JSON.stringify({
16
- address: getAttestorAddress(SelectedServiceSignatureType),
17
- signatureType: SelectedServiceSignatureType
18
- });
19
- async function createServer(port = PORT) {
20
- const http = createHttpServer();
21
- const serveBrowserRpc = serveStatic(
22
- "browser",
23
- {
24
- index: ["index.html"],
25
- setHeaders(res) {
26
- res.setHeader("Access-Control-Allow-Origin", "*");
27
- }
28
- }
29
- );
30
- const bgpListener = !DISABLE_BGP_CHECKS ? createBgpListener(LOGGER.child({ service: "bgp-listener" })) : void 0;
31
- const wss = new WebSocketServer({ noServer: true });
32
- http.on("upgrade", handleUpgrade.bind(wss));
33
- http.on("request", (req, res) => {
34
- const url = URL.parse(req.url || "", "http://localhost");
35
- if (!url) {
36
- res.statusCode = 422;
37
- res.end("Invalid URL");
38
- return;
39
- }
40
- if (url.pathname === ATTESTOR_ADDRESS_PATHNAME) {
41
- res.writeHead(200, { "Content-Type": "application/json" });
42
- res.end(ATTESTOR_ADDRESS_JSON_RES);
43
- return;
44
- }
45
- if (!url.pathname?.startsWith(BROWSER_RPC_PATHNAME)) {
46
- res.statusCode = 404;
47
- res.end("Not found");
48
- return;
49
- }
50
- req.url = req.url.slice(BROWSER_RPC_PATHNAME.length) || "/";
51
- serveBrowserRpc(req, res, (err) => {
52
- if (err) {
53
- LOGGER.error({ err, url: req.url }, "Failed to serve file");
54
- }
55
- res.statusCode = err?.statusCode ?? 404;
56
- res.end(err?.message ?? "Not found");
57
- });
58
- });
59
- http.listen(port);
60
- await new Promise((resolve, reject) => {
61
- http.once("listening", () => resolve());
62
- http.once("error", reject);
63
- });
64
- wss.on("connection", (ws, req) => handleNewClient(ws, req, bgpListener));
65
- LOGGER.info(
66
- {
67
- port,
68
- apiPath: WS_PATHNAME,
69
- browserRpcPath: BROWSER_RPC_PATHNAME,
70
- signerAddress: getAttestorAddress(SelectedServiceSignatureType)
71
- },
72
- "WS server listening"
73
- );
74
- const wssClose = wss.close.bind(wss);
75
- wss.close = (cb) => {
76
- wssClose(() => http.close(cb));
77
- bgpListener?.close();
78
- };
79
- return wss;
80
- }
81
- async function handleNewClient(ws, req, bgpListener) {
82
- promisifySend(ws);
83
- const client = await AttestorServerSocket.acceptConnection(
84
- ws,
85
- { req, bgpListener, logger: LOGGER }
86
- );
87
- if (!client) {
88
- return;
89
- }
90
- ws.serverSocket = client;
91
- addKeepAlive(ws, LOGGER.child({ sessionId: client.sessionId }));
92
- }
93
- function handleUpgrade(request, socket, head) {
94
- const { pathname } = new URL(request.url, "wss://base.url");
95
- if (pathname === WS_PATHNAME) {
96
- this.handleUpgrade(request, socket, head, (ws) => {
97
- this.emit("connection", ws, request);
98
- });
99
- return;
100
- }
101
- socket.destroy();
102
- }
103
- export {
104
- createServer
105
- };
@@ -1,232 +0,0 @@
1
- import { ClaimTeeBundleResponse } from "../../proto/api.js";
2
- import { VerificationBundle } from "../../proto/tee-bundle.js";
3
- import { substituteParamValues } from "../../providers/http/index.js";
4
- import { assertValidProviderTranscript } from "../../server/utils/assert-valid-claim-request.js";
5
- import { getAttestorAddress, niceParseJsonObject, signAsAttestor } from "../../server/utils/generics.js";
6
- import { verifyOprfMpcOutputs } from "../../server/utils/tee-oprf-mpc-verification.js";
7
- import { verifyOprfProofs } from "../../server/utils/tee-oprf-verification.js";
8
- import { reconstructTlsTranscript } from "../../server/utils/tee-transcript-reconstruction.js";
9
- import { verifyTeeBundle } from "../../server/utils/tee-verification.js";
10
- import { AttestorError } from "../../utils/error.js";
11
- import { createSignDataForClaim, getIdentifierFromClaimInfo } from "../../utils/index.js";
12
- const claimTeeBundle = async (teeBundleRequest, { logger, client }) => {
13
- const {
14
- verificationBundle,
15
- data
16
- } = teeBundleRequest;
17
- const res = ClaimTeeBundleResponse.create({ request: teeBundleRequest });
18
- logger.info("Starting TEE bundle verification");
19
- const teeData = await verifyTeeBundle(verificationBundle, logger);
20
- const timestampS = Math.floor(teeData.kOutputPayload.timestampMs / 1e3);
21
- logger.info("Verifying OPRF proofs");
22
- const bundle = VerificationBundle.decode(verificationBundle);
23
- const zkOprfResults = await verifyOprfProofs(
24
- { ...teeData, oprfVerifications: bundle.oprfVerifications },
25
- logger
26
- );
27
- logger.info("Verifying OPRF MPC outputs");
28
- const oprfMpcResults = verifyOprfMpcOutputs(
29
- teeData.kOutputPayload,
30
- teeData.tOutputPayload,
31
- logger
32
- );
33
- const allOprfResults = validateAndCombineOprfResults(zkOprfResults, oprfMpcResults, logger);
34
- logger.info("Starting TLS transcript reconstruction with OPRF replacements");
35
- const transcriptData = await reconstructTlsTranscript(teeData, logger, allOprfResults);
36
- logger.info("Creating plaintext transcript from TEE data");
37
- const plaintextTranscript = createPlaintextTranscriptFromTeeData(transcriptData, logger);
38
- logger.info("Running direct provider validation on TEE reconstructed data");
39
- if (!data) {
40
- throw new AttestorError("ERROR_INVALID_CLAIM", "No claim data provided in TEE bundle request");
41
- }
42
- const validatedClaim = await validateTeeProviderReceipt(
43
- plaintextTranscript,
44
- data,
45
- logger,
46
- { version: client.metadata.clientVersion },
47
- transcriptData.certificateInfo
48
- );
49
- const ctx = niceParseJsonObject(validatedClaim.context, "context");
50
- ctx.pcr0_k = teeData.teekPcr0;
51
- ctx.pcr0_t = teeData.teetPcr0;
52
- ctx.tee_session_id = teeData.teeSessionId;
53
- validatedClaim.context = JSON.stringify(ctx);
54
- res.claim = {
55
- ...validatedClaim,
56
- identifier: getIdentifierFromClaimInfo(validatedClaim),
57
- // Use timestampS from TEE_K bundle for claim signing
58
- timestampS,
59
- // hardcode for compatibility with V1 claims
60
- epoch: 1
61
- };
62
- logger.info({ claim: res.claim }, "TEE bundle claim validation successful");
63
- res.signatures = {
64
- attestorAddress: getAttestorAddress(
65
- client.metadata.signatureType
66
- ),
67
- claimSignature: res.claim ? await signAsAttestor(
68
- createSignDataForClaim(res.claim),
69
- client.metadata.signatureType
70
- ) : new Uint8Array(),
71
- resultSignature: await signAsAttestor(
72
- ClaimTeeBundleResponse.encode(res).finish(),
73
- client.metadata.signatureType
74
- )
75
- };
76
- logger.info("TEE bundle claim processing completed");
77
- return res;
78
- };
79
- function createPlaintextTranscriptFromTeeData(transcriptData, logger) {
80
- const transcript = [];
81
- if (transcriptData.revealedRequest && transcriptData.revealedRequest.length > 0) {
82
- transcript.push({
83
- sender: "client",
84
- message: transcriptData.revealedRequest
85
- });
86
- logger.debug("Added TEE revealed request to plaintext transcript", {
87
- length: transcriptData.revealedRequest.length
88
- });
89
- }
90
- if (transcriptData.reconstructedResponse && transcriptData.reconstructedResponse.length > 0) {
91
- transcript.push({
92
- sender: "server",
93
- message: transcriptData.reconstructedResponse
94
- });
95
- logger.debug("Added TEE consolidated response to plaintext transcript", {
96
- length: transcriptData.reconstructedResponse.length
97
- });
98
- }
99
- if (transcriptData.certificateInfo) {
100
- logger.info("Certificate information available for validation", {
101
- commonName: transcriptData.certificateInfo.commonName,
102
- issuerCommonName: transcriptData.certificateInfo.issuerCommonName,
103
- dnsNames: transcriptData.certificateInfo.dnsNames,
104
- notBefore: new Date(transcriptData.certificateInfo.notBeforeUnix * 1e3).toISOString(),
105
- notAfter: new Date(transcriptData.certificateInfo.notAfterUnix * 1e3).toISOString()
106
- });
107
- }
108
- logger.info("Created plaintext transcript from TEE data", {
109
- totalMessages: transcript.length,
110
- hasRequest: !!transcriptData.revealedRequest?.length,
111
- hasResponse: !!transcriptData.reconstructedResponse?.length,
112
- hasCertificateInfo: !!transcriptData.certificateInfo
113
- });
114
- return transcript;
115
- }
116
- async function validateTeeProviderReceipt(plaintextTranscript, claimInfo, logger, providerCtx, certificateInfo) {
117
- logger.info("Starting direct TEE provider validation", {
118
- provider: claimInfo.provider,
119
- transcriptMessages: plaintextTranscript.length,
120
- hasCertificateInfo: !!certificateInfo
121
- });
122
- if (certificateInfo) {
123
- validateTlsCertificate(claimInfo, certificateInfo, logger);
124
- }
125
- const validatedClaim = await assertValidProviderTranscript(
126
- plaintextTranscript,
127
- claimInfo,
128
- logger,
129
- providerCtx
130
- );
131
- logger.info("TEE provider validation completed successfully", {
132
- provider: validatedClaim.provider,
133
- owner: validatedClaim.owner || "unknown"
134
- });
135
- return validatedClaim;
136
- }
137
- function isHostnameValidForCertificate(hostname, certName) {
138
- if (hostname === certName) {
139
- return true;
140
- }
141
- if (certName.startsWith("*.")) {
142
- const wildcardDomain = certName.slice(2);
143
- if (hostname.endsWith(wildcardDomain)) {
144
- const subdomainPart = hostname.slice(0, -wildcardDomain.length);
145
- if (subdomainPart.endsWith(".")) {
146
- const subdomain = subdomainPart.slice(0, -1);
147
- return !subdomain.includes(".");
148
- }
149
- }
150
- }
151
- return false;
152
- }
153
- function validateTlsCertificate(claimInfo, certificateInfo, logger) {
154
- let claimedHostname;
155
- const paramsWithTemplates = niceParseJsonObject(claimInfo.parameters, "params");
156
- const params = substituteParamValues(paramsWithTemplates, void 0, true).newParams;
157
- if ("url" in params && typeof params.url === "string") {
158
- claimedHostname = new URL(params.url).hostname;
159
- }
160
- if (!claimedHostname) {
161
- logger.warn("Could not extract hostname from claim for certificate validation", {
162
- provider: claimInfo.provider
163
- });
164
- throw new AttestorError(
165
- "ERROR_INVALID_CLAIM",
166
- "Certificate validation failed: hostname not found"
167
- );
168
- }
169
- logger.info("Validating TLS certificate for claimed hostname", {
170
- claimedHostname,
171
- certificateCommonName: certificateInfo.commonName,
172
- certificateDnsNames: certificateInfo.dnsNames
173
- });
174
- const isValidForHostname = isHostnameValidForCertificate(claimedHostname, certificateInfo.commonName) || certificateInfo.dnsNames.some((name) => isHostnameValidForCertificate(claimedHostname, name));
175
- if (!isValidForHostname) {
176
- throw new AttestorError(
177
- "ERROR_INVALID_CLAIM",
178
- `Certificate validation failed: hostname '${claimedHostname}' not valid for certificate (CN: ${certificateInfo.commonName}, SANs: ${certificateInfo.dnsNames.join(", ")})`
179
- );
180
- }
181
- const now = Date.now() / 1e3;
182
- if (now < certificateInfo.notBeforeUnix || now > certificateInfo.notAfterUnix) {
183
- throw new AttestorError(
184
- "ERROR_INVALID_CLAIM",
185
- `Certificate validation failed: certificate not valid at current time (valid from ${new Date(certificateInfo.notBeforeUnix * 1e3).toISOString()} to ${new Date(certificateInfo.notAfterUnix * 1e3).toISOString()})`
186
- );
187
- }
188
- logger.info("TLS certificate validation passed", {
189
- claimedHostname,
190
- validatedAgainst: isHostnameValidForCertificate(claimedHostname, certificateInfo.commonName) ? `CommonName: ${certificateInfo.commonName}` : `SAN: ${certificateInfo.dnsNames.find((name) => isHostnameValidForCertificate(claimedHostname, name))}`
191
- });
192
- }
193
- function validateAndCombineOprfResults(zkOprfResults, oprfMpcResults, logger) {
194
- const allOprfResults = [...zkOprfResults, ...oprfMpcResults];
195
- if (allOprfResults.length === 0) {
196
- return allOprfResults;
197
- }
198
- logger.info(`Combined ${zkOprfResults.length} ZK OPRF + ${oprfMpcResults.length} OPRF MPC results`);
199
- const seen = {};
200
- for (const result of zkOprfResults) {
201
- seen[result.position] = { length: result.length, source: "zk" };
202
- }
203
- for (const result of oprfMpcResults) {
204
- const existing = seen[result.position];
205
- if (existing) {
206
- if (existing.length !== result.length) {
207
- throw new AttestorError(
208
- "ERROR_INVALID_CLAIM",
209
- `OPRF range conflict at position ${result.position}: ZK length ${existing.length} vs MPC length ${result.length}`
210
- );
211
- }
212
- logger.warn(`Duplicate OPRF range at position ${result.position} from both ZK and MPC - using MPC result`);
213
- }
214
- for (const [pos, data] of Object.entries(seen)) {
215
- const position = Number(pos);
216
- const existingEnd = position + data.length;
217
- const newEnd = result.position + result.length;
218
- const overlaps = result.position < existingEnd && newEnd > position && result.position !== position;
219
- if (overlaps) {
220
- throw new AttestorError(
221
- "ERROR_INVALID_CLAIM",
222
- `Overlapping OPRF ranges: [${position}:${existingEnd}] (${data.source}) and [${result.position}:${newEnd}] (mpc)`
223
- );
224
- }
225
- }
226
- seen[result.position] = { length: result.length, source: "mpc" };
227
- }
228
- return allOprfResults;
229
- }
230
- export {
231
- claimTeeBundle
232
- };
@@ -1,80 +0,0 @@
1
- import { MAX_CLAIM_TIMESTAMP_DIFF_S } from "../../config/index.js";
2
- import { ClaimTunnelResponse } from "../../proto/api.js";
3
- import { getApm } from "../../server/utils/apm.js";
4
- import { assertTranscriptsMatch, assertValidClaimRequest } from "../../server/utils/assert-valid-claim-request.js";
5
- import { getAttestorAddress, signAsAttestor } from "../../server/utils/generics.js";
6
- import { AttestorError, createSignDataForClaim, getIdentifierFromClaimInfo, unixTimestampSeconds } from "../../utils/index.js";
7
- const claimTunnel = async (claimRequest, { tx, logger, client }) => {
8
- const {
9
- request,
10
- data: { timestampS } = {}
11
- } = claimRequest;
12
- const tunnel = client.getTunnel(request?.id);
13
- try {
14
- await tunnel.close();
15
- } catch (err) {
16
- logger.debug({ err }, "error closing tunnel");
17
- }
18
- if (tx) {
19
- const transcriptBytes = tunnel.transcript.reduce(
20
- (acc, { message }) => acc + message.length,
21
- 0
22
- );
23
- tx?.setLabel("transcriptBytes", transcriptBytes.toString());
24
- }
25
- if (tunnel.createRequest?.host !== request?.host || tunnel.createRequest?.port !== request?.port || tunnel.createRequest?.geoLocation !== request?.geoLocation || tunnel.createRequest?.proxySessionId !== request?.proxySessionId) {
26
- throw AttestorError.badRequest("Tunnel request does not match");
27
- }
28
- assertTranscriptsMatch(claimRequest.transcript, tunnel.transcript);
29
- const res = ClaimTunnelResponse.create({ request: claimRequest });
30
- try {
31
- const now = unixTimestampSeconds();
32
- if (Math.floor(timestampS - now) > MAX_CLAIM_TIMESTAMP_DIFF_S) {
33
- throw new AttestorError(
34
- "ERROR_INVALID_CLAIM",
35
- `Timestamp provided ${timestampS} is too far off. Current time is ${now}`
36
- );
37
- }
38
- const assertTx = getApm()?.startTransaction("assertValidClaimRequest", { childOf: tx });
39
- try {
40
- const claim = await assertValidClaimRequest(
41
- claimRequest,
42
- client.metadata,
43
- logger
44
- );
45
- res.claim = {
46
- ...claim,
47
- identifier: getIdentifierFromClaimInfo(claim),
48
- // hardcode for compatibility with V1 claims
49
- epoch: 1
50
- };
51
- } catch (err) {
52
- assertTx?.setOutcome("failure");
53
- throw err;
54
- } finally {
55
- assertTx?.end();
56
- }
57
- } catch (err) {
58
- logger.error({ err }, "invalid claim request");
59
- const attestorErr = AttestorError.fromError(err, "ERROR_INVALID_CLAIM");
60
- res.error = attestorErr.toProto();
61
- }
62
- res.signatures = {
63
- attestorAddress: getAttestorAddress(
64
- client.metadata.signatureType
65
- ),
66
- claimSignature: res.claim ? await signAsAttestor(
67
- createSignDataForClaim(res.claim),
68
- client.metadata.signatureType
69
- ) : new Uint8Array(),
70
- resultSignature: await signAsAttestor(
71
- ClaimTunnelResponse.encode(res).finish(),
72
- client.metadata.signatureType
73
- )
74
- };
75
- client.removeTunnel(request.id);
76
- return res;
77
- };
78
- export {
79
- claimTunnel
80
- };
@@ -1,29 +0,0 @@
1
- import { EventLog } from "ethers";
2
- import { getContracts } from "../../avs/utils/contracts.js";
3
- import { getEnvVariable } from "../../utils/env.js";
4
- import { AttestorError, ethersStructToPlainObject } from "../../utils/index.js";
5
- const ACCEPT_CLAIM_PAYMENT_REQUESTS = getEnvVariable("ACCEPT_CLAIM_PAYMENT_REQUESTS") === "1";
6
- const completeClaimOnChain = async ({ chainId: chainIdNum, taskIndex, completedTaskJson }) => {
7
- if (!ACCEPT_CLAIM_PAYMENT_REQUESTS) {
8
- throw new AttestorError(
9
- "ERROR_PAYMENT_REFUSED",
10
- "Payment requests are not accepted at this time"
11
- );
12
- }
13
- const chainId = chainIdNum.toString();
14
- const { contract } = getContracts(chainId.toString());
15
- const task = JSON.parse(completedTaskJson);
16
- const tx = await contract.taskCompleted(task, taskIndex);
17
- const rslt = await tx.wait();
18
- const logs = rslt?.logs ?? [];
19
- const eventLogs = logs.filter((log) => log instanceof EventLog);
20
- const obj = eventLogs[0]?.args;
21
- const plainObj = ethersStructToPlainObject(obj);
22
- return {
23
- txHash: rslt?.hash ?? "",
24
- taskCompletedObjectJson: JSON.stringify(plainObj)
25
- };
26
- };
27
- export {
28
- completeClaimOnChain
29
- };