Documentation Index
Fetch the complete documentation index at: https://cofhe-docs.fhenix.zone/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The old decryption pattern usedFHE.decrypt(ctHash) to trigger an asynchronous decryption, followed by FHE.getDecryptResultSafe(ctHash) to read the result once available. The new pattern replaces FHE.decrypt with an off-chain decryption step using the Client SDK, and uses FHE.publishDecryptResult to submit the result on-chain with a cryptographic proof.
This guide walks through concrete before/after Solidity examples.
What changed
| Old pattern | New pattern | |
|---|---|---|
| Trigger decrypt | FHE.decrypt(ctHash) (on-chain) | FHE.allowPublic(ctHash) (on-chain) + client.decryptForTx(ctHash) (off-chain) |
| Submit result | Automatic (async, no proof) | FHE.publishDecryptResult(ctHash, plaintext, signature) |
| Verify only | N/A | FHE.verifyDecryptResult(ctHash, plaintext, signature) |
| Read result | FHE.getDecryptResultSafe(ctHash) | FHE.getDecryptResultSafe(ctHash) (same) |
The key difference:
FHE.decrypt triggered decryption without any proof. The new flow requires a Threshold Network signature, ensuring the plaintext is cryptographically verified before being used on-chain.The New Decryption Flow
Grant decryption permission (on-chain)
Instead of calling
FHE.decrypt(), mark the value as decryptable:Decrypt off-chain (client-side)
The client requests decryption from the Threshold Network, which returns the plaintext and a signature:
Example 1: Simple counter
A minimal example showing how the reveal pattern changes.Example 2: Token unshield (FHERC20Wrapper)
The unshield flow is whereFHE.decrypt was most commonly used. It already followed a two-step pattern (unshield + claim), which maps naturally to the new flow.
FHE.decrypt(burned)→FHE.allowPublic(burned)— no on-chain decryption is triggered, just a permission grantclaimUnshielded(bytes32 ctHash)→claimUnshielded(bytes32 ctHash, uint64 decryptedAmount, bytes signature)— the caller now provides the decrypted value + proofFHE.getDecryptResultSafe→FHE.publishDecryptResult— the contract verifies the Threshold Network signature instead of polling for a result
Example 3: Revealing a vote result
A simple pattern: revealing a single encrypted vote count after a deadline.publishDecryptResult vs verifyDecryptResult
| Method | Stores result on-chain | Others can read it | Use case |
|---|---|---|---|
publishDecryptResult | Yes | Yes, via getDecryptResultSafe | Revealing results publicly (auctions, votes, counters) |
verifyDecryptResult | No | No | One-time verification (transfers, burns) |
verifyDecryptResult when you only need to confirm the plaintext is authentic and don’t need other contracts or future calls to read it:
Migration checklist
Replace FHE.decrypt with FHE.allowPublic
In the function that previously called
FHE.decrypt(ctHash), replace it with FHE.allowPublic(ctHash).Add a finalize function
Create a new function that accepts
(plaintext, signature) parameters and calls FHE.publishDecryptResult or FHE.verifyDecryptResult.Next Steps
- Read about Decryption Operations for the full reference
- See Adding FHE to an Existing Contract for a complete contract migration
- Learn about Access Control for managing decrypt permissions
- Check the Client SDK decrypt guide for the full client-side API