# zkAPI Markdown version of https://l2beat.com/zk-catalog/zkapi ## Summary **Warning:** The vault owner can block withdrawals until deposits expire and become sweepable to the treasury. The proofs rely on a single-party trusted setup. - Creator: Open Anonymity - Total Value Secured: $2.32 K (+26.2% compared to seven days ago) - Trusted setups for Arkworks (Groth16): - zkapi-v2-note-bound-v1 single-party setup, risk red (highest risk) per the [Trusted Setups Risk Framework](https://forum.l2beat.com/t/the-trusted-setups-framework-for-zk-catalog/381): The published request and withdrawal keys were generated by one party. Retained setup secrets can allow forged proofs. - Used in: [zkAPI](https://l2beat.com/privacy/projects/zkapi) - Verifiers: 1 not verified - zkVM: Arkworks (Groth16), BN254 (curve) ### About Anonymous access to AI models, prepaid with ETH, that hides which deposit pays for which request. ### Links - Website: https://chat.openanonymity.ai - Docs: https://zkapi.openanonymity.ai - Repository: https://github.com/ethereum/zkapi ## Value Secured The interactive TVS chart is shown on [the HTML page](https://l2beat.com/zk-catalog/zkapi#tvs). ## Proof System Application-specific request and withdrawal Groth16 circuits over BN254. Poseidon Merkle membership and note-bound Baby-JubJub balance commitments hide the note and balance during authorization. Withdrawals expose the note id and remaining balance. ## Trusted Setups Risk levels follow the [Trusted Setups Risk Framework](https://forum.l2beat.com/t/the-trusted-setups-framework-for-zk-catalog/381). Yellow (medium risk): all contributions are published and the final output can be verified, the ceremony client is open source, there were at least 30 contributions, participation was open to the public and announced, and participants are publicly identified. Green (lowest risk): everything required for yellow, with at least 150 contributions. Red (highest risk): at least one requirement for yellow is not met. N/A: the proof system needs no trusted setup. ### zkapi-v2-note-bound-v1 single-party setup - Risk: red (highest risk) - Proof systems: Arkworks (Groth16) The request and withdrawal Groth16 keys were generated by one party. There was no multi-party ceremony. Security requires that this party erased the setup secrets, otherwise it can forge withdrawal proofs. Matching public artifacts cannot prove erasure. [Setup implementation](https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/protocol/rust/crates/zkapi-proof/src/compact.rs#L288-L383), [provenance](https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/protocol/setup/v2/README.md). ## Verifier IDs List of different onchain verifiers for this proving system. Unique ID distinguishes different deployments of the same verifier from different verifiers (e.g. different versions). ### Groth16: Arkworks Arkworks implementation of Groth16 written in Rust. #### zkapi note-bound request and withdrawal verifier - Verifier ID: `0xd31acf861825869e6a84b6b0025cb6940077f5981a10e73d2e4e8e5d7417c853` - Source: https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/protocol/rust/crates/zkapi-proof/src/groth16.rs - Verification: not verified - Used in: [zkAPI](https://l2beat.com/privacy/projects/zkapi) **Known deployments** - [0x8e92013Dd7cc86f75b539DBD3814B2e603e0F9C1](https://etherscan.io/address/0x8e92013Dd7cc86f75b539DBD3814B2e603e0F9C1#code) on Ethereum, used in: [zkAPI](https://l2beat.com/privacy/projects/zkapi) ##### Verification steps ###### Contracts and proof artifacts Reviewed [ethereum/zkapi revision](https://github.com/ethereum/zkapi/tree/045b444ea1b52538d1b40273c7cb6ed09468a052), whose vault, adapter and circuits match the deployment revision reported by the production manifest. Compile with the checked-in configuration: solc 0.8.28, optimizer 200, viaIR and Prague. ```bash git clone https://github.com/ethereum/zkapi.git cd zkapi git checkout 045b444ea1b52538d1b40273c7cb6ed09468a052 cd demo/contracts forge build --skip test --build-info cast tx 0xf753fd93c7e672f7b851f261f600e06930e502bdfd73be29ce8a065643df6985 --json --rpc-url "$ZKAPI_RESEARCH_RPC_URL" > vault-tx.json cast tx 0x45f2f5259476afd5f64a6a62a36c9012c3a26efcdd35b048a7fac5ae1ba43780 --json --rpc-url "$ZKAPI_RESEARCH_RPC_URL" > verifier-tx.json ``` The adapter creation bytecode matches exactly, including metadata. The vault matches after linking the discovered Poseidon address. Decode its ten constructor arguments from the remaining transaction input. Sources are verified on Etherscan: [vault](https://etherscan.io/address/0x4386FDbdA35D995beB3BF8625118Ec5982ec81fe#code), [adapter](https://etherscan.io/address/0x8e92013Dd7cc86f75b539DBD3814B2e603e0F9C1#code), [Poseidon](https://etherscan.io/address/0xc6B55e86668d8c446B3D81273AAb9CBb20F28c7f#code). The deployed verification-key coordinates and public inputs match the [published setup artifacts](https://github.com/ethereum/zkapi/tree/045b444ea1b52538d1b40273c7cb6ed09468a052/protocol/setup/v2), and the proving-key hashes match the SDK and production pins. A single-party setup with fresh randomness yields different keys each time, so matching artifacts show that the deployed keys are the published ones. Only the setup party knows whether its secrets were erased. ###### Frontend and local client The [browser frontend](https://github.com/OpenAnonymity/oa-chat/blob/60ed5be2957d984c70a7299474927becec47b61f/README.md#quick-start) and the [local API daemon](https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/zkapi-clientd/README.md) have public source and build instructions. Both still depend on the operator's authorization and inference services. ###### Verifier enclave The mainnet verifier is `verifier-production-20260917.openanonymity.ai`, pinned in the hosted app's [browser config](https://chat.openanonymity.ai/zkapi/browser-config.json). It runs in an Azure confidential container on AMD SEV-SNP and serves a hardware attestation. Its source, [OpenAnonymity/oa-verifier](https://github.com/OpenAnonymity/oa-verifier), is pinned to commit `4299cfa` by the [production rollout](https://github.com/OpenAnonymity/oa-verifier/blob/86b7031c2f15d01d19efb77f547812e29992d4d9/deploy/production/rollout.py#L27-L29). ```bash curl -sS "https://verifier-production-20260917.openanonymity.ai/attestation?nonce=$(date +%s)" > attestation.json # 1. the JWT in .token is signed by Azure Attestation (.verify_at), its x-ms-sevsnpvm-hostdata equals sha256 of the decoded .policy # 2. the policy lists one dm-verity layer hash for the verifier container git clone https://github.com/OpenAnonymity/oa-verifier && cd oa-verifier git checkout 4299cfa136c90550737dd46c89dba586c213159b nix build .#container && docker load < result # 3. push oa-verifier:latest to a local registry, then go install github.com/Microsoft/hcsshim/cmd/dmverity-vhd@v0.12.9 dmverity-vhd roothash -i localhost:5000/oa-verifier:latest ``` The rebuilt image matches the published `ghcr.io/openanonymity/oa-verifier@sha256:60f9892b…` in nix store path, config and layer, and its layer root hash equals the attested policy. Pushing through a different docker version changes the compressed manifest digest, while the measured layer hash stays. The attestation also binds the TLS key of the live endpoint. Both clients pin only the verifier's address, so repeat the check when it matters.