blindseal 0.5.0 → 0.5.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.
Files changed (34) hide show
  1. package/dashboard/assets/blindseal_verifier_bg-BYF7rQG1.wasm +0 -0
  2. package/dashboard/assets/geist-400-gapTbOY8.woff2 +0 -0
  3. package/dashboard/assets/geist-500-uokXdC-Q.woff2 +0 -0
  4. package/dashboard/assets/geist-600-DFOURf8L.woff2 +0 -0
  5. package/dashboard/assets/geist-mono-400-DTRLJnHl.woff2 +0 -0
  6. package/dashboard/assets/geist-mono-600-V-KvD_pi.woff2 +0 -0
  7. package/dashboard/assets/index-ErSVkiAF.css +1 -0
  8. package/dashboard/assets/index-cOSTL8eT.js +1 -0
  9. package/dashboard/assets/index-p0eB3k2y.js +70 -0
  10. package/dashboard/index.html +76 -0
  11. package/dist/attest-VWYZAOLY.js +346 -0
  12. package/dist/{audit-C756XFXR.js → audit-G4DDMAXH.js} +1 -1
  13. package/dist/chunk-6EU4GH4P.js +513 -0
  14. package/dist/chunk-B44GZXDX.js +136 -0
  15. package/dist/chunk-CIUQ6WHJ.js +88 -0
  16. package/dist/{chunk-BTIXDNTV.js → chunk-DJL2E6RF.js} +69 -6
  17. package/dist/{chunk-PQ457W6T.js → chunk-VSOUJM6X.js} +1 -0
  18. package/dist/{chunk-JJY62YXJ.js → chunk-ZZTWGFH2.js} +0 -20
  19. package/dist/dashboard-J6BA7OBL.js +105 -0
  20. package/dist/decide.js +1 -1
  21. package/dist/index.js +122 -1307
  22. package/dist/{init.js → init-ZP3SLHM3.js} +122 -36
  23. package/dist/run-YQBNEPSD.js +17 -0
  24. package/dist/{submit-2UALCRX2.js → submit-D6MQTAXT.js} +1 -1
  25. package/dist/verify-RISAGKXC.js +98 -0
  26. package/fixtures/attestation-sample.json +25 -0
  27. package/fixtures/attestation-tampered.json +29 -0
  28. package/fixtures/attestations.json +174 -0
  29. package/fixtures/audit.json +1810 -0
  30. package/fixtures/decisions.json +9899 -0
  31. package/fixtures/policy.json +216 -0
  32. package/package.json +8 -8
  33. package/dist/attest-QLIE2OSQ.js +0 -195
  34. package/dist/verify-HO4IU7XV.js +0 -45
@@ -1,7 +1,20 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ loadIdentity
4
+ } from "./chunk-VSOUJM6X.js";
5
+ import {
6
+ blindsealHome,
7
+ nearestFixturesDir,
8
+ shippedFixturesDir
9
+ } from "./chunk-CIUQ6WHJ.js";
2
10
  import "./chunk-PDX44BCA.js";
3
11
 
4
12
  // src/cli/init.ts
13
+ import { randomBytes } from "crypto";
14
+ import { chmodSync, copyFileSync as copyFileSync2, existsSync as existsSync2, mkdirSync, statSync, writeFileSync as writeFileSync2 } from "fs";
15
+ import path2 from "path";
16
+
17
+ // src/cli/wrap.ts
5
18
  import { readFileSync, writeFileSync, existsSync, copyFileSync } from "fs";
6
19
  import path from "path";
7
20
  import os from "os";
@@ -17,21 +30,18 @@ var yellow = (s) => color(s, "33");
17
30
  var green = (s) => color(s, "32");
18
31
  var cyan = (s) => color(s, "36");
19
32
  var bold = (s) => color(s, "1");
20
- var HELP = `blindseal init \u2014 wrap your MCP servers with the Blindseal proxy
33
+ var HELP = `blindseal init --wrap \u2014 wrap your MCP servers with the Blindseal proxy
21
34
 
22
35
  Usage:
