Skip to main content

Hooks Overview

The FHEVM SDK provides a comprehensive set of React hooks for working with encrypted smart contracts. These hooks handle encryption, decryption, contract interactions, and state management automatically.

Categories​

Contract Interaction Hooks​

Hooks for reading and writing to smart contracts with automatic encryption/decryption:

Token Hooks​

Specialized hooks for token operations:

Utility Hooks​

Helper hooks for common operations:

Quick Reference​

HookPurposeAuto-EncryptAuto-Decrypt
useContractGet contract instanceNoNo
useReadContractRead contract stateNoYes
useWriteContractWrite to contractYesNo
useDecryptedValueDecrypt a handleNoYes
useTokenBalanceGet token balanceNoYes
useTokenTransferTransfer tokensYesNo
useOperatorManage operatorsYesNo
useBatchTransactionsBatch operationsYesNo

Common Patterns​

Pattern 1: Read Encrypted Data​

import { useReadContract } from '@fhevm/sdk';

function BalanceDisplay() {
const { decryptedData, isLoading, isDecrypting } = useReadContract({
address: '0x123...',
abi: tokenAbi,
functionName: 'balanceOf',
args: [userAddress],
decrypt: true,
});

if (isLoading || isDecrypting) return <div>Loading...</div>;

return <div>Balance: {decryptedData?.toString()}</div>;
}

Pattern 2: Write Encrypted Data​

import { useWriteContract } from '@fhevm/sdk';

function TransferButton() {
const { write, isLoading, isSuccess } = useWriteContract({
address: '0x123...',
abi: tokenAbi,
});

const handleTransfer = async () => {
await write({
functionName: 'confidentialTransfer',
args: [recipientAddress, 100n],
});
};

return (
<button onClick={handleTransfer} disabled={isLoading}>
{isLoading ? 'Transferring...' : 'Transfer'}
</button>
);
}

Pattern 3: Use Named Contracts​

import { useReadContract } from '@fhevm/sdk';

function MyComponent() {
// Reference contract by name from config
const { decryptedData } = useReadContract({
name: 'myToken', // From config
functionName: 'balanceOf',
args: [userAddress],
decrypt: true,
});

return <div>{decryptedData?.toString()}</div>;
}

Pattern 4: Conditional Fetching​

import { useReadContract } from '@fhevm/sdk';

function ConditionalFetch({ enabled }: { enabled: boolean }) {
const { data, refetch } = useReadContract({
address: '0x123...',
abi: tokenAbi,
functionName: 'getData',
enabled: enabled, // Only fetch when enabled
});

return (
<div>
{data && <p>Data: {data}</p>}
<button onClick={() => refetch()}>Refresh</button>
</div>
);
}

Hook Capabilities​

Automatic Encryption​

Hooks like useWriteContract and useTokenTransfer automatically detect which parameters need encryption based on the ABI:

  • externalEuint* types (e.g., externalEuint64)
  • euint* types (e.g., euint64)
  • externalEbool types

No manual encryption is needed:

// This is automatically encrypted
write({
functionName: 'transfer',
args: [recipient, 100n], // Amount is encrypted if ABI specifies externalEuint64
});

Automatic Decryption​

Hooks like useReadContract and useDecryptedValue automatically decrypt encrypted return values:

  • Detects bytes32 handles
  • Requests decryption signature from user (once per session)
  • Decrypts using FHEVM instance
  • Caches results for performance
// This is automatically decrypted
const { decryptedData } = useReadContract({
functionName: 'getBalance',
decrypt: true, // Enable auto-decrypt
});

Type Safety​

All hooks are fully typed with TypeScript:

import { useWriteContract } from '@fhevm/sdk';
import type { MyTokenAbi } from './types';

function TypedComponent() {
const { write } = useWriteContract<MyTokenAbi>({
address: '0x123...',
abi: myTokenAbi,
});

// TypeScript knows about your contract functions
write({
functionName: 'transfer', // Autocomplete works!
args: [recipient, amount], // Type-checked!
});
}

Error Handling​

All hooks provide error states:

const { data, error, isError } = useReadContract({
address: '0x123...',
abi: tokenAbi,
functionName: 'getData',
});

if (isError) {
console.error('Failed to read:', error);
return <div>Error: {error?.message}</div>;
}

Loading States​

Track loading and processing states:

const {
isLoading, // Initial loading
isDecrypting, // Decryption in progress
isSuccess, // Operation succeeded
} = useReadContract({
address: '0x123...',
abi: tokenAbi,
functionName: 'getData',
decrypt: true,
});

return (
<div>
{isLoading && <Spinner />}
{isDecrypting && <span>Decrypting...</span>}
{isSuccess && <span>Success!</span>}
</div>
);

Context Requirements​

Most hooks require the FhevmProvider to be present in the component tree:

import { FhevmProvider } from '@fhevm/sdk';

function App() {
return (
<FhevmProvider config={config}>
{/* Hooks can be used here */}
<YourComponent />
</FhevmProvider>
);
}

Next Steps​

Best Practice

Enable the cache in your configuration for better performance. Decryption operations can be slow, and caching significantly improves UX.

Provider Required

All hooks must be used within a FhevmProvider. Make sure to wrap your app appropriately.