import type { EVMChain, ExtendedChain } from '@lifi/sdk' import { useCallback } from 'react' import { useChains } from '../../hooks/useChains.js' import { useSwapOnly } from '../../hooks/useSwapOnly.js' import { useToAddressReset } from '../../hooks/useToAddressReset.js' import { useExternalWalletProvider } from '../../providers/WalletProvider/useExternalWalletProvider.js' import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js' import { useChainOrder } from '../../stores/chains/useChainOrder.js' import type { FormType } from '../../stores/form/types.js' import { FormKeyHelper } from '../../stores/form/types.js' import { useFieldActions } from '../../stores/form/useFieldActions.js' import type { DisabledUIConfig } from '../../types/widget.js' export const useChainSelect = ( formType: FormType ): { chainOrder: number[] chains: ExtendedChain[] | undefined getSelectedChains: () => EVMChain[] isLoading: boolean setChainOrder: (chainId: number, type: FormType) => void setCurrentChain: (chainId: number) => void } => { const { disabledUI } = useWidgetConfig() const chainKey = FormKeyHelper.getChainKey(formType) const { setFieldValue, getFieldValues } = useFieldActions() const { useExternalWalletProvidersOnly, externalChainTypes } = useExternalWalletProvider() const { chains, isLoading, getChainById } = useChains( formType, // If the integrator uses external wallet management and has not opted in for partial wallet management, // restrict the displayed chains to those compatible with external wallet management. // This ensures users only see chains for which they can sign transactions. formType === 'from' && useExternalWalletProvidersOnly ? externalChainTypes : undefined ) const [chainOrder, setChainOrder] = useChainOrder(formType) const swapOnly = useSwapOnly() const { tryResetToAddress } = useToAddressReset() const getSelectedChains = useCallback((): EVMChain[] => { if (!chains) { return [] } const selectedChains = chainOrder .map((chainId) => chains.find((chain) => chain.id === chainId)) .filter(Boolean) as EVMChain[] return selectedChains }, [chains, chainOrder]) const setCurrentChain = useCallback( (chainId: number): void => { setFieldValue(chainKey, chainId, { isDirty: true, isTouched: true }) if (swapOnly) { setFieldValue(FormKeyHelper.getChainKey('to'), chainId, { isTouched: true, }) } const tokenKey = FormKeyHelper.getTokenKey(formType) if (!disabledUI?.[tokenKey as keyof DisabledUIConfig]) { setFieldValue(tokenKey, '') } const amountKey = FormKeyHelper.getAmountKey(formType) if (!disabledUI?.[amountKey as keyof DisabledUIConfig]) { setFieldValue(amountKey, '') } const [toChainId] = getFieldValues('toChain') const toChain = getChainById(toChainId) if (toChain) { tryResetToAddress(toChain) } setChainOrder(chainId, formType) }, [ chainKey, swapOnly, setFieldValue, disabledUI, formType, getChainById, tryResetToAddress, setChainOrder, getFieldValues, ] ) return { chainOrder: chainOrder, chains: chains, getSelectedChains: getSelectedChains, isLoading: isLoading, setChainOrder: setChainOrder, setCurrentChain: setCurrentChain, } }