Use decryptForView to reveal a confidential (encrypted) value locally in your app so you can display it in the UI.
Unlike decryptForTx, this flow does not return an on-chain-verifiable signature, and it is not meant to be published on-chain.
Flow
- Read the encrypted handle (
ctHash) from your contract.
- Ensure you have a permit that authorizes decryption of that value.
- Call
decryptForView(ctHash, utype).execute() to get the plaintext.
decryptForView always decrypts using a permit (there is no .withoutPermit() mode). If your protocol intends for the plaintext to become publicly visible on-chain, use decryptForTx instead.
Prerequisites
- Create and connect a client.
- Know the encrypted handle (
ctHash) and the encrypted type (utype).
- Have a permit available for the connected
chainId + account.
Getting ctHash: In most apps, ctHash comes from reading a stored encrypted value, an event arg, or a return value from a view call.
Providing utype: utype must match the ciphertext’s underlying FHE type. The SDK uses it to convert the decrypted bigint into a convenient JS type.Supported utypes:
FheTypes.Bool → returns a boolean
FheTypes.Uint160 (address) → returns a checksummed 0x... string
FheTypes.Uint8 | Uint16 | Uint32 | Uint64 | Uint128 → returns a bigint
Permit setup
If you don’t have a permit yet, create one once after connecting:
Decrypt for UI
Choose the pattern that matches how your app manages permits:
What decryptForView returns
Running .execute() resolves to a scalar JS value:
- Integer utypes (
Uint8, Uint16, Uint32, Uint64, Uint128): a bigint
FheTypes.Bool: a boolean
FheTypes.Uint160 (address): a checksummed 0x... address string
Builder API
.execute() — required, call last
Runs the decryption and returns a UI-friendly scalar value.
.withPermit(...) — optional
Select which permit to use:
.withPermit() — uses the active permit
.withPermit(permitHash) — fetches a stored permit by hash
.withPermit(permit) — uses the provided permit object
If you don’t call .withPermit(...), the active permit is used by default.
.setAccount(address) — optional
Overrides the account used to resolve the active/stored permit.
.setChainId(chainId) — optional
Overrides the chain used to resolve the Threshold Network URL and permits.
Common UI patterns
Common pitfalls
- Missing permit:
decryptForView will fail if there is no active permit for the current chainId + account.
- Wrong
utype: you must pass the correct FHE type for the ciphertext.
- Wrong chain/account: permits are scoped to
chainId + account. If the user switches wallets or networks, create/select the correct permit.