> ## Documentation Index
> Fetch the complete documentation index at: https://docs.streambird.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Switch Chains

Switch your user's embedded wallet to different EVM-compatible networks programmatically. MoonKey makes it easy to change networks for multi-chain applications.

## Overview

Switching chains allows your application to interact with different blockchain networks without requiring users to manually change networks. This is particularly useful for:

* **Multi-chain dApps**: Support operations across multiple networks
* **Network optimization**: Move to cheaper or faster chains for specific operations
* **Feature availability**: Access chain-specific protocols and features
* **User experience**: Seamlessly switch networks based on app context

## React SDK

### Basic Usage

To switch the network of an embedded wallet, use the `switchChain` method from the `useSwitchChain` hook:

<Tabs>
  <Tab title="Using useSwitchChain">
    ```tsx theme={null}
    import { useMoonKey } from '@moon-key/react-auth';
    import { useSwitchChain } from '@moon-key/react-auth/ethereum';

    function SwitchNetworkButton() {
      const { user } = useMoonKey();
      const { switchChain } = useSwitchChain();

      const handleSwitch = async () => {
        if (!user?.wallet) {
          alert('No wallet found');
          return;
        }

        try {
          // Switch to Base (chainId: 8453)
          await switchChain(8453);
          console.log('Switched to Base');
          alert('Network switched successfully!');
        } catch (error) {
          console.error('Failed to switch network:', error);
        }
      };

      return (
        <button onClick={handleSwitch}>
          Switch to Base
        </button>
      );
    }
    ```
  </Tab>

  <Tab title="Using Wallet Method">
    ```tsx theme={null}
    import { useMoonKey } from '@moon-key/react-auth';
    import { useWallets } from '@moon-key/react-auth/ethereum';

    function SwitchNetworkButton() {
      const { user } = useMoonKey();
      const { wallets } = useWallets();

      const handleSwitch = async () => {
        if (wallets.length === 0) {
          alert('No wallet found');
          return;
        }

        const wallet = wallets[0];

        try {
          // Switch to Optimism (chainId: 10)
          await wallet.switchChain(10);
          console.log('Switched to Optimism');
          alert('Network switched successfully!');
        } catch (error) {
          console.error('Failed to switch network:', error);
        }
      };

      return (
        <button onClick={handleSwitch}>
          Switch to Optimism
        </button>
      );
    }
    ```
  </Tab>
</Tabs>

### Chain ID Formats

The `switchChain` method accepts chain IDs in two formats:

```tsx theme={null}
// As a decimal number (recommended)
await switchChain(1); // Ethereum Mainnet

// As a hexadecimal string
await switchChain('0x1'); // Ethereum Mainnet
```

<Info>
  Using decimal numbers is recommended for better readability and consistency across your codebase.
</Info>

## Supported Chains

MoonKey supports switching to any EVM-compatible chain that has been configured in your app. Common networks include:

| Network           | Chain ID (Decimal) | Chain ID (Hex) |
| ----------------- | ------------------ | -------------- |
| Ethereum Mainnet  | 1                  | 0x1            |
| Sepolia Testnet   | 11155111           | 0xaa36a7       |
| Base              | 8453               | 0x2105         |
| Optimism          | 10                 | 0xa            |
| Arbitrum One      | 42161              | 0xa4b1         |
| Polygon           | 137                | 0x89           |
| Avalanche C-Chain | 43114              | 0xa86a         |
| BNB Smart Chain   | 56                 | 0x38           |

<Info>
  Learn how to configure additional networks in the [Configuring EVM Networks](/get-started/frontend-sdks/react/advanced/configure-evm-networks) guide.
</Info>

## Complete Examples

### Multi-Chain Network Selector

