Skip to content

Chain Switching

Manage network chains in your Mini App, including detecting the current chain and handling chain mismatches.

Supported Chains

MiniPay supports the following Celo networks:

  • Celo Mainnet (Chain ID: 42220)
  • Celo Sepolia Testnet (Chain ID: 11142220)

MiniPay does not currently support programmatic chain switching. The wagmi useSwitchChain hook will not work inside MiniPay.

Chain Configuration

Configure your Wagmi config with supported chains:

ts
import { http } from "viem";
import { createConfig } from "wagmi";
import { injected } from "wagmi/connectors";
import { celo, celoSepolia } from "wagmi/chains";

export const config = createConfig({
  chains: [celo, celoSepolia],
  connectors: [injected()],
  transports: {
    [celo.id]: http(),
    [celoSepolia.id]: http(),
  },
});

Detect Current Chain

Use useChainId to get the current chain ID and derive a display name or helper. You can also react to chain changes (e.g. refresh data) in a useEffect that depends on chainId:

tsx
import { useEffect } from "react";
import { useChainId } from "wagmi";
import { celo, celoSepolia } from "wagmi/chains";

const CHAIN_NAMES: Record<number, string> = {
  [celo.id]: "Celo Mainnet",
  [celoSepolia.id]: "Celo Sepolia",
};

function CurrentChain() {
  const chainId = useChainId();
  const chainName = CHAIN_NAMES[chainId] ?? "Unknown";
  const isMainnet = chainId === celo.id;
  const isTestnet = chainId === celoSepolia.id;

  useEffect(() => {
    // Optional: react to chain changes (refresh data, update UI)
    console.log("Chain:", chainId);
  }, [chainId]);

  return (
    <div>
      <p>Current Chain: {chainName}</p>
      <p>Chain ID: {chainId}</p>
      {!isMainnet && !isTestnet && <p>This app requires Celo Mainnet or Celo Sepolia.</p>}
    </div>
  );
}

Handle Chain Mismatches

When the user is on the wrong chain, detect it with useChainId() and show a clear message. MiniPay does not support chain switching; the pattern below is for detection and messaging only.

tsx
import { useChainId } from "wagmi";
import { celo, celoSepolia } from "wagmi/chains";

const SUPPORTED_CHAINS = [celo.id, celoSepolia.id];

function useIsChainSupported() {
  const chainId = useChainId();
  return SUPPORTED_CHAINS.includes(chainId);
}

function ChainMismatchMessage() {
  const isSupported = useIsChainSupported();

  if (isSupported) {
    return null;
  }

  return (
    <div className="chain-mismatch">
      <p>This app requires Celo Mainnet or Celo Sepolia. You are currently on an unsupported network.</p>
    </div>
  );
}

Chain-Specific Addresses

Token and contract addresses differ between mainnet and testnet. Use a Record<chainId, Address> (or nested record for multiple tokens) and useChainId():

tsx
import { useChainId } from "wagmi";
import { celo, celoSepolia } from "wagmi/chains";
import type { Address } from "viem";

// Example: one contract per chain
const CONTRACT_ADDRESSES: Record<number, Address> = {
  [celo.id]: "0x..." as Address, // Mainnet
  [celoSepolia.id]: "0x..." as Address, // Testnet
};

// Example: multiple tokens per chain
const TOKEN_ADDRESSES: Record<number, Record<string, Address>> = {
  [celo.id]: {
    USDC: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
    USDm: "0x765DE816845861e75A25fCA122bb6898B8B1282a",
  },
  [celoSepolia.id]: {
    USDC: "0x01C5C0122039549AD1493B8220cABEdD739BC44E",
    USDm: "0xEF4d55D6dE8e8d73232827Cd1e9b2F2dBb45bC80",
  },
};

function useTokenAddress(symbol: "USDC" | "USDm") {
  const chainId = useChainId();
  return TOKEN_ADDRESSES[chainId]?.[symbol];
}

Best Practices

  1. Always check chain ID: Verify the user is on the expected network before making transactions
  2. Use chain-specific addresses: Token and contract addresses differ between mainnet and testnet
  3. Handle chain mismatches: Detect when the user is on an unsupported chain and show a clear message (MiniPay does not support programmatic chain switching)
  4. Monitor chain changes: Update your app state when the user switches networks
  5. Test on both networks: Ensure your app works correctly on both mainnet and testnet

Common Issues

  • Wrong network: Detect when chainId is not celo.id or celoSepolia.id and show a message that the app requires Celo Mainnet or Celo Sepolia. Do not rely on chain switching in MiniPay—it is not supported.
  • Unsupported chain: Check [celo.id, celoSepolia.id].includes(chainId) and show a fallback or redirect.

Next Steps