跳到主要内容

Quickstart Guide

Get started with the FHEVM SDK in minutes. This guide will show you how to set up your application and perform your first encrypted transaction.

Installation

Install the FHEVM SDK package:

npm install @fhevm/sdk
# or
yarn add @fhevm/sdk
# or
pnpm add @fhevm/sdk

Basic Setup

1. Create Configuration

First, create a configuration for your FHEVM application:

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

const config = createConfig({
chains: [
{
id: 8009,
name: 'Zama Devnet',
rpcUrl: 'https://devnet.zama.ai',
isMock: false,
},
],
cache: {
enabled: true,
ttl: 60000, // 1 minute
},
});

2. Wrap Your App with FhevmProvider

Wrap your application with the FhevmProvider to make FHEVM functionality available throughout your app:

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

function App() {
return (
<FhevmProvider config={config}>
<YourApp />
</FhevmProvider>
);
}

3. Connect Wallet

Use the provider to sync with your wallet provider (e.g., wagmi, ethers):

import { useSyncWithWallet } from '@fhevm/sdk';
import { useAccount, useWalletClient } from 'wagmi';
import { useMemo } from 'react';
import { BrowserProvider } from 'ethers';

function YourComponent() {
const { address, chainId } = useAccount();
const { data: walletClient } = useWalletClient();

const ethersSigner = useMemo(() => {
if (!walletClient) return undefined;
const provider = new BrowserProvider(walletClient);
return provider.getSigner();
}, [walletClient]);

useSyncWithWallet({
address,
chainId,
signer: ethersSigner,
});

return <div>Connected: {address}</div>;
}

Your First Encrypted Transaction

Reading Encrypted Data

Use the useReadContract hook to read from a contract. The SDK automatically decrypts encrypted return values:

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

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

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

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

Writing Encrypted Data

Use the useWriteContract hook to write encrypted data. The SDK automatically encrypts your inputs:

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

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

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

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

Using Token Transfer Hook

For token transfers, use the specialized useTokenTransfer hook:

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

function TokenTransfer() {
const { transfer, isLoading, isSuccess } = useTokenTransfer({
address: '0x123...',
abi: myTokenAbi,
isConfidential: true, // Use confidentialTransfer
});

const handleTransfer = async () => {
await transfer({
to: '0x456...',
amount: '100', // Human-readable amount
decimals: 18,
});
};

return (
<div>
<button onClick={handleTransfer} disabled={isLoading}>
Transfer Tokens
</button>
{isSuccess && <p>Transfer successful!</p>}
</div>
);
}

Complete Example

Here's a complete example bringing it all together:

import { createConfig, FhevmProvider, useReadContract, useWriteContract, useSyncWithWallet } from '@fhevm/sdk';
import { useAccount, useWalletClient } from 'wagmi';
import { BrowserProvider } from 'ethers';
import { useMemo } from 'react';

// 1. Create config
const config = createConfig({
chains: [
{
id: 8009,
name: 'Zama Devnet',
rpcUrl: 'https://devnet.zama.ai',
},
],
});

// 2. Main App Component
function App() {
return (
<FhevmProvider config={config}>
<WalletSync />
<EncryptedCounter />
</FhevmProvider>
);
}

// 3. Sync with wallet
function WalletSync() {
const { address, chainId } = useAccount();
const { data: walletClient } = useWalletClient();

const ethersSigner = useMemo(() => {
if (!walletClient) return undefined;
const provider = new BrowserProvider(walletClient);
return provider.getSigner();
}, [walletClient]);

useSyncWithWallet({ address, chainId, signer: ethersSigner });
return null;
}

// 4. Use encrypted contract
function EncryptedCounter() {
const { decryptedData, isLoading } = useReadContract({
address: '0x123...',
abi: counterAbi,
functionName: 'getCount',
decrypt: true,
});

const { write, isLoading: isWriting } = useWriteContract({
address: '0x123...',
abi: counterAbi,
});

return (
<div>
<p>Count: {isLoading ? 'Loading...' : decryptedData?.toString()}</p>
<button
onClick={() => write({ functionName: 'increment', args: [1] })}
disabled={isWriting}
>
Increment
</button>
</div>
);
}

export default App;

Next Steps

Common Issues

Cache Configuration

Make sure to enable caching for better performance. Decryption operations can be slow, and caching significantly improves the user experience.

TypeScript Support

The SDK is fully typed. Make sure to use TypeScript for the best development experience and to catch errors at compile time.

Testing

For testing, you can use mock chains by setting isMock: true in your chain configuration. This allows you to test your application without connecting to a real network.