```tsx theme={null}
'use client';
import { useMoonKey } from '@moon-key/react-auth';
import { useSwitchChain } from '@moon-key/react-auth/ethereum';
import { useState } from 'react';

interface Network {
  name: string;
  chainId: number;
  logo: string;
}

const NETWORKS: Network[] = [
  { name: 'Ethereum', chainId: 1, logo: '🔷' },
  { name: 'Base', chainId: 8453, logo: '🔵' },
  { name: 'Optimism', chainId: 10, logo: '🔴' },
  { name: 'Arbitrum', chainId: 42161, logo: '🔷' },
  { name: 'Polygon', chainId: 137, logo: '🟣' }
];

export default function NetworkSelector() {
  const { user, isAuthenticated } = useMoonKey();
  const { switchChain } = useSwitchChain();
  const [currentChainId, setCurrentChainId] = useState<number>(1);
  const [isSwitching, setIsSwitching] = useState(false);

  const handleSwitchNetwork = async (chainId: number) => {
    if (!user?.wallet) {
      alert('Please connect your wallet first');
      return;
    }

    setIsSwitching(true);

    try {
      await switchChain(chainId);
      setCurrentChainId(chainId);
      console.log(`Switched to chain ${chainId}`);
    } catch (error) {
      console.error('Failed to switch network:', error);
      alert('Failed to switch network. Please try again.');
    } finally {
      setIsSwitching(false);
    }
  };

  if (!isAuthenticated) {
    return <p>Please sign in to switch networks</p>;
  }

  return (
    <div className="network-selector">
      <h2>Select Network</h2>
      
      <div className="networks-grid">
        {NETWORKS.map((network) => (
          <button
            key={network.chainId}
            onClick={() => handleSwitchNetwork(network.chainId)}
            disabled={isSwitching || currentChainId === network.chainId}
            className={`network-button ${
              currentChainId === network.chainId ? 'active' : ''
            }`}
          >
            <span className="network-logo">{network.logo}</span>
            <span className="network-name">{network.name}</span>
            {currentChainId === network.chainId && <span>✓</span>}
          </button>
        ))}
      </div>

      {isSwitching && <p className="switching-text">Switching network...</p>}
    </div>
  );
}
```

### Network Switch with Confirmation

```tsx theme={null}
'use client';
import { useMoonKey } from '@moon-key/react-auth';
import { useSwitchChain } from '@moon-key/react-auth/ethereum';
import { useState } from 'react';

export default function NetworkSwitchWithConfirmation() {
  const { user } = useMoonKey();
  const { switchChain } = useSwitchChain();
  const [showConfirmation, setShowConfirmation] = useState(false);
  const [targetChain, setTargetChain] = useState<{ id: number; name: string } | null>(null);

  const requestNetworkSwitch = (chainId: number, chainName: string) => {
    setTargetChain({ id: chainId, name: chainName });
    setShowConfirmation(true);
  };

  const confirmSwitch = async () => {
    if (!user?.wallet || !targetChain) return;

    try {
      await switchChain(targetChain.id);
      alert(`Successfully switched to ${targetChain.name}`);
    } catch (error) {
      console.error('Failed to switch:', error);
      alert('Failed to switch network');
    } finally {
      setShowConfirmation(false);
      setTargetChain(null);
    }
  };

  const cancelSwitch = () => {
    setShowConfirmation(false);
    setTargetChain(null);
  };

  return (
    <div className="network-switch">
      <button onClick={() => requestNetworkSwitch(8453, 'Base')}>
        Switch to Base
      </button>

      {showConfirmation && targetChain && (
        <div className="confirmation-modal">
          <div className="modal-content">
            <h3>Switch Network?</h3>
            <p>
              You are about to switch to <strong>{targetChain.name}</strong> (Chain ID: {targetChain.id})
            </p>
            <p>This will change your wallet's active network.</p>
            <div className="modal-actions">
              <button onClick={confirmSwitch} className="confirm-btn">
                Confirm
              </button>
              <button onClick={cancelSwitch} className="cancel-btn">
                Cancel
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
```

## Error Handling

Handle common errors when switching chains:

