Check existing issues
Describe the bug
There is an inconsistency in the behavior of switchChainAsync when used with MetaMask. The function resolves before the actual chain switch is completed, leading to a mismatch between the Promise resolution and the actual chain state.
Key observations:
-
Timing:
switchChainAsync resolves immediately after sending the request to MetaMask
- The actual chain switch in MetaMask happens several seconds later
- This creates a gap between Promise resolution and chain switch completion
-
State Management:
- UI updates show the new chain immediately
- Hook values (
useChainId, useAccount) maintain previous chain values
- Console logs demonstrate the state mismatch during the switch process
Link to Minimal Reproducible Example
https://stackblitz.com/edit/new-wagmi-hrpyucft?file=src%2FApp.tsx
Steps To Reproduce
import { useState, useEffect } from 'react';
import { useChainId, useSwitchChain, useAccount } from 'wagmi';
import { arbitrum, base } from 'wagmi/chains';
export default function App() {
const chainId = useChainId();
const { chain: accountChain } = useAccount();
const { switchChainAsync } = useSwitchChain();
const [isLoading, setIsLoading] = useState(false);
// Monitor chain changes
useEffect(() => {
console.log('Chain ID from useChainId:', chainId);
console.log('Chain ID from useAccount:', accountChain?.id);
}, [chainId, accountChain]);
const testAsyncBehavior = async (targetChainId: number) => {
console.log('=== Test Async Behavior Start ===');
console.log('T0 - Initial state:');
console.log('- ChainId from useChainId:', chainId);
console.log('- ChainId from useAccount:', accountChain?.id);
const switchPromise = switchChainAsync({ chainId: targetChainId });
console.log('T1 - Switch request sent to wallet');
const result = await switchPromise;
console.log('T3 - switchChainAsync resolved with:', result);
console.log('T4 - State after await:');
console.log('- ChainId from useChainId:', chainId);
console.log('- ChainId from useAccount:', accountChain?.id);
return result;
};
const handleSwitchChain = async () => {
try {
setIsLoading(true);
if (!chainId) return;
const targetChainId = chainId === base.id ? arbitrum.id : base.id;
await testAsyncBehavior(targetChainId);
} catch (error) {
console.error('Chain switch error:', error);
} finally {
setTimeout(() => {
if (isLoading) setIsLoading(false);
}, 5000);
}
};
return (
<div>
<button onClick={handleSwitchChain} disabled={isLoading}>
{isLoading
? 'Switching...'
: `Switch to ${chainId === base.id ? 'Arbitrum' : 'Base'}`}
</button>
<div>
<p>Current Chain (useChainId): {chainId === base.id ? 'Base' : 'Arbitrum'}</p>
<p>Current Chain (useAccount): {accountChain?.id === base.id ? 'Base' : 'Arbitrum'}</p>
</div>
</div>
);
}
Console output showing the issue:
=== Test Async Behavior Start ===
T0 - Initial state:
- ChainId from useChainId: 8453
- ChainId from useAccount: 8453
T1 - Switch request sent to wallet
T3 - switchChainAsync resolved with: {id: 42161, name: 'Arbitrum One', ...}
T4 - State after await:
- ChainId from useChainId: 8453 // Still showing old chain
- ChainId from useAccount: 8453 // Still showing old chain
What Wagmi package(s) are you using?
wagmi
Wagmi Package(s) Version(s)
wagmi@2.14.15
Viem Version
2.24.1
TypeScript Version
5.7.3
Anything else?
Using:
- MetaMask as wallet
- Testing performed with Base (8453) and Arbitrum (42161) networks
The issue affects the reliability of chain-switching logic in dApps, as developers cannot depend on the Promise resolution to accurately reflect the actual chain state.
Check existing issues
Describe the bug
There is an inconsistency in the behavior of
switchChainAsyncwhen used with MetaMask. The function resolves before the actual chain switch is completed, leading to a mismatch between the Promise resolution and the actual chain state.Key observations:
Timing:
switchChainAsyncresolves immediately after sending the request to MetaMaskState Management:
useChainId,useAccount) maintain previous chain valuesLink to Minimal Reproducible Example
https://stackblitz.com/edit/new-wagmi-hrpyucft?file=src%2FApp.tsx
Steps To Reproduce
Console output showing the issue:
What Wagmi package(s) are you using?
wagmi
Wagmi Package(s) Version(s)
wagmi@2.14.15
Viem Version
2.24.1
TypeScript Version
5.7.3
Anything else?
Using:
The issue affects the reliability of chain-switching logic in dApps, as developers cannot depend on the Promise resolution to accurately reflect the actual chain state.