23
- blindseal init detect configs, show diff, confirm, write
24
- blindseal init --yes skip confirmation
25
- blindseal init --dry-run preview only, never write
26
- blindseal init unwrap restore from .blindseal-backup files
27
- blindseal init --config <path> operate on one specific config file
28
- blindseal init --help, -h this help
29
-
30
- Telemetry is OFF by default for newly-wrapped servers. To opt in, set
31
- BLINDSEAL_TELEMETRY=1 in your shell or in the wrapped server's env block.
36
+ blindseal init --wrap detect configs, show diff, confirm, write
37
+ blindseal init --wrap --yes skip confirmation
38
+ blindseal init --wrap --dry-run preview only, never write
39
+ blindseal init --unwrap restore from .blindseal-backup files
40
+ blindseal init --wrap --config <path> operate on one specific config file
41
+ blindseal init --wrap --help, -h this help
32
42
 
33
43
  Backups: every modified file is copied to <path>.blindseal-backup before writing.
34
- Re-running blindseal init is safe \u2014 already-wrapped servers are skipped.
44
+ Re-running blindseal init --wrap is safe \u2014 already-wrapped servers are skipped.
35
45
  `;
36
46
  function parseArgs(argv) {
37
47
  const out = { command: "init", yes: false, dryRun: false, showHelp: false };
@@ -41,8 +51,8 @@ function parseArgs(argv) {
41
51
  else if (a === "--yes" || a === "-y") out.yes = true;
42
52
  else if (a === "--dry-run") out.dryRun = true;
43
53
  else if (a === "--config") out.configOverride = argv[++i];
44
- else if (a === "unwrap") out.command = "unwrap";
45
- else if (a === "init") out.command = "init";
54
+ else if (a === "--unwrap" || a === "unwrap") out.command = "unwrap";
55
+ else if (a === "--wrap" || a === "wrap" || a === "init") out.command = "init";
46
56
  else if (a?.startsWith("--")) throw new Error(`unknown flag: ${a}`);
47
57
  }
48
58
  return out;
@@ -204,12 +214,12 @@ async function confirm(question) {
204
214
  });
205
215
  });
206
216
  }
207
- async function runInit(argv) {
217
+ async function runWrap(argv) {
208
218
  let args;
209
219
  try {
210
220
  args = parseArgs(argv);
211
221
  } catch (e) {
212
- process.stderr.write(`blindseal init: ${e.message}
222
+ process.stderr.write(`blindseal init --wrap: ${e.message}
213
223
  `);
214
224
  process.stderr.write(HELP);
215
225
  return 2;
@@ -233,7 +243,7 @@ async function runInit(argv) {
233
243
  }
234
244
  }
235
245
  if (restored === 0) {
236
- process.stderr.write("blindseal init unwrap: no .blindseal-backup files found\n");
246
+ process.stderr.write("blindseal init --unwrap: no .blindseal-backup files found\n");
237
247
  return 1;
238
248
  }
239
249
  return 0;