```tsx theme={null}
import { useMoonKey } from '@moon-key/react-auth';
import { useSwitchChain } from '@moon-key/react-auth/ethereum';

function SafeNetworkSwitch() {
  const { user } = useMoonKey();
  const { switchChain } = useSwitchChain();

  const handleSwitch = async (chainId: number) => {
    if (!user?.wallet) {
      alert('No wallet connected');
      return;
    }

    try {
      await switchChain(chainId);
      console.log('Network switched successfully');
    } catch (error: any) {
      // Handle specific error cases
      if (error.code === 'CHAIN_NOT_CONFIGURED') {
        alert(
          'This network is not configured. Please add it in your app settings.'
        );
      } else if (error.code === 'USER_REJECTED') {
        console.log('User cancelled network switch');
      } else if (error.message?.includes('unsupported')) {
        alert('This chain is not supported by MoonKey');
      } else {
        console.error('Unexpected error:', error);
        alert('Failed to switch network: ' + error.message);
      }
    }
  };

  return (
    <button onClick={() => handleSwitch(8453)}>
      Switch Network
    </button>
  );
}
```

## Getting Current Chain

To get the current chain ID of the wallet:

```tsx theme={null}
import { useMoonKey } from '@moon-key/react-auth';
import { useWallets } from '@moon-key/react-auth/ethereum';

function CurrentChainDisplay() {
  const { user } = useMoonKey();
  const { wallets } = useWallets();

  if (!user?.wallet || wallets.length === 0) {
    return <p>No wallet connected</p>;
  }

  const wallet = wallets[0];
  const currentChainId = wallet.chainId;

  return (
    <div className="current-chain">
      <p>Current Chain ID: {currentChainId}</p>
      <p>Current Chain: {getChainName(currentChainId)}</p>
    </div>
  );
}

function getChainName(chainId: number): string {
  const chains: Record<number, string> = {
    1: 'Ethereum Mainnet',
    11155111: 'Sepolia Testnet',
    8453: 'Base',
    10: 'Optimism',
    42161: 'Arbitrum One',
    137: 'Polygon'
  };

  return chains[chainId] || `Chain ${chainId}`;
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Configure chains before switching">
    Ensure chains are properly configured in your `MoonKeyProvider`:

    ```tsx theme={null}
    import { MoonKeyProvider } from '@moon-key/react-auth';
    import { mainnet, base, optimism, arbitrum } from 'viem/chains';

    <MoonKeyProvider
      publishableKey="your-moonkey-publishableKey"
      config={{
        chains: [mainnet, base, optimism, arbitrum]
      }}
    >
      {children}
    </MoonKeyProvider>
    ```
  </Accordion>

  <Accordion title="Provide clear user feedback">
    Always inform users when switching networks:

    ```tsx theme={null}
    const handleSwitch = async (chainId: number, chainName: string) => {
      // Show loading state
      setIsLoading(true);
      setStatusMessage(`Switching to ${chainName}...`);

      try {
        await switchChain(chainId);
        setStatusMessage(`Successfully switched to ${chainName}`);
      } catch (error) {
        setStatusMessage('Failed to switch network');
      } finally {
        setIsLoading(false);
      }
    };
    ```
  </Accordion>

  <Accordion title="Handle chain-specific features gracefully">
    Check chain compatibility before enabling features:

    ```tsx theme={null}
    const isFeatureAvailable = (chainId: number): boolean => {
      const supportedChains = [1, 8453, 10]; // Mainnet, Base, Optimism
      return supportedChains.includes(chainId);
    };

    if (!isFeatureAvailable(currentChainId)) {
      return (
        <div>
          <p>This feature is not available on this network</p>
          <button onClick={() => switchChain(8453)}>
            Switch to Base
          </button>
        </div>
      );
    }
    ```
  </Accordion>

  <Accordion title="Use descriptive chain names">
    Display human-readable names instead of chain IDs:

    ```tsx theme={null}
    const CHAIN_NAMES: Record<number, string> = {
      1: 'Ethereum',
      8453: 'Base',
      10: 'Optimism',
      42161: 'Arbitrum'
    };

    <button onClick={() => switchChain(8453)}>
      Switch to {CHAIN_NAMES[8453]}
    </button>
    ```
  </Accordion>

  <Accordion title="Validate chain before operations">
    Ensure correct network before executing transactions:

    ```tsx theme={null}
    const executeTransaction = async (targetChainId: number) => {
      const currentChainId = wallet.chainId;

      // Check if we're on the right chain
      if (currentChainId !== targetChainId) {
        const confirmed = confirm(
          `This operation requires switching to chain ${targetChainId}. Continue?`
        );

        if (!confirmed) return;

        // Switch to correct chain
        await switchChain(targetChainId);
      }

      // Now execute the transaction
      await sendTransaction({ ... });
    };
    ```
  </Accordion>

  <Accordion title="Handle network switch failures gracefully">
    Provide fallback options when switching fails:

    ```tsx theme={null}
    const handleCriticalOperation = async (requiredChainId: number) => {
      try {
        await switchChain(requiredChainId);
        await performOperation();
      } catch (error) {
        // Offer alternative if switch fails
        const useAlternative = confirm(
          'Failed to switch network. Use alternative chain?'
        );

        if (useAlternative) {
          await switchChain(alternativeChainId);
          await performOperation();
        }
      }
    };
    ```
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Chain not configured error">
    If you get a "chain not configured" error, add the chain to your configuration:

    ```tsx theme={null}
    // Add the chain to your MoonKeyProvider
    import { MoonKeyProvider } from '@moon-key/react-auth';
    import { base } from 'viem/chains';

    <MoonKeyProvider
      publishableKey="your-moonkey-publishableKey"
      config={{
        chains: [base] // Add your required chains here
      }}
    >
      {children}
    </MoonKeyProvider>
    ```

    See [Configuring EVM Networks](/get-started/frontend-sdks/react/advanced/configure-evm-networks) for more details.
  </Accordion>

  <Accordion title="Switch not taking effect">
    If the network doesn't seem to switch:

    1. **Check wallet state**: Ensure wallet is connected
    2. **Wait for promise**: Make sure to await the `switchChain` call
    3. **Verify chain support**: Check if the chain is configured
    4. **Check for errors**: Look for error messages in console

    ```tsx theme={null}
    const handleSwitch = async (chainId: number) => {
      console.log('Current chain:', wallet.chainId);
      
      try {
        await switchChain(chainId);
        console.log('Switch successful');
        console.log('New chain:', wallet.chainId);
      } catch (error) {
        console.error('Switch failed:', error);
      }
    };
    ```
  </Accordion>

  <Accordion title="Multiple rapid switches">
    Avoid switching chains multiple times in quick succession:

    ```tsx theme={null}
    let isSwitching = false;

    const handleSwitch = async (chainId: number) => {
      if (isSwitching) {
        console.log('Already switching chains, please wait');
        return;
      }

      isSwitching = true;

      try {
        await switchChain(chainId);
      } catch (error) {
        console.error('Switch failed:', error);
      } finally {
        isSwitching = false;
      }
    };
    ```
  </Accordion>

  <Accordion title="Hex vs decimal chain IDs">
    If switching with hex strings isn't working, use decimal numbers:

    ```tsx theme={null}
    // ✅ Recommended - use decimal
    await switchChain(8453);

    // ⚠️ Use hex only if required by your setup
    await switchChain('0x2105');
    ```
  </Accordion>
</AccordionGroup>

## Related Documentation

<CardGroup cols={2}>
  <Card title="Configure EVM Networks" icon="network-wired" href="/get-started/frontend-sdks/react/advanced/configure-evm-networks">
    Add and configure custom EVM networks
  </Card>

  <Card title="Send Transaction" icon="paper-plane" href="/wallet-as-a-service/using-wallets/ethereum/send-transaction">
    Send transactions on different chains
  </Card>

  <Card title="Get User Wallets" icon="wallet" href="/wallet-as-a-service/embedded-wallets/get-a-wallet/get-user-connected-wallets">
    Access wallet information and chain details
  </Card>

  <Card title="Viem Chains" icon="link" href="https://viem.sh/docs/chains/introduction">
    Explore available chain configurations
  </Card>
</CardGroup>

## Next Steps

* Learn how to [configure custom EVM networks](/get-started/frontend-sdks/react/advanced/configure-evm-networks)
* Understand [multi-chain wallet management](/wallet-as-a-service/embedded-wallets/get-a-wallet/get-user-connected-wallets)
* Explore [chain-specific RPC configurations](https://viem.sh/docs/clients/transports/http)
* Implement [cross-chain transaction flows](/wallet-as-a-service/using-wallets/ethereum/send-transaction)
