Web3 Architecture
FHEVM hooks, encryption/decryption flows, and on-chain compliance
Zentity's Web3 layer keeps identity verification off-chain and uses the blockchain solely for encrypted attestation and compliance checks, so that on-chain contracts never see plaintext identity data. This document maps the Web2-to-Web3 transition from verification to on-chain attestation, with the trust boundary between the registrar (server) and the ACL (on-chain) as the axis of variation.
System Context
The registrar encrypts identity attributes and submits attestations to fhEVM. Users authorize decryption and access via explicit grants. The following sections move from system context through the transition flow to Web3-specific mechanics.
Key technologies
| Technology | Purpose |
|---|---|
| FHEVM | Encrypted smart contract operations |
| Reown AppKit | Wallet connection UX |
| Wagmi | Wallet state + Ethereum hooks |
| tRPC | Type-safe API between frontend and backend |
| ethers.js | Transaction signing + EIP-712 support |
Key ideas
- Encrypted on-chain state: ciphertext handles only, no plaintext in contracts.
- Server-side attestation: registrar encrypts identity attributes and submits attestations.
- User-controlled access: decryption and access are gated by user-authorized grants.
- FHE-based compliance: contracts evaluate policies on encrypted data.
Auth & session gating
- Wallet connection ≠ session: Reown AppKit connects a wallet, but it does not create a server session.
- SIWE bridge: the UI performs Sign‑In With Ethereum via Better Auth (
/api/auth/siwe/*) to mint a session and link the wallet address. - Wallet-as-auth: Wallet signatures (EIP-712) can also serve as the primary authentication method for account creation, distinct from wallet connection for on-chain operations.
- Server gating: Web3/FHE APIs require a Better Auth session and explicit credential unlock for encrypted payloads.
Web2 to Web3 Transition
Zentity bridges traditional identity verification with privacy-preserving blockchain attestation.
The two worlds
| Aspect | Web2 (Off-chain) | Web3 (On-chain) |
|---|---|---|
| Purpose | Collect and verify identity | Enforce compliance on encrypted data |
| Data state | Plaintext briefly; encrypted at rest | Encrypted throughout |
| Trust model | Trust Zentity backend | Trustless verification |
| Storage | Commitments and ciphertexts | Ciphertext handles |
| Operations | OCR, liveness, face match | Encrypted comparisons and policy checks |
PoC limitations
| Limitation | Current state | Production requirement |
|---|---|---|
| Country codes | ~55 countries supported (EU, EEA, LATAM, Five Eyes, + 4 additional) | Full ISO 3166-1 coverage |
| Rate limiting | In-memory (resets on restart) | Redis or DB-backed |
| Liveness sessions | In-memory storage | Persistent storage (Redis/DB) |
Note: The attestation flow supports a demo mode that simulates successful submissions without on-chain transactions.
Data flow
What stays in Web2
- Document OCR and authenticity checks
- Liveness and face match scoring
- ZK proof generation (client-side)
- Encryption of sensitive attributes
- Storage of commitments, proofs, and evidence packs
- Passkey-based key custody for encrypted attributes
What moves to Web3
- Encrypted identity attributes stored in smart contracts
- ACL-gated access to ciphertexts
- Encrypted compliance checks (no plaintext)
- Optional encrypted asset transfers (demo)
- Typical encrypted fields: date of birth (dobDays), country code, compliance tier, and sanctions status
Encryption boundaries
- Web2: Attributes are encrypted off-chain and stored as ciphertexts; only the user can decrypt.
- Web3: Attestations are encrypted server-side and stored on-chain as ciphertext handles.
- Access: Users grant contracts explicit access via ACLs; decryption requires user authorization.
Encryption points
- Client-side encryption for user-initiated encrypted transfers.
- Server-side encryption for on-chain attestations.
- Never encrypted: wallet addresses, transaction hashes, and event metadata.
Computation under encryption
The fhEVM never sees plaintext. Compliance checks execute directly on encrypted attributes.
Access control model
Each ciphertext handle has an ACL that controls who can read or decrypt encrypted state.
| State | Can transfer | Can read own data | Compliance can check |
|---|---|---|---|
| Not attested | No | No | No |
| Attested, no grant | No | Yes | No |
| Attested + granted | Yes | Yes | Yes |
Silent failure pattern
Compliance checks do not revert when failing. Instead, they return an encrypted "false" that results in a zero-value transfer. This avoids leaking compliance status on-chain.
UI implications:
- A transaction can succeed while transferring zero.
- The UI must verify balance changes to detect failures.
- Users should grant access and verify attestation status before transferring.
Operational responsibilities
- Users: complete Web2 verification, attest on-chain, grant access before transfers.
- Operators: deploy contracts, set authorized callers, configure registrar keys.
- UI integrators: check attestation and access status before enabling transfers.
Integration checklist
- Verify Web2 proofs and signed claims before enabling Web3 attestation.
- Ensure the wallet is connected to the target network with gas available.
- Ensure SIWE has established a Better Auth session for the wallet address.
- Require a passkey PRF unlock before generating or decrypting encrypted payloads.
- Confirm the registrar keys and contract addresses are configured.
- Confirm ACL grants are issued for required contracts.
- Validate disclosure flows against the evidence pack schema.
Configuration details (network endpoints, contract addresses, registrar keys) are environment-specific and managed through deployment configuration.
Common failure modes
- Transfers succeed but move zero because access was not granted.
- Attestations fail because registrar configuration is missing.
- Compliance checks fail due to incorrect attribute encoding.
Security model (public vs encrypted)
Encrypted:
- Date of birth (dobDays) and nationality
- Compliance level and sanctions status
- Compliance results and encrypted balances
Public:
- Wallet addresses and transaction existence
- Contract interactions and event metadata
- Gas usage
High-Level Architecture
On-Chain Data Flow
Key points:
- Attestation encryption happens server-side (registrar + relayer SDK).
- Wallet-initiated operations use client-side FHEVM SDK.
- Contracts operate on ciphertexts only; no plaintext is revealed.
- Access is explicit: users grant contract-level access to their ciphertexts.
Provider Hierarchy
Provider responsibilities
| Provider | Purpose |
|---|---|
Web3Provider | Root wrapper; initializes AppKit and shared clients |
trpcReact.Provider | Type-safe API client |
WagmiProvider | Wallet connection state + hooks |
QueryClientProvider | Shared cache for tRPC + Wagmi |
InMemoryStorageProvider | Signature cache for decryption |
FhevmProvider | Manages FHEVM SDK lifecycle |
SDK Lifecycle States
| State | Meaning |
|---|---|
idle | No wallet connected or SDK not initialized |
loading | WASM modules and SDK are initializing |
ready | SDK is usable for encryption/decryption |
error | Initialization failed |
Client-Side Encryption Flow
Decryption Flow
Attestation Flow
Revocation Flow
When an identity verification is revoked (admin or self-service), the on-chain attestation is also revoked:
- DB revocation is committed in a transaction (marks
identity_verificationsandidentity_bundleas revoked). - On-chain revocation is attempted outside the DB transaction (best-effort).
- If the on-chain call fails, the attestation enters
revocation_pendingstatus. - Retry uses exponential backoff: 1s → 3s → 9s, max 3 attempts.
- If all retries fail, an admin tRPC procedure (
admin.retryOnChainRevocation) allows manual retry.
DB revocation is committed regardless of on-chain success; the server-side state is always authoritative.
Data Privacy Model
- Identity verification happens off-chain (OCR, liveness, face match).
- Identity attributes are encrypted server-side by the registrar.
- Ciphertext handles are stored on-chain (no plaintext).
- Compliance checks operate on ciphertexts (no decryption in contracts).
- Attestation metadata includes proof and policy hashes for auditability.
- User decryption requires explicit authorization (signature-based).
Privacy & Access Control Patterns
- Encryption boundaries: data is encrypted before it touches the chain and remains encrypted throughout contract execution.
- ACL-gated access: ciphertext handles are readable only by approved contracts.
- User-authorized decryption: decryption requires explicit user authorization.
- Silent failure: compliance checks avoid leaking policy details when access is missing.
See Tamper Model for integrity controls and Attestation & Privacy Architecture for data classification.
How This Fits the Web2 Flow
Web2 performs collection + verification; Web3 performs encrypted attestation + compliance checks.
- Web2 stores commitments, proofs, and encrypted attributes.
- Web3 stores encrypted attestation handles + public metadata.
The end-to-end transition is captured in the Web2 to Web3 Transition section above.