useDecrypt
Hook for decrypting confidential values with user authorization.
Usage
import { useDecrypt } from '@fhevmsdk/react'
function Component() {
const { decrypt, isDecrypting, canDecrypt } = useDecrypt()
const handleDecrypt = async () => {
const value = await decrypt({
ciphertextHandle: '0xabcd...',
contractAddress: '0x...',
})
console.log('Decrypted:', value)
}
return <button onClick={handleDecrypt}>Decrypt</button>
}
Returns
interface UseDecryptReturn {
decrypt: (params: DecryptParams) => Promise<bigint>
isDecrypting: boolean
error: string | null
canDecrypt: boolean
}
Parameters
interface DecryptParams {
ciphertextHandle: string
contractAddress: string
// walletClient is automatic from Wagmi
}
Examples
Basic Decryption
import { useDecrypt } from '@fhevmsdk/react'
import { useReadContract } from 'wagmi'
function BalanceDisplay() {
const { decrypt, isDecrypting } = useDecrypt()
const [balance, setBalance] = useState<bigint>()
const { data: encryptedBalance } = useReadContract({
address: tokenAddress,
abi: tokenABI,
functionName: 'balanceOf',
args: [userAddress],
})
const handleReveal = async () => {
const decrypted = await decrypt({
ciphertextHandle: encryptedBalance as string,
contractAddress: tokenAddress,
})
setBalance(decrypted)
}
return (
<div>
{balance ? (
<p>Balance: {balance.toString()}</p>
) : (
<button onClick={handleReveal} disabled={isDecrypting}>
{isDecrypting ? 'Revealing...' : 'Reveal Balance'}
</button>
)}
</div>
)
}
With Formatted Display
import { useDecrypt } from '@fhevmsdk/react'
import { formatTokenAmount } from '@fhevmsdk/core'
function FormattedBalance({ handle, contract }: Props) {
const { decrypt } = useDecrypt()
const [balance, setBalance] = useState<string>()
const handleReveal = async () => {
const value = await decrypt({
ciphertextHandle: handle,
contractAddress: contract,
})
const formatted = formatTokenAmount(value, 18)
setBalance(formatted)
}
return (
<div>
{balance ? `${balance} tokens` : <button onClick={handleReveal}>Reveal</button>}
</div>
)
}
Error Handling
import { useDecrypt } from '@fhevmsdk/react'
function SafeDecrypt() {
const { decrypt, error, canDecrypt } = useDecrypt()
const handleDecrypt = async () => {
if (!canDecrypt) {
alert('Please connect your wallet')
return
}
try {
const value = await decrypt({ ciphertextHandle: '0x...', contractAddress: '0x...' })
console.log('Success:', value)
} catch (err) {
if (err.message.includes('permission')) {
alert('You do not have permission to decrypt this value')
} else if (err.message.includes('rejected')) {
alert('You cancelled the request')
} else {
console.error('Decryption failed:', err)
}
}
}
return (
<div>
<button onClick={handleDecrypt} disabled={!canDecrypt}>Decrypt</button>
{error && <p className="error">{error}</p>}
</div>
)
}
State Properties
isDecrypting
boolean - True while decryption is in progress
{isDecrypting && <Spinner />}
<button disabled={isDecrypting}>Decrypt</button>
error
string | null - Error message if last decryption failed
{error && <div className="error">{error}</div>}
canDecrypt
boolean - True if FHEVM ready, wallet connected, and wallet client available
<button disabled={!canDecrypt}>Decrypt</button>
{!canDecrypt && <p>Please connect wallet to decrypt</p>}
Notes
- ✅ Automatically uses connected wallet for signing
- ✅ Prompts user to sign EIP-712 message
- ✅ Handles permission verification via ACL
- ⚠️ Requires ACL permission (granted by contract)
- ⚠️ User must approve each decryption request
- ⚠️ Must be used within
FHEVMProvider
See Also
- Core Decrypt API - Core decryption method
- useEncrypt - Encryption hook
- useConfidentialBalance - Higher-level balance hook