@@ -242,7 +252,7 @@ async function runInit(argv) {
242
252
  const presentPlans = plans.filter((p) => p.exists);
243
253
  if (presentPlans.length === 0) {
244
254
  process.stderr.write(
245
- "blindseal init: no MCP configs found in default locations.\n Looked in:\n" + targets.map((p) => ` - ${p}`).join("\n") + "\n Pass --config <path> to operate on a specific file.\n"
255
+ "blindseal init --wrap: no MCP configs found in default locations.\n Looked in:\n" + targets.map((p) => ` - ${p}`).join("\n") + "\n Pass --config <path> to operate on a specific file.\n"
246
256
  );
247
257
  return 1;
248
258
  }
@@ -282,29 +292,105 @@ Wrap ${totalWraps} server${totalWraps === 1 ? "" : "s"}? [y/N] `);
282
292
  process.stdout.write("\n" + bold("Next steps:") + "\n");
283
293
  process.stdout.write(` 1. Restart Claude Code / Claude Desktop to pick up the new config.
284
294
  `);
285
- process.stdout.write(` 2. ${dim("Telemetry is OFF by default. To share threat data with the Blindseal network,")}
286
- `);
287
- process.stdout.write(` ${dim("add BLINDSEAL_TELEMETRY=1 to your shell or to a wrapped server's env block.")}
295
+ process.stdout.write(` 2. ${dim("Watch decisions:")} ${cyan("blindseal dashboard")}
288
296
  `);
289
- process.stdout.write(` 3. ${dim("Verify with:")} ${cyan("blindseal check --all")}
290
- `);
291
- process.stdout.write(` 4. ${dim("To revert:")} ${cyan("blindseal init unwrap")}
297
+ process.stdout.write(` 3. ${dim("To revert:")} ${cyan("blindseal init --unwrap")}
292
298
  `);
293
299
  return 0;
294
300
  }
295
- if (import.meta.url === `file://${process.argv[1]}`) {
296
- runInit(process.argv.slice(2)).then((code) => process.exit(code));
301
+
302
+ // src/cli/init.ts
303
+ var HELP2 = `blindseal init \u2014 set up ~/.blindseal (identity key, default policy, dashboard token)
304
+
305
+ Usage:
306
+ blindseal init create ~/.blindseal and its defaults (safe to re-run)
307
+ blindseal init --wrap [flags] wrap the MCP servers in your Claude configs with blindseal
308
+ blindseal init --unwrap restore those configs from their .blindseal-backup files
309
+ blindseal init --help, -h this help
310
+
311
+ --wrap flags: --yes (skip confirmation), --dry-run (preview only), --config <path> (one file)
312
+
313
+ Next steps after init:
314
+ blindseal run --mock local API + dashboard over sample data
315
+ blindseal -- <server command> wrap a stdio MCP server
316
+ `;
317
+ function scaffoldHome(home = blindsealHome()) {
318
+ const created = [];
319
+ const kept = [];
320
+ if (!existsSync2(home)) {
321
+ mkdirSync(home, { recursive: true, mode: 448 });
322
+ created.push(home + path2.sep);
323
+ } else {
324
+ kept.push(home + path2.sep);
325
+ }
326
+ try {
327
+ if ((statSync(home).mode & 511) !== 448) chmodSync(home, 448);
328
+ } catch {
329
+ }
330
+ const keyPath = path2.join(home, "identity.key");
331
+ const hadKey = existsSync2(keyPath);
332
+ const { pubkeyHex } = loadIdentity(keyPath);
333
+ (hadKey ? kept : created).push(keyPath);
334
+ const policyPath = path2.join(home, "policy.json");
335
+ let policySource;
336
+ if (existsSync2(policyPath)) {
337
+ kept.push(policyPath);
338
+ } else {
339
+ const fixtures = shippedFixturesDir() ?? nearestFixturesDir();
340
+ const src = fixtures ? path2.join(fixtures, "policy.json") : void 0;
341
+ if (src && existsSync2(src)) {
342
+ copyFileSync2(src, policyPath);
343
+ chmodSync(policyPath, 384);
344
+ policySource = src;
345
+ created.push(policyPath);
346
+ }
347
+ }
348
+ const tokenPath = path2.join(home, "dashboard.token");
349
+ if (existsSync2(tokenPath)) {
350
+ kept.push(tokenPath);
351
+ } else {
352
+ writeFileSync2(tokenPath, randomBytes(24).toString("base64url") + "\n", { mode: 384 });
353
+ created.push(tokenPath);
354
+ }
355
+ return { home, created, kept, pubkeyHex, policySource };
356
+ }
357
+ async function runInit(argv) {
358
+ if (argv.some((a) => a === "--wrap" || a === "--unwrap" || a === "wrap" || a === "unwrap")) {
359
+ return runWrap(argv);
360
+ }
361
+ for (const a of argv) {
362
+ if (a === "--help" || a === "-h") {
363
+ process.stdout.write(HELP2);
364
+ return 0;
365
+ }
366
+ process.stderr.write(`blindseal init: unknown argument "${a}"
367
+ ${HELP2}`);
368
+ return 2;
369
+ }
370
+ let report;
371
+ try {
372
+ report = scaffoldHome();
373
+ } catch (e) {
374
+ process.stderr.write(`blindseal init: ${e.message}
375
+ `);
376
+ return 1;
377
+ }
378
+ const lines = [`blindseal init: ${report.home}`];
379
+ for (const f of report.created) lines.push(` created ${f}`);
380
+ for (const f of report.kept) lines.push(` kept ${f}`);
381
+ lines.push(` identity ${report.pubkeyHex.slice(0, 16)}\u2026 (ed25519, signs audit disclosures)`);
382
+ if (!report.created.includes(path2.join(report.home, "policy.json")) && !report.kept.includes(path2.join(report.home, "policy.json"))) {
383
+ lines.push(" warning default policy not written: fixtures/policy.json not found in this install");
384
+ }
385
+ lines.push("");
386
+ lines.push("Next:");
387
+ lines.push(" blindseal run --mock local API + dashboard over sample data");
388
+ lines.push(" blindseal -- <server command> wrap a stdio MCP server (e.g. blindseal -- npx -y @modelcontextprotocol/server-filesystem /tmp)");
389
+ lines.push(" blindseal init --wrap rewrite your Claude MCP configs to go through blindseal");
390
+ process.stdout.write(lines.join("\n") + "\n");
391
+ return 0;
297
392
  }
298
393
  export {
299
- applyPlan,
300
- applyUnwrap,
301
- defaultConfigPaths,
302
- isAlreadyWrapped,
303
- isBashShellCommand,
304
- parseArgs,
305
- planConfig,
306
- planEntry,
307
- renderPlan,
308
- resolveRelativeArgs,
309
- runInit
394
+ runInit,
395
+ scaffoldHome
310
396
  };
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ parseRunArgs,
4
+ resolveDashboardDir,
5
+ resolveFixturesDir,
6
+ runRun
7
+ } from "./chunk-6EU4GH4P.js";
8
+ import "./chunk-B44GZXDX.js";
9
+ import "./chunk-VSOUJM6X.js";
10
+ import "./chunk-CIUQ6WHJ.js";
11
+ import "./chunk-PDX44BCA.js";
12
+ export {
13
+ parseRunArgs,
14
+ resolveDashboardDir,
15
+ resolveFixturesDir,
16
+ runRun
17
+ };
@@ -5,7 +5,7 @@ import {
5
5
  isConsumed,
6
6
  submit,
7
7
  verifyOffchain
8
- } from "./chunk-BTIXDNTV.js";
8
+ } from "./chunk-DJL2E6RF.js";
9
9
  import "./chunk-PDX44BCA.js";
