@antseed/antseed-verifier 0.1.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.
Files changed (83) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +86 -0
  3. package/dist/adapters/aci.d.ts +4 -0
  4. package/dist/adapters/aci.d.ts.map +1 -0
  5. package/dist/adapters/aci.js +42 -0
  6. package/dist/adapters/aci.js.map +1 -0
  7. package/dist/adapters/chutes.d.ts +4 -0
  8. package/dist/adapters/chutes.d.ts.map +1 -0
  9. package/dist/adapters/chutes.js +72 -0
  10. package/dist/adapters/chutes.js.map +1 -0
  11. package/dist/adapters/index.d.ts +26 -0
  12. package/dist/adapters/index.d.ts.map +1 -0
  13. package/dist/adapters/index.js +19 -0
  14. package/dist/adapters/index.js.map +1 -0
  15. package/dist/antseed-node-types.d.ts +55 -0
  16. package/dist/antseed-node-types.d.ts.map +1 -0
  17. package/dist/antseed-node-types.js +8 -0
  18. package/dist/antseed-node-types.js.map +1 -0
  19. package/dist/capability.d.ts +50 -0
  20. package/dist/capability.d.ts.map +1 -0
  21. package/dist/capability.js +15 -0
  22. package/dist/capability.js.map +1 -0
  23. package/dist/caps/gpu-nvidia.d.ts +66 -0
  24. package/dist/caps/gpu-nvidia.d.ts.map +1 -0
  25. package/dist/caps/gpu-nvidia.js +142 -0
  26. package/dist/caps/gpu-nvidia.js.map +1 -0
  27. package/dist/caps/index.d.ts +7 -0
  28. package/dist/caps/index.d.ts.map +1 -0
  29. package/dist/caps/index.js +21 -0
  30. package/dist/caps/index.js.map +1 -0
  31. package/dist/caps/measured-image.d.ts +14 -0
  32. package/dist/caps/measured-image.d.ts.map +1 -0
  33. package/dist/caps/measured-image.js +46 -0
  34. package/dist/caps/measured-image.js.map +1 -0
  35. package/dist/caps/provider-claims.d.ts +52 -0
  36. package/dist/caps/provider-claims.d.ts.map +1 -0
  37. package/dist/caps/provider-claims.js +195 -0
  38. package/dist/caps/provider-claims.js.map +1 -0
  39. package/dist/caps/seller-bound.d.ts +9 -0
  40. package/dist/caps/seller-bound.d.ts.map +1 -0
  41. package/dist/caps/seller-bound.js +104 -0
  42. package/dist/caps/seller-bound.js.map +1 -0
  43. package/dist/caps/tee-tdx.d.ts +107 -0
  44. package/dist/caps/tee-tdx.d.ts.map +1 -0
  45. package/dist/caps/tee-tdx.js +210 -0
  46. package/dist/caps/tee-tdx.js.map +1 -0
  47. package/dist/collect/configfs.d.ts +6 -0
  48. package/dist/collect/configfs.d.ts.map +1 -0
  49. package/dist/collect/configfs.js +38 -0
  50. package/dist/collect/configfs.js.map +1 -0
  51. package/dist/collect/dstack.d.ts +8 -0
  52. package/dist/collect/dstack.d.ts.map +1 -0
  53. package/dist/collect/dstack.js +79 -0
  54. package/dist/collect/dstack.js.map +1 -0
  55. package/dist/collect/http.d.ts +25 -0
  56. package/dist/collect/http.d.ts.map +1 -0
  57. package/dist/collect/http.js +83 -0
  58. package/dist/collect/http.js.map +1 -0
  59. package/dist/index.d.ts +33 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +40 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/nras.d.ts +81 -0
  64. package/dist/nras.d.ts.map +1 -0
  65. package/dist/nras.js +190 -0
  66. package/dist/nras.js.map +1 -0
  67. package/dist/prover.d.ts +5 -0
  68. package/dist/prover.d.ts.map +1 -0
  69. package/dist/prover.js +204 -0
  70. package/dist/prover.js.map +1 -0
  71. package/dist/report-data.d.ts +47 -0
  72. package/dist/report-data.d.ts.map +1 -0
  73. package/dist/report-data.js +111 -0
  74. package/dist/report-data.js.map +1 -0
  75. package/dist/shared.d.ts +89 -0
  76. package/dist/shared.d.ts.map +1 -0
  77. package/dist/shared.js +158 -0
  78. package/dist/shared.js.map +1 -0
  79. package/dist/verifier.d.ts +21 -0
  80. package/dist/verifier.d.ts.map +1 -0
  81. package/dist/verifier.js +149 -0
  82. package/dist/verifier.js.map +1 -0
  83. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # @antseed/antseed-verifier
