This guide will help you get up and running with the FHEVM SDK in minutes.
Before you begin, ensure you have:
- Node.js 18+ installed (Download)
- npm or yarn package manager
- MetaMask browser extension (Install)
- Sepolia testnet ETH (Faucet)
Install the SDK in any JavaScript/TypeScript project:
npm install @fhevm-sdk/core fhevmjs ethersThen use it:
import { FhevmClient, encryptInput } from '@fhevm-sdk/core';
const client = new FhevmClient();
await client.init(provider);Try the complete example application:
# Navigate to example
cd examples/nextjs-sports-contract
# Install dependencies
npm install
# Start development server
npm run devWork on the SDK itself:
# Install all workspace dependencies
npm install
# Build the SDK
npm run build:sdk
# Run Next.js example
npm run dev:nextjsIn your project directory:
npm install @fhevm-sdk/core fhevmjs ethersCreate a new file app.ts:
import { BrowserProvider } from 'ethers';
import { FhevmClient, encryptInput } from '@fhevm-sdk/core';
// Initialize client
const client = new FhevmClient({
network: {
chainId: 11155111, // Sepolia
},
});
// Connect to MetaMask
const provider = new BrowserProvider(window.ethereum);
await provider.send('eth_requestAccounts', []);
// Initialize FHEVM
await client.init(provider);
// Create encrypted input
const instance = client.getInstance();
const userAddress = await provider.getSigner().getAddress();
const contractAddress = '0x...'; // Your contract
const input = encryptInput(instance, contractAddress, userAddress);
input.add32(42);
const encrypted = await input.encrypt();
console.log('Encrypted:', encrypted);Create a React app with the SDK:
// App.tsx
import { FhevmProvider } from '@fhevm-sdk/core';
import { MainComponent } from './MainComponent';
function App() {
return (
<FhevmProvider config={{ network: { chainId: 11155111 } }}>
<MainComponent />
</FhevmProvider>
);
}
// MainComponent.tsx
import { useState } from 'react';
import { BrowserProvider } from 'ethers';
import { useFhevmClient, useFhevmInit } from '@fhevm-sdk/core';
function MainComponent() {
const [provider, setProvider] = useState<BrowserProvider | null>(null);
const client = useFhevmClient();
const { isInitialized, isLoading, error } = useFhevmInit(provider);
const connectWallet = async () => {
const newProvider = new BrowserProvider(window.ethereum);
await newProvider.send('eth_requestAccounts', []);
setProvider(newProvider);
};
if (!provider) {
return <button onClick={connectWallet}>Connect Wallet</button>;
}
if (isLoading) {
return <div>Initializing FHEVM...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
if (isInitialized) {
return <div>Ready to use FHEVM!</div>;
}
return null;
}In a Next.js project:
// app/layout.tsx
import { FhevmProvider } from '@fhevm-sdk/core';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<FhevmProvider config={{ network: { chainId: 11155111 } }}>
{children}
</FhevmProvider>
</body>
</html>
);
}
// app/page.tsx
'use client';
import { useFhevmClient, useEncryptedInput } from '@fhevm-sdk/core';
export default function Home() {
const client = useFhevmClient();
const { createInput } = useEncryptedInput(
'0x...', // contract address
'0x...' // user address
);
const encryptValue = async () => {
const input = createInput();
input.add32(100);
const encrypted = await input.encrypt();
console.log('Encrypted:', encrypted);
};
return (
<button onClick={encryptValue}>
Encrypt Value
</button>
);
}import { Contract } from 'ethers';
import { encryptInput } from '@fhevm-sdk/core';
// Create encrypted input
const input = encryptInput(instance, contractAddress, userAddress);
input.add32(salary);
input.add32(bonus);
const encrypted = await input.encrypt();
// Send to contract
const contract = new Contract(contractAddress, abi, signer);
await contract.registerAthlete(
name,
position,
encrypted.handles[0],
encrypted.handles[1],
encrypted.inputProof
);import { userDecrypt } from '@fhevm-sdk/core';
// Get encrypted handle from contract
const encryptedSalary = await contract.getEncryptedSalary(athleteId);
// Decrypt (requires EIP-712 signature)
const decrypted = await userDecrypt(
instance,
encryptedSalary,
signer,
{
contractAddress,
userAddress,
}
);
console.log('Salary:', decrypted.toString());import { batchUserDecrypt } from '@fhevm-sdk/core';
// Get multiple encrypted values
const handles = [handle1, handle2, handle3];
// Decrypt all at once
const decrypted = await batchUserDecrypt(
instance,
handles,
signer,
{ contractAddress, userAddress }
);
console.log('Values:', decrypted.map(v => v.toString()));import { useEncryptedInput } from '@fhevm-sdk/core';
function MyComponent() {
const { createInput } = useEncryptedInput(contractAddress, userAddress);
const handleSubmit = async (value: number) => {
const input = createInput();
input.add32(value);
const encrypted = await input.encrypt();
// Use encrypted data
await contract.submitValue(encrypted);
};
return (
<button onClick={() => handleSubmit(42)}>
Submit Encrypted Value
</button>
);
}- Open MetaMask
- Click network dropdown
- Click "Add Network"
- Select "Sepolia" or add manually:
- Network Name: Sepolia
- RPC URL: https://sepolia.infura.io/v3/YOUR_KEY
- Chain ID: 11155111
- Currency: SepoliaETH
- Block Explorer: https://sepolia.etherscan.io
- Visit Sepolia Faucet
- Enter your wallet address
- Request test ETH
- Wait for confirmation
Solution: Install the dependency:
npm install @fhevm-sdk/core fhevmjs ethersSolution: Ensure you call init() before using the client:
await client.init(provider);Solution: Install MetaMask browser extension and reload the page.
Solution: Switch MetaMask to Sepolia testnet.
Solution: Add webpack config to next.config.js:
module.exports = {
webpack: (config) => {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
net: false,
tls: false,
};
return config;
},
};Solution: Ensure TypeScript 5.0+ and proper tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"lib": ["dom", "esnext"],
"module": "esnext",
"moduleResolution": "bundler",
"esModuleInterop": true
}
}After getting started:
- Read the Documentation: Check README.md for full API reference
- Explore Examples: See examples/nextjs-sports-contract
- Study the Contract: Review ConfidentialSportsContract.sol
- Watch the Demo: See DEMO_INSTRUCTIONS.md for video guide
- FHEVM Docs: https://docs.zama.ai/fhevm
- fhevmjs: https://github.com/zama-ai/fhevmjs
- Ethers.js: https://docs.ethers.org/v6/
- Zama: https://www.zama.ai/
Need help?
- Check README.md for detailed documentation
- Review example code
- Open an issue on GitHub
// Core
import { FhevmClient } from '@fhevm-sdk/core';
import { encryptInput } from '@fhevm-sdk/core';
import { userDecrypt, batchUserDecrypt } from '@fhevm-sdk/core';
// React
import { FhevmProvider } from '@fhevm-sdk/core';
import { useFhevmClient, useFhevmInit } from '@fhevm-sdk/core';
import { useEncryptedInput, useFhevmContract } from '@fhevm-sdk/core';
// Types
import type { FhevmClientConfig, EncryptedInput } from '@fhevm-sdk/core';// Client
const client = new FhevmClient(config);
await client.init(provider);
const instance = client.getInstance();
// Encryption
const input = encryptInput(instance, contractAddress, userAddress);
input.add32(value);
const encrypted = await input.encrypt();
// Decryption
const decrypted = await userDecrypt(instance, handle, signer, options);You're ready to build confidential dApps with FHEVM! 🚀
For more information, see the main README or explore the examples.