import type { ExtendedChain } from '@lifi/sdk'; import { config, getChains } from '@lifi/sdk'; import { useQuery } from '@tanstack/react-query'; import { useCallback } from 'react'; import { useHasExternalWalletProvider } from '../providers/WalletProvider/useHasExternalWalletProvider.js'; import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'; import { isItemAllowed } from '../utils/item.js'; import { ChainType } from '../utils/chainType.js'; import { ECLIPSE_CHAIN_ID, ECLIPSE_NATIVE_ADDRESS, MOVE_CHAIN_ID, MOVE_NATIVE_ADDRESS, TON_CHAIN_ID, TON_NATIVE_ADDRESS, } from '../utils/constants.js'; import { MVM_RPC_URL } from '../utils/mvm.js'; import { ECLIPSE_RPC_URL } from '../utils/eclipse.js'; const supportedChainTypes = [ ChainType.EVM, ChainType.SVM, ChainType.TVM, ChainType.MVM, ChainType.ECLIPSE, ]; export const useAvailableChains = () => { const { chains } = useWidgetConfig(); const { providers } = useHasExternalWalletProvider(); const { data, isLoading } = useQuery({ queryKey: [ 'chains', providers, chains?.types, chains?.allow, chains?.deny, chains?.from, chains?.to, ] as const, queryFn: async ({ queryKey: [, providers, chainTypes] }) => { let availableChains: ExtendedChain[] = []; const chainTypesRequest = ( providers.length > 0 ? providers : supportedChainTypes ).filter((chainType) => isItemAllowed(chainType, chainTypes)); const listNotCustomChain = chainTypesRequest.filter( (chainType) => ![ChainType.TVM, ChainType.MVM, ChainType.ECLIPSE].includes( chainType, ), ); if (listNotCustomChain.length > 0) { availableChains = await getChains({ chainTypes: listNotCustomChain as any, }); } if (chainTypesRequest.includes(ChainType.TVM)) { availableChains.unshift({ key: 'ton' as any, chainType: 'TVM' as any, name: 'Ton', coin: 'TON' as any, id: TON_CHAIN_ID, mainnet: true, logoURI: 'https://ton.org/download/ton_symbol.png', multicallAddress: '', metamask: { chainId: `${TON_CHAIN_ID}`, blockExplorerUrls: ['https://tonscan.org/'], chainName: 'TON', nativeCurrency: { name: 'TON', symbol: 'TON', decimals: 9, }, rpcUrls: [ 'https://go.getblock.io/7588f444d16b4b59a989cc163ec675e2', ], }, nativeToken: { address: TON_NATIVE_ADDRESS, // @ts-ignore chainId: TON_CHAIN_ID, symbol: 'TON', decimals: 9, name: 'Toncoin', coinKey: 'TON' as any, logoURI: 'https://assets.dedust.io/images/ton.webp', // TODO: need to check if we can get the price from the API priceUSD: '7.360767272727266', }, }); } if (chainTypesRequest.includes(ChainType.MVM)) { availableChains.unshift({ key: 'sui' as any, chainType: 'MVM' as any, name: 'Sui', coin: 'SUI' as any, id: MOVE_CHAIN_ID, mainnet: true, logoURI: 'https://strapi-dev.scand.app/uploads/sui_c07df05f00.png', multicallAddress: '', metamask: { chainId: `${MOVE_CHAIN_ID}`, blockExplorerUrls: ['https://suiscan.xyz/'], chainName: 'SUI', nativeCurrency: { name: 'SUI', symbol: 'SUI', decimals: 9, }, rpcUrls: [MVM_RPC_URL], }, nativeToken: { address: MOVE_NATIVE_ADDRESS, // @ts-ignore chainId: MOVE_CHAIN_ID, symbol: 'SUI', decimals: 9, name: 'Sui', coinKey: 'SUI' as any, logoURI: 'https://strapi-dev.scand.app/uploads/sui_c07df05f00.png', // TODO: need to check if we can get the price from the API priceUSD: '0.7958', }, }); } if (chainTypesRequest.includes(ChainType.ECLIPSE)) { availableChains.unshift({ key: 'eclipse' as any, chainType: 'ECLIPSE' as any, name: 'Eclipse', coin: 'ECLIPSE' as any, id: ECLIPSE_CHAIN_ID, mainnet: true, logoURI: 'https://icons.llamao.fi/icons/chains/rsz_eclipse?w=48&h=48', multicallAddress: '', metamask: { chainId: `${ECLIPSE_CHAIN_ID}`, blockExplorerUrls: ['https://eclipsescan.xyz/'], chainName: 'ECLIPSE', nativeCurrency: { name: 'ECLIPSE', symbol: 'ECLIPSE', decimals: 9, }, rpcUrls: [ECLIPSE_RPC_URL], }, nativeToken: { address: ECLIPSE_NATIVE_ADDRESS, // @ts-ignore chainId: ECLIPSE_CHAIN_ID, symbol: 'ECLIPSE', decimals: 9, name: 'Eclipse', coinKey: 'ECLIPSE' as any, logoURI: 'https://icons.llamao.fi/icons/chains/rsz_eclipse?w=48&h=48', // TODO: need to check if we can get the price from the API priceUSD: '200', }, }); } config.setChains(availableChains); return availableChains; }, refetchInterval: 300_000, staleTime: 300_000, }); const getChainById = useCallback( (chainId?: number, chains: ExtendedChain[] | undefined = data) => { if (!chainId) { return; } const chain = chains?.find((chain) => chain.id === chainId); // if (!chain) { // throw new Error('Chain not found or chainId is invalid.'); // } return chain; }, [data], ); return { chains: data, getChainById, isLoading, }; };