For developers

Architecture

A tour of the pieces behind Obscura: confidential tokens, the FHEVM coprocessor and relayer, the access-control list, the distribution contracts, and the frontend stack.

The big picture

Obscura is a frontend over a small set of pre-deployed contracts. It does not run its own backend or indexer for the core flows. Three systems do the work:

  • Zama FHEVM encrypts amounts and runs the homomorphic math off-chain on a coprocessor.
  • TokenOps contracts (airdrop, vesting, disperse) hold and move the encrypted allocations.
  • ERC-7984 tokens (any confidential token you import) carry the confidential balances.

The end-to-end flow

1

Encrypt in the browser

The frontend encrypts each amount to its recipient with the Zama relayer, producing a handle and an input proof. Plaintext never leaves the machine.
2

Write handles onchain

The distribution contract stores handles, not values, and moves tokens with ERC-7984 transfers.
3

Compute off-chain

The FHEVM coprocessor evaluates the encrypted operations; the chain only ever holds ciphertext handles.
4

Decrypt with permission

A recipient calls the relayer to decrypt their own handle. The onchain ACL gates who is allowed to.

Encrypted values and handles

An encrypted amount is a 64-bit ciphertext (euint64) referenced by an opaque handle. Contracts operate on handles; a block explorer shows handles and addresses, never a plaintext amount. See Confidentiality & FHEVM for the encryption model.

The ACL

Every encrypted value carries an access-control list. Decryption is gated by it: the contract that stored a handle must have granted a wallet access, or the decrypt fails. In the app this is a two-call pattern, one EIP-712 signature per session, cached in IndexedDB so later decrypts are silent.

Missing an ACL grant is the difference between a value a recipient can read and one they cannot. It is enforced onchain, not in the frontend.

Distribution contracts

The TokenOps airdrop factory, vesting factory, and disperse singleton are pre-deployed on Sepolia and called through @tokenops/sdk; Obscura does not redeploy them. The confidential asset they move is any ERC-7984 token you import.

PieceRole
Airdrop factoryDeploys a per-campaign airdrop clone; recipients pull via signed authorizations.
Vesting factoryDeploys a vesting workspace; holds per-recipient encrypted grants.
Disperse singletonPushes encrypted subtotals to recipients via confidentialTransferFrom.

Real addresses are on Networks & contracts. Moving tokens uses ERC-7984 operator approval, not ERC-20 allowances; see ERC-7984 tokens.

The frontend stack

  • Next.js 15 (App Router) and React 18.
  • wagmi v2 and RainbowKit for wallets, connected only to Sepolia.
  • @tokenops/sdk for the distribution contracts and disperse orchestration.
  • @zama-fhe/sdk and @zama-fhe/react-sdk for encryption and decryption, wiring the Zama relayer, a viem signer, and IndexedDB storage.
  • Tailwind CSS for the UI, and COOP/COEP headers so the Zama WASM can run in the browser.