import { useContext, useCallback, useState, useEffect } from 'react'
import { ConnectionContext } from '../providers/ConnectionProvider'
import type {
NetworkId,
UseSwitchNetworkReturn,
WalletError
} from '@meshconnect/uwc-types'
/**
* Hook for switching networks on the connected wallet
* @returns Network switching function and loading states
* @throws Error if used outside of ConnectionProvider
* @example
* ```tsx
* const { switchNetwork, isLoading, isWaitingForUserApproval } = useSwitchNetwork()
*
* const handleSwitch = async () => {
* try {
* await switchNetwork('eip155:8453') // Switch to Base
* } catch (error) {
* console.error('Network switch failed:', error)
* }
* }
*
* // Show loading UI
* if (isWaitingForUserApproval) {
* return
Please approve in your wallet...
* }
* if (isLoading) {
* return Switching network...
* }
* ```
*/
export function useSwitchNetwork(): UseSwitchNetworkReturn {
const context = useContext(ConnectionContext)
if (!context) {
throw new Error('useSwitchNetwork must be used within a ConnectionProvider')
}
const { connector } = context
const [isLoading, setIsLoading] = useState(false)
const [isWaitingForUserApproval, setIsWaitingForUserApproval] =
useState(false)
const [error, setError] = useState()
// Subscribe to loading state changes from the core
useEffect(() => {
const updateLoadingState = () => {
const state = connector.getNetworkSwitchLoadingState()
setIsLoading(state.isLoading)
setIsWaitingForUserApproval(state.isWaitingForUserApproval)
}
// Check initial state
updateLoadingState()
// Subscribe to changes
const unsubscribe = connector.subscribe(updateLoadingState)
return unsubscribe
}, [connector])
const switchNetwork = useCallback(
async (networkId: NetworkId) => {
setError(undefined)
try {
await connector.switchNetwork(networkId)
} catch (err) {
const walletError = err as WalletError
setError(walletError)
throw err
}
},
[connector]
)
return {
switchNetwork,
isLoading,
isWaitingForUserApproval,
error
}
}