Switch via wagmi#
useSwitchChain is the wagmi primitive. It prompts the wallet UI; once resolved, every wagmi-aware hook (and every SDK hook layered on top) sees the new chain.
import { useSwitchChain, useChainId } from "wagmi";
import { sepolia, mainnet } from "viem/chains";
export function ChainSwitch() {
const chainId = useChainId();
const { switchChain, isPending } = useSwitchChain();
return (
<select
value={chainId}
onChange={(e) => switchChain({ chainId: Number(e.target.value) })}
disabled={isPending}
>
<option value={sepolia.id}>Sepolia</option>
<option value={mainnet.id}>Mainnet</option>
</select>
);
}Guard your writes#
Writes that target a specific deployment (a manager address valid only on Sepolia, etc.) should explicitly gate on useChainId. Submitting a Sepolia-only contract call while the wallet is on mainnet either reverts or succeeds against a stale address, neither is a good UX.
import { useChainId } from "wagmi";
import { sepolia } from "viem/chains";
import { useCreateVesting } from "@tokenops/sdk/fhe-vesting/react";
export function CreateButton() {
const chainId = useChainId();
const create = useCreateVesting({ address: managerAddress });
if (chainId !== sepolia.id) {
return <span>Switch to Sepolia first.</span>;
}
// Safe to proceed, useCreateVesting hits the chain wagmi is on.
return <button onClick={() => create.mutate(args)}>Create</button>;
}Anvil locally#
Anvil (chain id 31337) isn't in DEPLOYED_ADDRESSES, it comes from .cache/local-deploys.json after pnpm fhevm:deploy. The docs-site reads that via /api/local-deploys; a consumer repo can replicate the pattern or hardcode addresses for tests.