2
+
3
+ Verifier SDK for AntSeed's pluggable verifier system (AIP-3). One package has two halves. A
4
+ **buyer verifier** (default export) challenges a seller. It checks the seller's Intel TDX
5
+ attestation before it routes paid requests. An embedded **seller prover** (`prover` export,
6
+ loaded with `--verifiers antseed-verifier`) answers those challenges before provider
7
+ matching and payment.
8
+
9
+ ```ts
10
+ import verifier, { prover } from '@antseed/antseed-verifier'
11
+ // verifier → default export (type:'verifier', buyer half)
12
+ // prover → named export (type:'prover', seller half)
13
+ ```
14
+
15
+ It attests a menu of independent **capabilities**. Each capability is one claim, namespaced
16
+ `antseed-verifier:<capability>`. The seller offers only the capabilities that its infrastructure
17
+ supports. The buyer's verdict gates on two capabilities and reports the others for policy.
18
+ Provider differences are config only (generic `configfs` or `http` collectors). The SDK carries
19
+ no provider-specific hosts or schemas, and it is self-contained (no peer dependencies).
20
+
21
+ ## Capabilities
22
+
23
+ | Capability | Proves | Verdict |
24
+ |---|---|---|
25
+ | `seller-node-tee-genuine` | the seller **node** runs in a genuine Intel TDX enclave (DCAP: PCK chain to Intel's root, acceptable TCB, TD10, debug off). The quote binds to this nonce + peerId | **required** |
26
+ | `seller-bound` | the seller's identity key signs the whole evidence bundle for this fresh nonce (the signer recovers to peerId) | **required** |
27
+ | `seller-provider-tee-genuine` | the downstream inference **provider's** TEE is genuine TDX. It is also round-bound when the seller declares a `report_data` scheme | informational |
28
+ | `seller-provider-gpu-cc` | the provider's GPUs run NVIDIA Confidential Computing (NVIDIA NRAS verifies it, nonce-bound) | informational |
29
+ | `seller-provider-measured-image` | the provider quote's MRTD/RTMR match a buyer allow-list | informational |
30
+ | `seller-provider-claims` | named provider claims against a frozen SDK menu. Each claim is `asserted` (self-vouched) or `tdx-quote` (TEE-attested) | informational |
31
+
32
+ The two required capabilities together prove one thing: *a genuine Intel TDX seller node,
33
+ minted fresh this round and cryptographically tied to the seller's marketplace identity.*
34
+
35
+ ## Params
36
+
37
+ The **prover** (seller) reads its config from the environment, never from buyer-supplied values:
38
+
39
+ | Variable | Purpose |
40
+ |---|---|
41
+ | `ANTSEED_TEE_PEER_ID` | the seller's peer id (EVM address, no `0x`) |
42
+ | `ANTSEED_VERIFIER_SIGNING_KEY` | seller identity key (hex) for `seller-bound`. Disabled if its address ≠ peerId |
43
+ | `ANTSEED_VERIFIER_NODE_TEE` | node quote source: `configfs` (default, bare-metal/GCP TDX), `dstack` (Phala and other dstack CVMs), or `http` |
44
+ | `ANTSEED_VERIFIER_DSTACK_SOCKET` | override the dstack guest-agent socket path (default `/var/run/dstack.sock`) |
45
+ | `ANTSEED_VERIFIER_PROVIDER_ADAPTER` | in-process provider adapter id (`chutes`, `aci`). It fetches provider evidence directly, no shim. See [CHUTES.md](./CHUTES.md) or [REDPILL.md](./REDPILL.md) |
46
+ | `ANTSEED_VERIFIER_PROVIDER_EVIDENCE_URL` | generic provider evidence route (`{nonce}` → hex nonce). The manual alternative to an adapter |
47
+ | `ANTSEED_VERIFIER_PROVIDER_TEE_FIELD` | JSON field with the base64 provider quote (default `quote`) |
48
+ | `ANTSEED_VERIFIER_PROVIDER_GPU_FIELD` | JSON field with per-GPU NVIDIA CC evidence → enables `seller-provider-gpu-cc` |
49
+ | `ANTSEED_VERIFIER_PROVIDER_CLAIMS_FIELD` | JSON field with the base64 claims doc → enables `seller-provider-claims` |
50
+ | `ANTSEED_VERIFIER_PROVIDER_BINDING_SCHEME` | frozen `report_data` scheme the provider quote uses (`antseed-rd-v1` \| `nonce-pubkey-sha256-v1`) |
51
+ | `ANTSEED_VERIFIER_PROVIDER_BINDING_PUBKEY_FIELD` | JSON field with the provider's base64 E2E pubkey (the scheme's ingredient) |
52
+
53
+ The **buyer** needs no special hardware. Optional policy knobs:
54
+
55
+ | Variable | Purpose |
56
+ |---|---|
57
+ | `ANTSEED_VERIFIER_REQUIRED_CAPS` | comma-separated capabilities that gate the overall `ok` (default `seller-node-tee-genuine,seller-bound`). For example, a provenance buyer sets `seller-provider-tee-genuine,seller-bound` to require the downstream provider's TEE |
58
+ | `ANTSEED_VERIFIER_MEASURED_IMAGE_POLICY` | approved-measurement allow-list (inline JSON or `@/path.json`) for `measured-image` |
59
+ | `ANTSEED_VERIFIER_STRICT_TCB` | `true` requires TCB exactly `UpToDate` (default also accepts `SWHardeningNeeded`) |
60
+ | `ANTSEED_VERIFIER_NRAS_URL` / `_NRAS_JWKS_URL` | override NVIDIA NRAS endpoints for `gpu-cc` |
61
+
62
+ `seller-node-tee-genuine` runs only on a real Intel TDX VM. `configfs` mints via
63
+ `/sys/kernel/config/tsm/report` (needs root). `dstack` mints via the guest-agent socket
64
+ (Phala and other dstack CVMs, where configfs-tsm is absent). Both bind the same `antseed-rd-v1`
65
+ report_data, so the buyer verifies them identically.
66
+
67
+ ## Appendix: provider adapters
68
+
69
+ An **in-process adapter** bridges a provider whose evidence API does not match the generic route
70
+ (auth, a different response shape). Select the adapter with `ANTSEED_VERIFIER_PROVIDER_ADAPTER`.
71
+ There is no separate process. The SDK core stays provider-neutral. Each adapter is an isolated
72
+ module that loads lazily. Two adapters are available:
73
+
74
+ ```bash
75
+ export ANTSEED_VERIFIER_PROVIDER_ADAPTER=chutes # + CHUTES_API_KEY, CHUTES_CHUTE
76
+ export ANTSEED_VERIFIER_PROVIDER_ADAPTER=aci # + ACI_ATTESTATION_URL (RedPill / dstack ACI)
77
+ ```
78
+
79
+ The adapter fetches the provider's fresh, nonce-bound quote. It declares its frozen `report_data`
80
+ scheme (`nonce-pubkey-sha256-v1` for Chutes, `aci-keyset-v1` for ACI). The buyer verifies the
81
+ scheme unchanged. Full setup: [CHUTES.md](./CHUTES.md) · [REDPILL.md](./REDPILL.md) · [PHALA.md](./PHALA.md)
82
+ (run the seller node in a dstack TDX CVM).
83
+
84
+ ---
85
+
86
+ `v0.1.0` · GPL-3.0
@@ -0,0 +1,4 @@
1
+ import type { ProviderAdapter } from './index.js';
2
+ declare const adapter: ProviderAdapter;
3
+ export default adapter;
4
+ //# sourceMappingURL=aci.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aci.d.ts","sourceRoot":"","sources":["../../src/adapters/aci.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,YAAY,CAAA;AAkDnE,QAAA,MAAM,OAAO,EAAE,eAA8C,CAAA;AAC7D,eAAe,OAAO,CAAA"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * RedPill / ACI provider adapter (in-process). It gets a fresh, nonce-bound attestation from a
3
+ * Private-AI-Gateway (ACI spec) endpoint, reads the TDX quote, and binds via aci-keyset-v1.
4
+ * ANTSEED_VERIFIER_PROVIDER_ADAPTER=aci selects it.
5
+ *
6
+ * Env: ACI_ATTESTATION_URL (required, e.g. https://<gateway>/v1/aci/attestation), ACI_API_KEY (optional Bearer).
7
+ */
8
+ const TIMEOUT_MS = 20_000;
9
+ /** Validate ACI's workload_keyset_digest ("sha256:<64 hex>") and return it verbatim. */
10
+ function keysetDigest(raw) {
11
+ if (typeof raw !== 'string' || !/^sha256:[0-9a-f]{64}$/.test(raw)) {
12
+ throw new Error('aci report workload_keyset_digest is not "sha256:<64 hex>"');
13
+ }
14
+ return raw;
15
+ }
16
+ async function fetchEvidence(nonce, env) {
17
+ const url = env['ACI_ATTESTATION_URL'];
18
+ if (!url)
19
+ throw new Error('ACI_ATTESTATION_URL is required (e.g. https://<gateway>/v1/aci/attestation)');
20
+ const nonceHex = Buffer.from(nonce).toString('hex');
21
+ const full = `${url}${url.includes('?') ? '&' : '?'}nonce=${nonceHex}`;
22
+ const headers = {};
23
+ const key = env['ACI_API_KEY'];
24
+ if (key)
25
+ headers['authorization'] = `Bearer ${key}`;
26
+ const resp = await fetch(full, { headers, signal: AbortSignal.timeout(TIMEOUT_MS) });
27
+ if (!resp.ok)
28
+ throw new Error(`aci attestation HTTP ${resp.status}`);
29
+ const report = (await resp.json());
30
+ const quoteHex = report?.attestation?.evidence?.quote;
31
+ if (typeof quoteHex !== 'string' || quoteHex.length === 0) {
32
+ throw new Error('aci report has no attestation.evidence.quote');
33
+ }
34
+ return {
35
+ quote: new Uint8Array(Buffer.from(quoteHex.replace(/^0x/, ''), 'hex')),
36
+ bindingScheme: 'aci-keyset-v1',
37
+ ingredients: { keysetDigest: keysetDigest(report.workload_keyset_digest) },
38
+ };
39
+ }
40
+ const adapter = { id: 'aci', fetchEvidence };
41
+ export default adapter;
42
+ //# sourceMappingURL=aci.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aci.js","sourceRoot":"","sources":["../../src/adapters/aci.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,MAAM,UAAU,GAAG,MAAM,CAAA;AAOzB,wFAAwF;AACxF,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,KAAiB,EAAE,GAAuC;IACrF,MAAM,GAAG,GAAG,GAAG,CAAC,qBAAqB,CAAC,CAAA;IACtC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAA;IAExG,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,QAAQ,EAAE,CAAA;IACtE,MAAM,OAAO,GAA2B,EAAE,CAAA;IAC1C,MAAM,GAAG,GAAG,GAAG,CAAC,aAAa,CAAC,CAAA;IAC9B,IAAI,GAAG;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,GAAG,EAAE,CAAA;IAEnD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IACpF,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IAEpE,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAc,CAAA;IAC/C,MAAM,QAAQ,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAA;IACrD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IACD,OAAO;QACL,KAAK,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACtE,aAAa,EAAE,eAAe;QAC9B,WAAW,EAAE,EAAE,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC,sBAAsB,CAAC,EAAE;KAC3E,CAAA;AACH,CAAC;AAED,MAAM,OAAO,GAAoB,EAAE,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA;AAC7D,eAAe,OAAO,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { ProviderAdapter } from './index.js';
2
+ declare const adapter: ProviderAdapter;
3
+ export default adapter;
4
+ //# sourceMappingURL=chutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chutes.d.ts","sourceRoot":"","sources":["../../src/adapters/chutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,YAAY,CAAA;AAiFnE,QAAA,MAAM,OAAO,EAAE,eAAiD,CAAA;AAChE,eAAe,OAAO,CAAA"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Chutes provider adapter (in-process). Chutes splits the evidence across two Bearer-authed
3
+ * endpoints. `/e2e/instances/{chute}` returns the per-instance E2E pubkey (the report_data
4
+ * ingredient). `/chutes/{chute}/evidence?nonce={hex}` returns the per-instance TDX quote and
5
+ * GPU evidence, bound to the nonce. The adapter joins them by instance_id, decodes the base64
6
+ * quote, and reshapes the flat GPU evidence into the NRAS shape.
7
+ * ANTSEED_VERIFIER_PROVIDER_ADAPTER=chutes selects it.
8
+ *
9
+ * Env: CHUTES_API_KEY (required), CHUTES_CHUTE (required), CHUTES_API_BASE (default https://api.chutes.ai).
10
+ */
11
+ const DEFAULT_BASE = 'https://api.chutes.ai';
12
+ const TIMEOUT_MS = 20_000;
13
+ /** Reshape Chutes' flat GPU evidence [{arch, evidence, certificate}] → NRAS { arch, evidence_list }. */
14
+ function reshapeGpu(gpu) {
15
+ if (!gpu)
16
+ return undefined;
17
+ if (Array.isArray(gpu)) {
18
+ if (gpu.length === 0)
19
+ return undefined;
20
+ const first = gpu[0];
21
+ return {
22
+ arch: String(first.arch),
23
+ evidence_list: gpu.map((g) => {
24
+ const item = g;
25
+ return { evidence: String(item.evidence), certificate: String(item.certificate) };
26
+ }),
27
+ };
28
+ }
29
+ return gpu;
30
+ }
31
+ async function fetchEvidence(nonce, env) {
32
+ const base = (env['CHUTES_API_BASE'] ?? DEFAULT_BASE).replace(/\/+$/, '');
33
+ const key = env['CHUTES_API_KEY'];
34
+ const chute = env['CHUTES_CHUTE'];
35
+ if (!key)
36
+ throw new Error('CHUTES_API_KEY is required');
37
+ if (!chute)
38
+ throw new Error('CHUTES_CHUTE is required');
39
+ const headers = { authorization: `Bearer ${key}` };
40
+ const chuteEnc = encodeURIComponent(chute);
41
+ const get = async (path) => {
42
+ const resp = await fetch(`${base}${path}`, { headers, signal: AbortSignal.timeout(TIMEOUT_MS) });
43
+ if (!resp.ok)
44
+ throw new Error(`chutes ${path.split('?')[0]} HTTP ${resp.status}`);
45
+ return resp.json();
46
+ };
47
+ // E2E pubkey per instance (the report_data binding ingredient).
48
+ const instBody = (await get(`/e2e/instances/${chuteEnc}`));
49
+ const pubkeys = new Map();
50
+ for (const i of instBody.instances ?? []) {
51
+ if (i.instance_id && typeof i.e2e_pubkey === 'string' && i.e2e_pubkey.length > 0)
52
+ pubkeys.set(i.instance_id, i.e2e_pubkey);
53
+ }
54
+ // TDX quote and GPU evidence per instance, bound to this nonce.
55
+ const nonceHex = Buffer.from(nonce).toString('hex');
56
+ const evBody = (await get(`/chutes/${chuteEnc}/evidence?nonce=${nonceHex}`));
57
+ const inst = (evBody.evidence ?? []).find((e) => typeof e.quote === 'string' && e.quote.length > 0 && !!e.instance_id && pubkeys.has(e.instance_id));
58
+ if (!inst?.quote || !inst.instance_id)
59
+ throw new Error('no chutes instance had both a quote and an e2e_pubkey');
60
+ const evidence = {
61
+ quote: new Uint8Array(Buffer.from(inst.quote, 'base64')),
62
+ bindingScheme: 'nonce-pubkey-sha256-v1',
63
+ ingredients: { e2ePubkey: pubkeys.get(inst.instance_id) },
64
+ };
65
+ const gpu = reshapeGpu(inst.gpu_evidence);
66
+ if (gpu)
67
+ evidence.gpuEvidence = gpu;
68
+ return evidence;
69
+ }
70
+ const adapter = { id: 'chutes', fetchEvidence };
71
+ export default adapter;
72
+ //# sourceMappingURL=chutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chutes.js","sourceRoot":"","sources":["../../src/adapters/chutes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { BindingIngredients } from '../report-data.js';
2
+ import type { NvidiaGpuEvidence } from '../nras.js';
3
+ /**
4
+ * Provider evidence in the SDK's neutral shape, produced by an in-process adapter. The prover
5
+ * maps this onto the provider capabilities (tee / gpu). A foreign provider's API is bridged
6
+ * with no provider specifics in the core: the adapter is the only provider-aware code, and the
7
+ * SDK loads it lazily — by id, only when ANTSEED_VERIFIER_PROVIDER_ADAPTER selects it.
8
+ */
9
+ export interface ProviderEvidence {
10
+ /** The provider's raw TDX quote bytes. */
11
+ quote: Uint8Array;
12
+ /** Frozen report_data scheme the quote binds (e.g. 'nonce-pubkey-sha256-v1', 'aci-keyset-v1'). */
13
+ bindingScheme?: string;
14
+ /** The scheme's ingredients (e.g. { e2ePubkey } for Chutes, { keysetDigest } for ACI). */
15
+ ingredients?: Pick<BindingIngredients, 'peerId' | 'e2ePubkey' | 'keysetDigest'>;
16
+ /** Provider GPU CC evidence for seller-provider-gpu-cc, when the provider offers it. */
17
+ gpuEvidence?: NvidiaGpuEvidence;
18
+ }
19
+ /** A provider adapter. It uses the buyer nonce and the process env to fetch the provider's evidence. */
20
+ export interface ProviderAdapter {
21
+ id: string;
22
+ fetchEvidence(nonce: Uint8Array, env: Record<string, string | undefined>): Promise<ProviderEvidence>;
23
+ }
24
+ export declare function adapterIds(): string[];
25
+ export declare function loadAdapter(id: string): Promise<ProviderAdapter>;
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,KAAK,EAAE,UAAU,CAAA;IACjB,kGAAkG;IAClG,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,0FAA0F;IAC1F,WAAW,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,GAAG,WAAW,GAAG,cAAc,CAAC,CAAA;IAC/E,wFAAwF;IACxF,WAAW,CAAC,EAAE,iBAAiB,CAAA;CAChC;AAED,wGAAwG;AACxG,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;CACrG;AAYD,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAErC;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAItE"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Allowlisted lazy registry — the one place adapter ids map to modules. The env only selects
3
+ * a key here (never a path), so a hostile value cannot dynamic-import an arbitrary file. To add a
4
+ * provider, add its module and one line here; the core verify/collect path never changes.
5
+ */
6
+ const REGISTRY = {
7
+ chutes: () => import('./chutes.js'),
8
+ aci: () => import('./aci.js'),
9
+ };
10
+ export function adapterIds() {
11
+ return Object.keys(REGISTRY);
12
+ }
13
+ export async function loadAdapter(id) {
14
+ const load = REGISTRY[id];
15
+ if (!load)
16
+ throw new Error(`unknown provider adapter "${id}" (known: ${adapterIds().join(', ') || 'none'})`);
17
+ return (await load()).default;
18
+ }
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AA0BA;;;;GAIG;AACH,MAAM,QAAQ,GAAgE;IAC5E,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC;IACnC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;CAC9B,CAAA;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACzB,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,EAAE,aAAa,UAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CAAC,CAAA;IAC5G,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAA;AAC/B,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The AntSeed plugin contract this SDK implements, vendored so the published package is
3
+ * self-contained (no external type dependency, no peer dependency to build). These interfaces
4
+ * mirror the AntSeed runtime's plugin surface, which loads this SDK's default and `prover` exports
5
+ * structurally. Keep them in sync if that contract changes.
6
+ */
7
+ export interface AntseedPluginBase {
8
+ name: string;
9
+ displayName: string;
10
+ version: string;
11
+ description: string;
12
+ }
13
+ /** One capability's verdict. `claim` is a namespaced id, e.g. 'antseed-verifier:seller-bound'. */
14
+ export interface ClaimResult {
15
+ claim: string;
16
+ ok: boolean;
17
+ detail?: string;
18
+ }
19
+ /** Overall verify result; the buyer applies its own required-vs-optional policy. */
20
+ export interface VerifyResult {
21
+ ok: boolean;
22
+ claims: ClaimResult[];
23
+ }
24
+ /** A request the verifier sends to the seller over the existing buyer↔seller comms. */
25
+ export interface SellerRequest {
26
+ method: string;
27
+ path: string;
28
+ headers?: Record<string, string>;
29
+ body?: Uint8Array;
30
+ }
31
+ export interface SellerResponse {
32
+ statusCode: number;
33
+ headers: Record<string, string>;
34
+ body: Uint8Array;
35
+ }
36
+ export interface VerifyContext {
37
+ peerId: string;
38
+ /** Verifier id selected by the buyer; must match this SDK's name. */
39
+ verifierId: string;
40
+ /** Seller prover path for this verifier. */
41
+ attestPath: string;
42
+ fetchFromSeller(req: SellerRequest): Promise<SellerResponse>;
43
+ signal?: AbortSignal;
44
+ }
45
+ /** Buyer half (the default export). */
46
+ export interface AntseedVerifierPlugin extends AntseedPluginBase {
47
+ type: 'verifier';
48
+ verify(ctx: VerifyContext): VerifyResult | Promise<VerifyResult>;
49
+ }
50
+ /** Seller half (the `prover` export) — serves reserved attestation requests. */
51
+ export interface Prover extends AntseedPluginBase {
52
+ type: 'prover';
53
+ prove(req: SellerRequest): SellerResponse | Promise<SellerResponse>;
54
+ }
55
+ //# sourceMappingURL=antseed-node-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antseed-node-types.d.ts","sourceRoot":"","sources":["../src/antseed-node-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,kGAAkG;AAClG,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,WAAW,EAAE,CAAA;CACtB;AAED,uFAAuF;AACvF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAA;IAClB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC5D,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,uCAAuC;AACvC,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;CACjE;AAED,gFAAgF;AAChF,MAAM,WAAW,MAAO,SAAQ,iBAAiB;IAC/C,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;CACpE"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The AntSeed plugin contract this SDK implements, vendored so the published package is
3
+ * self-contained (no external type dependency, no peer dependency to build). These interfaces
4
+ * mirror the AntSeed runtime's plugin surface, which loads this SDK's default and `prover` exports
5
+ * structurally. Keep them in sync if that contract changes.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=antseed-node-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antseed-node-types.js","sourceRoot":"","sources":["../src/antseed-node-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,50 @@
1
+ import type { ClaimResult } from './antseed-node-types.js';
2
+ /**
3
+ * A Capability is one independent seller attestation. The SDK offers a menu of them.
4
+ * A seller produces evidence for the caps its infra supports (collect), and a buyer
5
+ * verifies each one (verify) into a single ClaimResult. Caps are generic — no provider
6
+ * hostnames or schemas. Provider differences live only in config-driven collectors.
7
+ */
8
+ /** Input to a capability's buyer-side check. */
9
+ export interface CapabilityVerifyInput {
10
+ /** The buyer's fresh nonce for this attestation round. */
11
+ nonce: Uint8Array;
12
+ /** The seller's peer id (EVM address, normalized by the caller). */
13
+ peerId: string;
14
+ /** This capability's own evidence bytes, if the seller returned any. */
15
+ evidence?: Uint8Array;
16
+ /**
17
+ * The already-DCAP-verified TDX quote this cap consumes (a ParsedTdxQuote from
18
+ * caps/tee-tdx). A TDX cap reads its own; a derived cap (measured-image) reads the
19
+ * quote it targets. `unknown` keeps this core module free of any cap-specific type.
20
+ */
21
+ parsedQuote?: unknown;
22
+ /** Buyer policy for this capability (e.g. approved measurements). Data, never fetched. */
23
+ policy?: unknown;
24
+ /**
25
+ * The full per-cap evidence map returned this round. seller-bound digests it (minus its
26
+ * own entry) to verify one seller signature covers the entire bundle.
27
+ */
28
+ evidenceBundle?: Record<string, Uint8Array>;
29
+ }
30
+ /** Input to a capability's seller-side evidence collection. */
31
+ export interface CapabilityCollectInput {
32
+ nonce: Uint8Array;
33
+ peerId: string;
34
+ /** Generic, provider-neutral config (source, url, field path, prior evidence, ...). */
35
+ config: Record<string, string>;
36
+ /** Signs a 32-byte digest with the seller's identity key; absent when unavailable. */
37
+ sign?: (msg: Uint8Array) => Promise<Uint8Array>;
38
+ }
39
+ export interface Capability {
40
+ id: string;
41
+ /** Most caps yield one ClaimResult; a granular cap (provider-claims) yields one per sub-claim. */
42
+ verify(input: CapabilityVerifyInput): ClaimResult | ClaimResult[] | Promise<ClaimResult | ClaimResult[]>;
43
+ /** Present only for caps a seller can produce evidence for. A throw means "not offered". */
44
+ collect?(input: CapabilityCollectInput): Promise<Uint8Array>;
45
+ }
46
+ export declare function registerCapability(cap: Capability): void;
47
+ export declare function getCapability(id: string): Capability | undefined;
48
+ export declare function listCapabilities(): Capability[];
49
+ export declare function capabilityIds(): string[];
50
+ //# sourceMappingURL=capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAE1D;;;;;GAKG;AAEH,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,KAAK,EAAE,UAAU,CAAA;IACjB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,QAAQ,CAAC,EAAE,UAAU,CAAA;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CAC5C;AAED,+DAA+D;AAC/D,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,UAAU,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,sFAAsF;IACtF,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;CAChD;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,kGAAkG;IAClG,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,WAAW,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,CAAA;IACxG,4FAA4F;IAC5F,OAAO,CAAC,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAC7D;AAKD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAExD;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAEhE;AAED,wBAAgB,gBAAgB,IAAI,UAAU,EAAE,CAE/C;AAED,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC"}
@@ -0,0 +1,15 @@
1
+ /** Registry — insertion order defines the menu order and the buyer's verify order. */
2
+ const registry = new Map();
3
+ export function registerCapability(cap) {
4
+ registry.set(cap.id, cap);
5
+ }
6
+ export function getCapability(id) {
7
+ return registry.get(id);
8
+ }
9
+ export function listCapabilities() {
10
+ return [...registry.values()];
11
+ }
12
+ export function capabilityIds() {
13
+ return [...registry.keys()];
14
+ }
15
+ //# sourceMappingURL=capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAkDA,sFAAsF;AACtF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAA;AAE9C,MAAM,UAAU,kBAAkB,CAAC,GAAe;IAChD,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,66 @@
1
+ import type { JWTVerifyGetKey } from 'jose';
2
+ import type { Capability } from '../capability.js';
3
+ import { type NrasSubmitFn } from '../nras.js';
4
+ /**
5
+ * Capability 'seller-provider-gpu-cc': proves the inference provider's GPUs run NVIDIA
6
+ * Confidential Computing, via NVIDIA's Remote Attestation Service (NRAS). The buyer submits
7
+ * the provider's per-GPU CC evidence and the buyer's nonce to NRAS, then verifies the returned
8
+ * EAR (signed JWT): the signature is valid against NVIDIA's JWKS, the overall result is success,
9
+ * the CC mode is on, and the nonce binds this round.
10
+ *
11
+ * Informational, not required: a CPU-only seller (no GPUs) must still verify, so this cap is
12
+ * never in the buyer's required set. The seller offers it only when it configures a provider
13
+ * evidence route and a GPU evidence field; otherwise it omits the cap. The buyer-side check goes
14
+ * through an injectable GpuVerifyFn (see below) so an offline verifier can replace it.
15
+ */
16
+ export declare const GPU_CAP_ID = "seller-provider-gpu-cc";
17
+ /** Result of a GPU-CC check — the cap maps this into a ClaimResult. */
18
+ export interface GpuVerification {
19
+ ok: boolean;
20
+ detail: string;
21
+ /** Set on network or service errors (NRAS unreachable). These are retryable, not a real verdict. */
22
+ transient?: boolean;
23
+ }
24
+ /**
25
+ * The injectable seam: verify a provider's GPU-CC evidence against the buyer's nonce. The
26
+ * default is NRAS. A localGpuVerify implements the offline path behind the same type, so a
27
+ * swap needs no cap change. Tests inject a stub to exercise the cap's policy.
28
+ */
29
+ export type GpuVerifyFn = (evidence: Uint8Array, nonce: Uint8Array) => Promise<GpuVerification>;
30
+ /** Config for the NRAS verifier. All fields are optional, so production uses NVIDIA defaults and real JWKS. */
31
+ export interface NrasOptions {
32
+ nrasUrl?: string;
33
+ jwksUrl?: string;
34
+ /** Injectable NRAS submit (default POSTs to NRAS). */
35
+ submit?: NrasSubmitFn;
36
+ /** Injectable jose key resolver (default fetches NVIDIA's JWKS). */
37
+ getKey?: JWTVerifyGetKey;
38
+ }
39
+ /**
40
+ * Build a NRAS-backed GpuVerifyFn. It submits the provider evidence and nonce to NRAS and
41
+ * verifies the EAR. Network or service errors are marked transient (retryable). Anything else
42
+ * (malformed evidence, bad signature, failed claim, nonce mismatch) fails closed as a real
43
+ * verdict. jose is imported lazily (only here) so the seller half and CPU-only buyers never load it.
44
+ */
45
+ export declare function makeNrasGpuVerify(opts?: NrasOptions): GpuVerifyFn;
46
+ /** Default NRAS verifier (production). */
47
+ export declare const nrasGpuVerify: GpuVerifyFn;
48
+ /**
49
+ * Offline GPU verifier — reserved for the nvtrust-style local path (report + device cert chain
50
+ * + RIM, no external service). Not implemented: it returns a clear, non-transient error so an
51
+ * operator who sets ANTSEED_VERIFIER_GPU_MODE=local gets an explicit "not implemented", not silence.
52
+ */
53
+ export declare const localGpuVerify: GpuVerifyFn;
54
+ /** Dispatch on ANTSEED_VERIFIER_GPU_MODE: 'nras' or 'local'. An unknown mode fails closed. */
55
+ export declare const defaultGpuVerify: GpuVerifyFn;
56
+ /** Config-key convention for this cap's collector settings (mirrors tee-tdx's tdxConfigKey). */
57
+ export declare function gpuConfigKey(key: string): string;
58
+ /**
59
+ * Mint the GPU-CC capability. `gpuVerify` is the injected buyer-side check (default: NRAS);
60
+ * tests pass a stub. collect fetches the provider's GPU evidence from the same provider
61
+ * evidence route as the TDX quote (config-supplied url and field). It throws when either is
62
+ * absent, so the cap is omitted.
63
+ */
64
+ export declare function makeGpuNvidiaCap(gpuVerify?: GpuVerifyFn): Capability;
65
+ export declare const gpuNvidiaCapability: Capability;
66
+ //# sourceMappingURL=gpu-nvidia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpu-nvidia.d.ts","sourceRoot":"","sources":["../../src/caps/gpu-nvidia.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AAE3C,OAAO,KAAK,EAAE,UAAU,EAAiD,MAAM,kBAAkB,CAAA;AAKjG,OAAO,EAML,KAAK,YAAY,EAElB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,UAAU,2BAA2B,CAAA;AAQlD,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,oGAAoG;IACpG,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;AAO/F,+GAA+G;AAC/G,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,oEAAoE;IACpE,MAAM,CAAC,EAAE,eAAe,CAAA;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,WAAgB,GAAG,WAAW,CA6BrE;AAED,0CAA0C;AAC1C,eAAO,MAAM,aAAa,EAAE,WAAiC,CAAA;AAE7D;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,WAG3B,CAAA;AAEF,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,EAAE,WAK9B,CAAA;AAED,gGAAgG;AAChG,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AA0BD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,WAA8B,GAAG,UAAU,CAuBtF;AAED,eAAO,MAAM,mBAAmB,YAAqB,CAAA"}