Handling Chain Switches

We help you handling network changes.

Some routes require a network switch in the end-users wallet during execution. This need arises when the route first bridges a token to another chain and subsequently wants to swap it into the final output token using an exchange. Since that last swap requires sending a transaction to an external contract, a renewed Signer for the new chain is necessary. The LI.FI SDK can no longer use the initial Signer passed to the executeRoute or resumeRoute functions since they point to another chain.

The ExecutionSettings you can pass to the executeRoute function allows you to pass a switchChainHook. This hook is called every time such a chain switch is needed. It gives you the chain id of the required chain and expects a Signer for the new chain.

interface ExecutionSettings {
  // ...
  switchChainHook?: SwitchChainHook
}

type SwitchChainHook = (
  requiredChainId: number
) => Promise<Signer | undefined>

The execution fails if a chain switch is needed and you are not providing a new signer. In that case, you can resume the route with resumeRoute and the new Signer. The same applies if you haven't provided a switchChainHook in the first place.

Example code snippet: MetaMask

The code snippet below shows how to handle a chain switch with the MetaMask browser extension.

// ... prepare a transfer ...

// define the switchChainHook
const switchChainHook = (requiredChainId: number) => {
    // this is where MetaMask lives
    const ethereum = (window as any).ethereum 
    
    // check if MetaMask is available
    if (typeof ethereum === 'undefined') return
    
    // use the MetaMask RPC API to switch chains automatically
    await ethereum.request({
      method: 'wallet_switchEthereumChain',
      params: [{ chainId: requiredChainId }],
    })
    
    // build a new provider for the new chain
    const newProvider = new ethers.providers.Web3Provider(window.ethereum)
    
    // return the associated Signer
    return newProvider.getSigner()
}

// execute the route
const route = await lifi.executeRoute(signer, chosenRoute, { switchChainHook })

Last updated