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, encrypted compliance checks, and minimal public compliance mirroring. On-chain contracts never see plaintext identity data. The Base mirror stores only attested/unattested state and the current compliance level for isCompliant(address,uint8) reads.
The decision record for the public-read mirror is ADR-0005: Base compliance mirror for payment-time reads. This page describes the runtime architecture and operational flow.
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 |
| Base Sepolia mirror | Public, level-aware compliance reads for x402 and resource servers |
| 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.
- Base mirror compliance: contracts and resource servers can read
isCompliant(user,minLevel)without learning underlying PII.
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)
- Public Base compliance mirror for
isCompliant(user,minLevel)reads - 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, event metadata, and Base mirror attested/level state.
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
- Base mirror attested/unattested status and numeric compliance level
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
On-chain attestation revocation is one delivery target of the canonical validity pipeline, not a separate business flow:
- A revoke transition updates the current account snapshot and appends one
identity_validity_eventsrow. - The same transition schedules
blockchain_attestation_revocationinidentity_validity_deliveriesalongside other downstream targets such as credential-status updates, CIBA cancellation, back-channel logout, and RP validity notice. - The delivery worker attempts the on-chain revoke outside the snapshot transaction.
- If the chain call fails, the delivery stays retryable and the attestation moves to
revocation_pending. - The same delivery framework handles retries and operator visibility;
admin.retryOnChainRevocationis an operational convenience, not a second revocation architecture.
Chain-originated revocations and confirmations also feed back through the same validity pipeline, so "confirmed on chain," "revoked on chain," and "valid in product" converge on one lifecycle model.
Base Mirror Flow
The Base mirror is a delivery target of the same validity pipeline:
- A Sepolia
IdentityAttestedevent is observed or an attestation refresh confirms a transaction. - Zentity records a chain-sourced
verifiedvalidity event. - The delivery worker schedules
mirror_compliance_write. - The mirror writer reads the current compliance level from the identity read model at execution time.
- The writer calls Base
IdentityRegistryMirror.recordCompliance(user, level). - A revoke transition schedules
mirror_revocation_write, which callsrevokeAttestation(user).
This keeps the mirror eventually consistent with the canonical read model while avoiding a parallel queue or mirror-specific table.
The mirror is not a second source of identity truth. It is a public delivery surface for payment-time reads, and any new public predicate must go through a separate privacy review before it is added.
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.