|
| 1 | +import { useAppKitNetwork } from '@reown/appkit/react' |
| 2 | +import { useEffect, useState } from 'react' |
| 3 | +import { |
| 4 | + getConfiguredChainId, |
| 5 | + getConfiguredNetwork, |
| 6 | + getConfiguredNetworkName, |
| 7 | + isCorrectNetwork, |
| 8 | +} from '~lib/network-config' |
| 9 | +import { useUnifiedWallet } from './use-unified-wallet' |
| 10 | + |
| 11 | +export interface NetworkValidationState { |
| 12 | + isCorrectNetwork: boolean |
| 13 | + isValidating: boolean |
| 14 | + isSwitching: boolean |
| 15 | + error: Error | null |
| 16 | + requiredChainId: number |
| 17 | + requiredNetworkName: string |
| 18 | + currentChainId: number | undefined |
| 19 | + switchToCorrectNetwork: () => Promise<void> |
| 20 | +} |
| 21 | + |
| 22 | +/** |
| 23 | + * Hook to validate and manage network switching for the connected wallet |
| 24 | + * Ensures the wallet is connected to the correct network as configured |
| 25 | + */ |
| 26 | +export function useNetworkValidation(): NetworkValidationState { |
| 27 | + const { isConnected } = useUnifiedWallet() |
| 28 | + const { chainId, switchNetwork } = useAppKitNetwork() |
| 29 | + const [isValidating, setIsValidating] = useState(false) |
| 30 | + const [isSwitching, setIsSwitching] = useState(false) |
| 31 | + const [error, setError] = useState<Error | null>(null) |
| 32 | + |
| 33 | + const requiredChainId = getConfiguredChainId() |
| 34 | + const requiredNetworkName = getConfiguredNetworkName() |
| 35 | + const currentChainId = chainId ? Number(chainId) : undefined |
| 36 | + const isOnCorrectNetwork = currentChainId ? isCorrectNetwork(currentChainId) : false |
| 37 | + |
| 38 | + // Validate network when connection state changes |
| 39 | + useEffect(() => { |
| 40 | + if (isConnected && currentChainId) { |
| 41 | + setIsValidating(true) |
| 42 | + const isValid = isCorrectNetwork(currentChainId) |
| 43 | + setIsValidating(false) |
| 44 | + |
| 45 | + if (!isValid) { |
| 46 | + console.warn( |
| 47 | + `Wallet connected to wrong network. Expected: ${requiredNetworkName} (${requiredChainId}), Got: ${currentChainId}` |
| 48 | + ) |
| 49 | + } |
| 50 | + } |
| 51 | + }, [isConnected, currentChainId, requiredChainId, requiredNetworkName]) |
| 52 | + |
| 53 | + /** |
| 54 | + * Switch the wallet to the correct network |
| 55 | + */ |
| 56 | + const switchToCorrectNetwork = async () => { |
| 57 | + if (!isConnected) { |
| 58 | + throw new Error('Wallet not connected') |
| 59 | + } |
| 60 | + |
| 61 | + if (isOnCorrectNetwork) { |
| 62 | + return // Already on correct network |
| 63 | + } |
| 64 | + |
| 65 | + setIsSwitching(true) |
| 66 | + setError(null) |
| 67 | + |
| 68 | + try { |
| 69 | + // Get the configured network object |
| 70 | + const network = getConfiguredNetwork() |
| 71 | + |
| 72 | + // Use AppKit's switchNetwork function |
| 73 | + await switchNetwork(network) |
| 74 | + |
| 75 | + console.info(`Successfully switched to ${requiredNetworkName}`) |
| 76 | + } catch (err) { |
| 77 | + const error = err as Error |
| 78 | + console.error('Failed to switch network:', error) |
| 79 | + |
| 80 | + // Provide user-friendly error messages |
| 81 | + if (error.message?.includes('rejected') || error.message?.includes('denied')) { |
| 82 | + setError(new Error('Network switch was rejected. Please try again.')) |
| 83 | + } else if (error.message?.includes('not supported')) { |
| 84 | + setError( |
| 85 | + new Error( |
| 86 | + `Your wallet doesn't support ${requiredNetworkName}. Please add it manually or use a different wallet.` |
| 87 | + ) |
| 88 | + ) |
| 89 | + } else { |
| 90 | + setError(new Error(`Failed to switch network: ${error.message}`)) |
| 91 | + } |
| 92 | + |
| 93 | + throw error |
| 94 | + } finally { |
| 95 | + setIsSwitching(false) |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + return { |
| 100 | + isCorrectNetwork: isOnCorrectNetwork, |
| 101 | + isValidating, |
| 102 | + isSwitching, |
| 103 | + error, |
| 104 | + requiredChainId, |
| 105 | + requiredNetworkName, |
| 106 | + currentChainId, |
| 107 | + switchToCorrectNetwork, |
| 108 | + } |
| 109 | +} |
0 commit comments