10
10
 
11
11
  // src/cli/submit.ts
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ decodePublicInputs,
4
+ verifyOffchain
5
+ } from "./chunk-DJL2E6RF.js";
6
+ import {
7
+ isCleanWindow,
8
+ verifyDisclosure
9
+ } from "./chunk-VSOUJM6X.js";
10
+ import "./chunk-PDX44BCA.js";
11
+
12
+ // src/cli/verify.ts
13
+ import { readFileSync } from "fs";
14
+ var HELP = `blindseal verify \u2014 verify an attestation.json or a disclosure.json offline
15
+
16
+ Usage:
17
+ blindseal verify <file>
18
+
19
+ An attestation is VALID only if the Groth16 proof checks out AND every labeled field
20
+ (payloadHash, policyRoot, detectorVersion, actionHash, nullifier, expirySlot) matches
21
+ what the proof's public-input blob actually commits to.
22
+ `;
23
+ var NO_EXPIRY_SLOT = 2e9;
24
+ var DECODED_LABELS = ["payloadHash", "policyRoot", "detectorVersion", "actionHash", "nullifier", "expirySlot"];
25
+ function formatDecoded(decoded) {
26
+ const expiry = decoded.expirySlot;
27
+ const expiryNote = String(expiry) === String(NO_EXPIRY_SLOT) ? " (no expiry)" : "";
28
+ return [
29
+ ` payloadHash ${decoded.payloadHash}`,
30
+ ` policyRoot ${decoded.policyRoot}`,
31
+ ` detectorVersion ${decoded.detectorVersion}`,
32
+ ` actionHash ${decoded.actionHash}`,
33
+ ` nullifier ${decoded.nullifier}`,
34
+ ` expirySlot ${expiry}${expiryNote}`
35
+ ].join("\n");
36
+ }
37
+ function decodedFrom(att, r) {
38
+ const fallback = (() => {
39
+ try {
40
+ return decodePublicInputs(att.publicInputs[0]);
41
+ } catch {
42
+ return void 0;
43
+ }
44
+ })();
45
+ const out = {};
46
+ for (const k of DECODED_LABELS) {
47
+ const v = r.decoded?.[k] ?? fallback?.[k];
48
+ out[k] = v === void 0 ? "(undecodable)" : String(v);
49
+ }
50
+ return out;
51
+ }
52
+ async function verifyAttestationFile(file, att) {
53
+ const r = await verifyOffchain(att);
54
+ const decoded = decodedFrom(att, r);
55
+ const mismatches = r.mismatches ?? [];
56
+ const lines = [`attestation ${file}: ${r.ok ? "VALID" : `INVALID \u2014 ${r.reason ?? "unknown reason"}`}`];
57
+ lines.push(formatDecoded(decoded));
58
+ if (mismatches.length > 0) {
59
+ lines.push(` label mismatch (${mismatches.length}): ${mismatches.join(", ")}`);
60
+ for (const m of mismatches) {
61
+ const labeled = att[m];
62
+ const dec = decoded[m];
63
+ if (labeled !== void 0) lines.push(` ${m}: labeled ${String(labeled)} \u2260 decoded ${dec ?? "?"}`);
64
+ }
65
+ }
66
+ return { ok: r.ok, reason: r.reason ?? null, decoded, mismatches, text: lines.join("\n") + "\n" };
67
+ }
68
+ async function runVerifyCli(argv) {
69
+ const file = argv[0];
70
+ if (!file || file === "--help" || file === "-h") {
71
+ process.stdout.write(HELP);
72
+ return file ? 0 : 2;
73
+ }
74
+ const doc = JSON.parse(readFileSync(file, "utf8"));
75
+ if (Array.isArray(doc.entries) && typeof doc.signature === "string") {
76
+ const d = doc;
77
+ const v = verifyDisclosure(d);
78
+ process.stdout.write(`disclosure ${file}: ${v.ok ? "VALID" : `INVALID \u2014 ${v.reason}`}
79
+ `);
80
+ if (v.ok) process.stdout.write(` window #${d.from}\u2013#${d.to}, ${d.entries.length} entries, signer ${d.signerPubkey.slice(0, 16)}\u2026, clean window: ${isCleanWindow(d) ? "yes" : "no"}
81
+ `);
82
+ return v.ok ? 0 : 1;
83
+ }
84
+ if (doc.proof && Array.isArray(doc.publicInputs)) {
85
+ const report = await verifyAttestationFile(file, doc);
86
+ process.stdout.write(report.text);
87
+ return report.ok ? 0 : 1;
88
+ }
89
+ process.stderr.write("blindseal verify: not an attestation.json or a disclosure.json\n");
90
+ return 2;
91
+ }
92
+ export {
93
+ DECODED_LABELS,
94
+ NO_EXPIRY_SLOT,
95
+ formatDecoded,
96
+ runVerifyCli,
97
+ verifyAttestationFile
98
+ };
@@ -0,0 +1,25 @@
1
+ {
2
+ "version": 1,
3
+ "id": "att_8e1c2a16",
4
+ "decisionId": "1ZYXWVTSRQPNMKJHGFEDCBA987",
5
+ "actionHash": "0x3c2ef0a0176baa898fd7ef83432e6b477f3ee4e7c3d116f2298f4916f8e57cd0",
6
+ "policyRoot": "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
7
+ "detectorVersion": "0x006a0d1e62646623f1d2b9af7f3792c4d15aa7d6107bdb089a0760fd5b29331e",
8
+ "expirySlot": 280000000,
9
+ "nullifier": "0x352e1ed89bd7948609a20e78ff99b65ae5ba64af3a363e4a824be542399857f0",
10
+ "payloadHash": "0xef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c",
11
+ "nonce": "0x8e1c2a16c62c803b8b94925554ebc12a3110e7744ebb06fc81b1943e998d3e6f",
12
+ "publicInputs": [
13
+ "0xef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397006a0d1e62646623f1d2b9af7f3792c4d15aa7d6107bdb089a0760fd5b29331e3c2ef0a0176baa898fd7ef83432e6b477f3ee4e7c3d116f2298f4916f8e57cd0352e1ed89bd7948609a20e78ff99b65ae5ba64af3a363e4a824be542399857f00076b01000000000"
14
+ ],
15
+ "proof": {
16
+ "bytes": "0xa4594c592c867d78e1af3cbd92d0a334237b8c400223beaf91c62313f1f6739b2a5590942525687e71f098fd546893d6e6a127c77605d507093bb6b0c05af13e9b0b0f8c0f61fcfd6f71bb26ed83eb0724aa966d684721ca1f0f961fd1f400eb8f9faf0b0ccbeaeae7ab555631c951dc3c8bbe0241bead87253fdb3d8816e678a73b424f254f17adb551740328c19af248cdad0bf8b8337626fd008fa40dddd8e53cf9f703f094ec325b97d3d0f448dfe6ea72536f21cd41d38a454e8bd1a8bc5caeee480eeb2d344fe06a2f450ffc22bab748df219d84f7963756fa5c9d36843dfc8d1d1a4aaaef7dc42f18c61ba1752317f4dc7a31a2192696a00d5cba2744b4352dcf",
17
+ "curve": "bn254",
18
+ "protocol": "groth16"
19
+ },
20
+ "tee": {
21
+ "mode": "local"
22
+ },
23
+ "status": "generated",
24
+ "createdAt": "2026-10-20T10:01:40.031Z"
25
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "version": 1,
3
+ "id": "att_8e1c2a16",
4
+ "decisionId": "1ZYXWVTSRQPNMKJHGFEDCBA987",
5
+ "actionHash": "0x419f8b8a5a8fd350cdb4e4b109dc347faa61cef1da5f3e85c8432fcb9614a337",
6
+ "policyRoot": "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
7
+ "detectorVersion": "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
8
+ "expirySlot": 280200000,
9
+ "nullifier": "0x949bcc04116aa64475b87e5a188ce6f4a109325a823dc12a6f83c431bcc00f21",
10
+ "nonce": "0x8e1c2a16c62c803b8b94925554ebc12a3110e7744ebb06fc81b1943e998d3e6f",
11
+ "publicInputs": [
12
+ "0x880dcefa96c5ac45dcb65880cf9f83b244d5e5e034c39675b6741ef16e5d3fe7",
13
+ "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
14
+ "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
15
+ "0xf138bb1972b30b2e19e8131164e9a357037ba18a9f3c8c24d86faa43a6f202a2",
16
+ "0x949bcc04116aa64475b87e5a188ce6f4a109325a823dc12a6f83c431bcc00f21",
17
+ "0x10b38340"
18
+ ],
19
+ "proof": {
20
+ "protocol": "groth16",
21
+ "curve": "bn254",
22
+ "bytes": "0x463872f8e4d833024e1806704f179ce986ea54c8c87089f52f3865c624c62978"
23
+ },
24
+ "tee": {
25
+ "mode": "local"
26
+ },
27
+ "status": "rejected",
28
+ "createdAt": "2026-10-20T10:01:40.031Z"
29
+ }
@@ -0,0 +1,174 @@
1
+ [
2
+ {
3
+ "version": 1,
4
+ "id": "att_af877263",
5
+ "decisionId": "1ZYXWVTSRQPNMKJHGFEDCBA987",
6
+ "actionHash": "0x13a111cb3474c0c4bc220f97b4552ff30f384f0d9cdf70e38c999fad075b56b6",
7
+ "policyRoot": "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
8
+ "detectorVersion": "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
9
+ "expirySlot": 280050000,
10
+ "nullifier": "0x6e505acf72de90804156c5c147e947acdfb71f13a0b9a2ee0a0693bf76810ea1",
11
+ "nonce": "0xaf877263a4c846ed9fcba50f2462466c14b71532aea54b96d09e555fae82fdca",
12
+ "publicInputs": [
13
+ "0x880dcefa96c5ac45dcb65880cf9f83b244d5e5e034c39675b6741ef16e5d3fe736a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d13a111cb3474c0c4bc220f97b4552ff30f384f0d9cdf70e38c999fad075b56b66e505acf72de90804156c5c147e947acdfb71f13a0b9a2ee0a0693bf76810ea15039b11000000000"
14
+ ],
15
+ "proof": {
16
+ "protocol": "groth16",
17
+ "curve": "bn254",
18
+ "bytes": "0x79f9451e18ff8af4594fd7417de6e1ac6c5fd856633cb10488c39d519920af95"
19
+ },
20
+ "tee": {
21
+ "mode": "local"
22
+ },
23
+ "status": "generating",
24
+ "progressPct": 40,
25
+ "createdAt": "2026-10-20T09:00:00.655Z"
26
+ },
27
+ {
28
+ "version": 1,
29
+ "id": "att_7db462be",
30
+ "decisionId": "GZYXWVTHRQPNMKJHGFEDCBA987",
31
+ "actionHash": "0x1ef1bf9891a621e00349bf8af77dfdb040436b1e99869c8908b0c5b9f6c7b17d",
32
+ "policyRoot": "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
33
+ "detectorVersion": "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
34
+ "expirySlot": 280051500,
35
+ "nullifier": "0xd194e860787b413bef3a27dd5350e1bde772d09b87cd4b0e3e84ce3411ac586a",
36
+ "nonce": "0x7db462be4a009edbb4fd81dd2d2719aebaa640edc4d1947efe945e3756c646de",
37
+ "publicInputs": [
38
+ "0x0adb6cb09a695e7ee3d2fbdcb3bf3d3519f14d26a82d0897fa2ee697e861a332",
39
+ "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
40
+ "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
41
+ "0x1ef1bf9891a621e00349bf8af77dfdb040436b1e99869c8908b0c5b9f6c7b17d",
42
+ "0xd194e860787b413bef3a27dd5350e1bde772d09b87cd4b0e3e84ce3411ac586a",
43
+ "0x10b13f2c"
44
+ ],
45
+ "proof": {
46
+ "protocol": "groth16",
47
+ "curve": "bn254",
48
+ "bytes": "0x4728743bfe2793c90cc5f0010a1265315c2d182af80d1262642f72e99a30d712"
49
+ },
50
+ "tee": {
51
+ "mode": "local"
52
+ },
53
+ "status": "generated",
54
+ "createdAt": "2026-10-20T09:00:41.945Z"
55
+ },
56
+ {
57
+ "version": 1,
58
+ "id": "att_730d318d",
59
+ "decisionId": "ZZYXWVTSRQPNMKJHGFEDCBA987",
60
+ "actionHash": "0xf52cb59155a8fff04f6839ee0326f8a8b009a159f7e8dc4cf3d536e59633be65",
61
+ "policyRoot": "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
62
+ "detectorVersion": "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
63
+ "expirySlot": 280053000,
64
+ "nullifier": "0x246fbea68e54fd20b0a51f622f6b9a7c620bb972db996da625f3e303fcfb212e",
65
+ "nonce": "0x730d318d494da9c8aec119f9215af82b01c05774f6e29775d138ad31e0d03e00",
66
+ "publicInputs": [
67
+ "0x7d6d6319d4591cf0310ba8f595dbbc22eda474b15a88f8e7ce2fc267566dfd1f",
68
+ "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
69
+ "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
70
+ "0xf52cb59155a8fff04f6839ee0326f8a8b009a159f7e8dc4cf3d536e59633be65",
71
+ "0x246fbea68e54fd20b0a51f622f6b9a7c620bb972db996da625f3e303fcfb212e",
72
+ "0x10b14508"
73
+ ],
74
+ "proof": {
75
+ "protocol": "groth16",
76
+ "curve": "bn254",
77
+ "bytes": "0x9587a488593dcf305174d6e2d3530e244916b1da9aaed6bb6de130d25d4f342f"
78
+ },
79
+ "tee": {
80
+ "mode": "local"
81
+ },
82
+ "status": "submitted",
83
+ "txSig": "4fbb48d0bc17b35e83d1689f3afb714085b61dfc6425ef1f19a5d9bed3317346",
84
+ "createdAt": "2026-10-20T09:01:15.908Z"
85
+ },
86
+ {
87
+ "version": 1,
88
+ "id": "att_daa57fbb",
89
+ "decisionId": "EZYXWVTSRQPNMKJHGFEDCBA987",
90
+ "actionHash": "0x1904a533e00fb24c0fa8107ee3738f01b3c79adfa2dbe2872d74b5ccd970b9e1",
91
+ "policyRoot": "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
92
+ "detectorVersion": "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
93
+ "expirySlot": 280054500,
94
+ "nullifier": "0x1481561e3ba282e46b576ebcc6317e9388995196e06ba6baeafafa6e40a50291",
95
+ "nonce": "0xdaa57fbb47c67bed35cfa2bbbb2c7cbe6723ec575fff59c8176bfd940058b640",
96
+ "publicInputs": [
97
+ "0xf92dbaf9090540cd09bfdeb43adea3f5639291925e6298b3ae29b39018b02e3c",
98
+ "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
99
+ "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
100
+ "0x1904a533e00fb24c0fa8107ee3738f01b3c79adfa2dbe2872d74b5ccd970b9e1",
101
+ "0x1481561e3ba282e46b576ebcc6317e9388995196e06ba6baeafafa6e40a50291",
102
+ "0x10b14ae4"
103
+ ],
104
+ "proof": {
105
+ "protocol": "groth16",
106
+ "curve": "bn254",
107
+ "bytes": "0x2145e9705712d87a3437fc6d3f2173962ac959ff8621dc7153b765f67bd53967"
108
+ },
109
+ "tee": {
110
+ "mode": "local"
111
+ },
112
+ "status": "consumed",
113
+ "txSig": "123269d63c5906ec89a20880b5b0a675e0bdfbe07f085767737bef290709143d",
114
+ "createdAt": "2026-10-20T09:01:52.203Z"
115
+ },
116
+ {
117
+ "version": 1,
118
+ "id": "att_5f5de7e9",
119
+ "decisionId": "XZYXWVTSRQPNMKJHGFEDCBA987",
120
+ "actionHash": "0x9baee8190b24e34008840a73c7c7a7538c46e01911992a931fe790f32fd29b33",
121
+ "policyRoot": "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
122
+ "detectorVersion": "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
123
+ "expirySlot": 279906000,
124
+ "nullifier": "0x87ef4f759db33f34017f5e10e1d178b158f837cab6fcd4692456fa27c2c54b18",
125
+ "nonce": "0x5f5de7e97280293b7c730790992649ccfaf661e50496d98af0c425aa5f35d84b",
126
+ "publicInputs": [
127
+ "0x0b0461c0ff4fa87a7d123062cfb71b1af989fcfc1ae2c27baa9eba1ffa35e42f",
128
+ "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
129
+ "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
130
+ "0x9baee8190b24e34008840a73c7c7a7538c46e01911992a931fe790f32fd29b33",
131
+ "0x87ef4f759db33f34017f5e10e1d178b158f837cab6fcd4692456fa27c2c54b18",
132
+ "0x10af06d0"
133
+ ],
134
+ "proof": {
135
+ "protocol": "groth16",
136
+ "curve": "bn254",
137
+ "bytes": "0xe0dcdeb8813d92d195f4f4350a2426be624da89e3f57cbaecc9d319dfbf000fe"
138
+ },
139
+ "tee": {
140
+ "mode": "local"
141
+ },
142
+ "status": "expired",
143
+ "createdAt": "2026-10-20T09:02:32.981Z"
144
+ },
145
+ {
146
+ "version": 1,
147
+ "id": "att_74c62e10",
148
+ "decisionId": "CZYXWVTSGQPNMKJHGFEDCBA987",
149
+ "actionHash": "0x1813c571fd039e0cfb5654e4c32190d59dc8d0ff0f67eb8edb74b0ffece71449",
150
+ "policyRoot": "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
151
+ "detectorVersion": "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
152
+ "expirySlot": 280057500,
153
+ "nullifier": "0xd2c1d1b41e30141a20a1a36ce7fcbb92e015903523e588916ca9c9efc197a956",
154
+ "nonce": "0x74c62e10a495557564238ea9d65bfd8d80edb56923187bfb7e871ef191491c7d",
155
+ "publicInputs": [
156
+ "0xdf663e9050b03500ec1028dd7c756de84d761be61f1cf404befa534b8fd4336f",
157
+ "0x36a9e9457db6ecfd752a379fc9279ad6a0acfea07928f61e2f3638a685c38397",
158
+ "0x726faa56c0857bbace50727feedf504a76f37a98c975f565e44bf341fb29851d",
159
+ "0x1813c571fd039e0cfb5654e4c32190d59dc8d0ff0f67eb8edb74b0ffece71449",
160
+ "0xd2c1d1b41e30141a20a1a36ce7fcbb92e015903523e588916ca9c9efc197a956",
161
+ "0x10b1569c"
162
+ ],
163
+ "proof": {
164
+ "protocol": "groth16",
165
+ "curve": "bn254",
166
+ "bytes": "0xd29428b98c622aed5e8356bd3221a19ea1fbcd57b52a724fbe6635762869b8ab"
167
+ },
168
+ "tee": {
169
+ "mode": "local"
170
+ },
171
+ "status": "rejected",
172
+ "createdAt": "2026-10-20T09:03:05.127Z"
173
+ }
174
+ ]