Standard EVM stores numbers in cleartext storage slots. Anyone running a node can read the value. FHEVM adds a parallel storage layer: instead of the raw uint64, the contract stores a 32-byte EncryptedHandle that points at a ciphertext managed by the Zama coprocessor.
Encryption happens client-side — the SDK's encryptor (a wrapper around the Zama relayer) takes a plaintext value plus your wallet's signature and returns a handle plus a proof. The contract verifies the proof on write; the value is now under the contract's control but never cleartext in the EVM's view.
What you can do with a handle#
Three operations matter:
Compute. The contract can call FHE.add, FHE.sub, FHE.min, comparison ops, etc. on handles — producing new handles without ever decrypting. This is how vesting accrual, airdrop allocation, and disperse splitting work without leaking amounts.
Grant ACL. Per-handle access control. The contract calls FHE.allow(handle, address) to permit a specific address to decrypt. ACL is append-only: granting Mira permission to view her vested amount doesn't grant her permission to view Investor A's. The grant lives in chain state, indexed by handle.
User-decrypt. Holders of an ACL grant query the Zama relayer with a signature; the relayer returns the plaintext. The SDK's useDecryptedHandle hook wraps this — pass it a handle and it reactively decrypts via the connected wallet.
Why @zama-fhe is an optional peer dep#
The SDK ships zero dependencies on @zama-fhe/relayer-sdk at the top level. Consumers running non-FHE flows (the cross-product utility modules, the headless types, anything in @tokenops/sdk root) pay no bundle cost.
Pulling in @tokenops/sdk/fhe-vesting + installing @zama-fhe/relayer-sdk as a peer dep is the moment FHE materializes. The encryptor source pattern (next page) is how we keep this clean across React, Vue, and Node consumers.
FHEVM-aware contracts the SDK targets#
Three products. Each ships a different contract shape but shares the FHE primitive vocabulary:
fhe-vesting — factory deploys per-user manager clones; each clone holds encrypted vesting positions for many recipients. Recipient claims call FHE.min(vested, available) on chain to compute the unlocked amount without revealing either input.
fhe-airdrop — factory deploys per-cohort clones with an EIP-712 admin signer. Admin signs Claim(recipient, encryptedAmountHandle) off chain; recipient redeems on chain; the clone grants ACL atomically.
fhe-disperse — singleton contract per chain. One disperse() call grants ACL to N recipients in one tx; each recipient sees only their own amount.