UNPKG

@openocean.finance/widget-sdk

Version:

OpenOcean Any-to-Any Cross-Chain-Swap SDK

92 lines (85 loc) 2.87 kB
import type { Client, GetChainIdReturnType } from 'viem' import { getChainId } from 'viem/actions' import { getAction } from 'viem/utils' import { OpenOceanErrorCode } from '../../errors/constants.js' import { ProviderError } from '../../errors/errors.js' import type { StatusManager } from '../StatusManager.js' import type { OpenOceanStepExtended, SwitchChainHook } from '../types.js' /** * This method checks whether the wallet client is configured for the correct chain. * If yes it returns the wallet clien. * If no and if user interaction is allowed it triggers the switchChainHook. If no user interaction is allowed it aborts. * * Account Type: local - * We need to create and return a new connector client from the switchChainHook in order to continue execution on a new chain. * * Account Type: json-rpc - * We can switch chain and return existing connector client from the switchChainHook in order to continue execution on a new chain. * @param client * @param statusManager * @param step * @param switchChainHook * @param allowUserInteraction * @returns New connector client */ export const switchChain = async ( client: Client, statusManager: StatusManager, step: OpenOceanStepExtended, allowUserInteraction: boolean, switchChainHook?: SwitchChainHook ): Promise<Client | undefined> => { // if we are already on the correct chain we can proceed directly const currentChainId = (await getAction( client, getChainId, 'getChainId' )(undefined)) as GetChainIdReturnType if (currentChainId === step.action.fromChainId) { return client } // -> set status message step.execution = statusManager.initExecutionObject(step) statusManager.updateExecution(step, 'ACTION_REQUIRED') let switchProcess = statusManager.findOrCreateProcess({ step, type: 'SWITCH_CHAIN', status: 'ACTION_REQUIRED', }) if (!allowUserInteraction) { return } try { const updatedClient = await switchChainHook?.(step.action.fromChainId) let updatedChainId: number | undefined if (updatedClient) { updatedChainId = (await getAction( updatedClient, getChainId, 'getChainId' )(undefined)) as GetChainIdReturnType } if (updatedChainId !== step.action.fromChainId) { throw new ProviderError( OpenOceanErrorCode.ChainSwitchError, 'Chain switch required.' ) } switchProcess = statusManager.updateProcess( step, switchProcess.type, 'DONE' ) statusManager.updateExecution(step, 'PENDING') return updatedClient } catch (error: any) { statusManager.updateProcess(step, switchProcess.type, 'FAILED', { error: { message: error.message, code: OpenOceanErrorCode.ChainSwitchError, }, }) statusManager.updateExecution(step, 'FAILED') throw error } }