Configuration
How to configure the SDK with createConfig — chains, relayers, provider, signer, and storage.
The SDK uses createConfig to wire together chains, relayers, a provider, an optional signer, and storage into a single configuration object. This guide walks through each piece.
Steps
1. Pick your chains
Import pre-configured chain objects from @zama-fhe/sdk/chains. Each chain includes contract addresses, relayer URLs, and chain IDs.
import { sepolia, mainnet, hoodi } from "@zama-fhe/sdk/chains";mainnet
1
Ethereum Mainnet
sepolia
11155111
Sepolia Testnet
hoodi
560048
Hoodi Testnet
ingenTestnet
364301
InGen Testnet
bscTestnet
97
BNB Smart Chain Testnet
hardhat
31337
Local Hardhat node
anvil is also exported as an alias for hardhat (both target chain ID 31337), for Foundry users.
The Sepolia testnet relayer needs no API key — presets like sepolia work as-is, so leave auth unset. Only the Zama-hosted mainnet relayer requires a key; see Authentication.
2. Pick a relayer
Relayers tell the SDK how to run FHE operations on each chain.
web()
Browser
Runs WASM in a Web Worker via CDN
node()
Node.js
Uses native worker threads
cleartext()
Local dev
No FHE infrastructure — cleartext operations
Chain-specific data (relayerUrl, network, executorAddress, etc.) comes from the chain preset. The relayer factory only accepts pool/worker options.
If you need to override a chain field (e.g. proxy relayer requests through your backend), spread the preset in the chains array:
3. Set up chain access
The SDK separates read access (provider) from wallet authority (signer). The provider handles contract reads and receipt polling. The signer handles signing and write transactions. Both are created automatically by createConfig — you pass your Web3 library's native objects.
For full type information, see the ViemProvider / ViemSigner and EthersProvider / EthersSigner reference pages. You can also implement GenericProvider and GenericSigner for a custom integration.
4. Create the config
createConfig takes your chains, relayers, and signer adapter and returns a config object.
When the built-in adapters don't fit your setup — for example, a server-side relayer that implements GenericSigner directly — use the generic createConfig from @zama-fhe/sdk:
See GenericSigner and GenericProvider for the interfaces your adapter must implement.
MV3 Chrome extensions can use chromeSessionStorage as permitStorage so permits survive service worker restarts:
Your manifest.json must include the "storage" permission. See the Web Extensions guide for manifest configuration, multi-context sharing, and browser close behavior.
Browser apps should proxy relayer requests through a backend to keep the API key secret. See the Authentication guide for the full setup.
5. (Optional) Configure TTLs and event listener
You can tune how long the transport key pair and permits remain valid, and subscribe to lifecycle events for debugging:
When done with the SDK, call sdk.terminate() to clean up the Web Worker or thread pool.
6. (Optional) Choose a storage backend
The transport key pair is cached so users don't get a wallet popup on every decrypt. By default, createConfig picks the right storage for your environment. Override with the storage field if needed:
indexedDBStorage
Browser apps — persists across reloads and sessions
memoryStorage
Tests, scripts, throwaway sessions
asyncLocalStorage
Node.js servers — isolates transport key pair per request
For full storage options see the GenericStorage reference.
7. (Optional) Supply a logger
The SDK is silent by default — it emits no console output of its own. Operation failures always surface through the rejected promise or typed error, never as a stray console.error. To observe internal diagnostics, pass a logger to createConfig:
The logger is a minimal four-level interface — error, warn, info, debug — that console and common logging libraries satisfy directly, so no adapter is needed. The SDK never bundles a logging library or imposes a format; level filtering is left to your logger. Levels follow these conventions:
error
Unexpected internal failures only — never failures already surfaced via a rejection
warn
Recoverable or degraded conditions (a fallback path, a retry, a swallowed best-effort write)
info
Reserved for coarse lifecycle milestones; not currently emitted
debug
Verbose diagnostics — worker lifecycle, request timing, orchestration progress
The logger is configured once here and flows SDK-wide — including into worker request tracing, the credential store, and the artifact cache. There is deliberately no per-relayer logger option; createConfig({ logger }) is the single source of truth.
Shared relayer options
When multiple chains use the same relayer, create it once and reference that single instance from each chain:
Chains that reference the same relayer object — the result of a single web() call — share one worker, reducing memory usage.
Next steps
Authentication — set up a backend proxy or use a direct API key
Shield Tokens — convert public ERC-20 tokens into confidential form
Chain Objects — pre-configured chain definitions for Sepolia, Mainnet, and more
GenericStorage reference — custom storage implementations
Last updated