UNPKG

@lifi/wallet-management

Version:

LI.FI Wallet Management solution.

234 lines 10.8 kB
import { useConnect as useBigmiConnect } from '@bigmi/react'; import { ChainType } from '@lifi/sdk'; import { useMediaQuery } from '@mui/material'; import { useWallets } from '@mysten/dapp-kit'; import { WalletReadyState } from '@solana/wallet-adapter-base'; import { useWallet } from '@solana/wallet-adapter-react'; import { useEffect, useState } from 'react'; import { useConnect } from 'wagmi'; import { defaultBaseAccountConfig } from '../config/baseAccount.js'; import { defaultCoinbaseConfig } from '../config/coinbase.js'; import { defaultMetaMaskConfig } from '../config/metaMask.js'; import { defaultWalletConnectConfig } from '../config/walletConnect.js'; import { createBaseAccountConnector } from '../connectors/baseAccount.js'; import { createCoinbaseConnector } from '../connectors/coinbase.js'; import { createMetaMaskConnector } from '../connectors/metaMask.js'; import { createPortoConnector } from '../connectors/porto.js'; import { createWalletConnectConnector } from '../connectors/walletConnect.js'; import { useWalletManagementConfig } from '../providers/WalletManagementProvider/WalletManagementContext.js'; import { getConnectorIcon } from '../utils/getConnectorIcon.js'; import { getWalletPriority } from '../utils/getWalletPriority.js'; import { isWalletInstalled } from '../utils/isWalletInstalled.js'; const normalizeName = (name) => name.split(' ')[0].toLowerCase().trim(); const combineWalletLists = (utxoConnectorList, evmConnectorList, svmWalletList, suiWalletList, walletEcosystemsOrder) => { const walletMap = new Map(); utxoConnectorList.forEach((utxo) => { const utxoName = utxo.name; const normalizedName = normalizeName(utxoName); const existing = walletMap.get(normalizedName) || { id: utxo.id, name: utxoName, icon: getConnectorIcon(utxo), connectors: [], }; existing.connectors.push({ connector: utxo, chainType: ChainType.UTXO }); walletMap.set(normalizedName, existing); }); evmConnectorList.forEach((evm) => { const evmName = evm?.displayName || evm?.name; const normalizedName = normalizeName(evmName); const existing = walletMap.get(normalizedName) || { id: evm.id, name: evmName, icon: getConnectorIcon(evm), connectors: [], }; existing.connectors.push({ connector: evm, chainType: ChainType.EVM }); walletMap.set(normalizedName, existing); }); svmWalletList.forEach((svm) => { const normalizedName = normalizeName(svm.adapter.name); const existing = walletMap.get(normalizedName) || { id: svm.adapter.name, name: svm.adapter.name, icon: svm.adapter.icon, connectors: [], }; existing.connectors.push({ connector: svm.adapter, chainType: ChainType.SVM, }); walletMap.set(normalizedName, existing); }); suiWalletList.forEach((sui) => { const normalizedName = normalizeName(sui.name); const existing = walletMap.get(normalizedName) || { id: sui.name, name: sui.name, icon: sui.icon, connectors: [], }; existing.connectors.push({ connector: sui, chainType: ChainType.MVM }); walletMap.set(normalizedName, existing); }); let combinedWallets = Array.from(walletMap.values()); if (walletEcosystemsOrder) { combinedWallets = combinedWallets.map((wallet) => { const order = walletEcosystemsOrder[wallet.name]; if (order) { return { ...wallet, connectors: wallet.connectors.sort((a, b) => walletEcosystemsComparator(a, b, order)), }; } return wallet; }); } combinedWallets.sort(walletComparator); return combinedWallets; }; export const useCombinedWallets = () => { const walletConfig = useWalletManagementConfig(); const { connectors: wagmiConnectors } = useConnect(); const { connectors: bigmiConnectors } = useBigmiConnect(); const { wallets: solanaWallets } = useWallet(); const suiWallets = useWallets(); const [combinedWallets, setCombinedWallets] = useState(() => { return { installedWallets: [], notDetectedWallets: [], }; }); const isDesktopView = useMediaQuery((theme) => theme.breakpoints.up('sm')); useEffect(() => { ; (async () => { let evmConnectors = Array.from(wagmiConnectors // Remove duplicate connectors ).filter((connector, index, self) => index === self.findIndex((c) => c.id === connector.id)); // Check if Safe connector exists and can get a provider const safeConnector = evmConnectors.find((connector) => connector.id === 'safe'); let shouldFilterOutSafeConnector = false; if (safeConnector) { try { const provider = await safeConnector.getProvider(); // If no provider is available, we should filter out the Safe connector if (!provider) { shouldFilterOutSafeConnector = true; } } catch { // If getting provider fails, filter out the Safe connector shouldFilterOutSafeConnector = true; } } if (shouldFilterOutSafeConnector) { evmConnectors = evmConnectors.filter((connector) => connector.id !== 'safe'); } // Ensure standard connectors are included if (!evmConnectors.some((connector) => connector.id.toLowerCase().includes('walletconnect'))) { evmConnectors.unshift(createWalletConnectConnector(walletConfig?.walletConnect ?? defaultWalletConnectConfig)); } if (!evmConnectors.some((connector) => connector.id.toLowerCase().includes('coinbase'))) { evmConnectors.unshift(createCoinbaseConnector(walletConfig?.coinbase ?? defaultCoinbaseConfig)); } if (!evmConnectors.some((connector) => connector.id.toLowerCase().includes('metamask'))) { evmConnectors.unshift(createMetaMaskConnector(walletConfig?.metaMask ?? defaultMetaMaskConfig)); } if (!evmConnectors.some((connector) => connector.id.toLowerCase().includes('baseaccount'))) { evmConnectors.unshift(createBaseAccountConnector(walletConfig?.baseAccount ?? defaultBaseAccountConfig)); } if (!evmConnectors.some((connector) => connector.id.toLowerCase().includes('porto'))) { evmConnectors.unshift(createPortoConnector(walletConfig?.porto)); } const includeEcosystem = (chainType) => !walletConfig.enabledChainTypes || walletConfig.enabledChainTypes.includes(chainType); const installedUTXOConnectors = includeEcosystem(ChainType.UTXO) ? bigmiConnectors.filter((connector) => { const isInstalled = isWalletInstalled(connector.id); return isInstalled; }) : []; const installedEVMConnectors = includeEcosystem(ChainType.EVM) ? evmConnectors.filter((connector) => { const isInstalled = isWalletInstalled(connector.id); return isInstalled; }) : []; const installedSVMWallets = includeEcosystem(ChainType.SVM) ? solanaWallets.filter((wallet) => { const isInstalled = wallet.adapter.readyState === WalletReadyState.Installed || wallet.adapter.readyState === WalletReadyState.Loadable; return isInstalled; }) : []; const installedSuiWallets = includeEcosystem(ChainType.MVM) ? suiWallets : []; const installedCombinedWallets = combineWalletLists(installedUTXOConnectors, installedEVMConnectors, installedSVMWallets, installedSuiWallets, walletConfig.walletEcosystemsOrder); const notDetectedUTXOConnectors = bigmiConnectors.filter((connector) => { const isInstalled = isWalletInstalled(connector.id); return !isInstalled && isDesktopView; }); const notDetectedEVMConnectors = evmConnectors.filter((connector) => { const isInstalled = isWalletInstalled(connector.id); return !isInstalled && isDesktopView; }); const notDetectedSVMWallets = solanaWallets.filter((wallet) => { const isInstalled = wallet.adapter.readyState === WalletReadyState.Installed || wallet.adapter.readyState === WalletReadyState.Loadable; return !isInstalled && isDesktopView; }); const notDetectedCombinedWallets = combineWalletLists(notDetectedUTXOConnectors, notDetectedEVMConnectors, notDetectedSVMWallets, []); installedCombinedWallets.sort(walletComparator); notDetectedCombinedWallets.sort(walletComparator); setCombinedWallets({ installedWallets: installedCombinedWallets, notDetectedWallets: notDetectedCombinedWallets, }); })(); }, [ bigmiConnectors, isDesktopView, solanaWallets, suiWallets, wagmiConnectors, walletConfig, ]); return combinedWallets; }; // Ensure the walletComparator function is updated to handle CombinedWallet const walletComparator = (a, b) => { const priorityA = getWalletPriority(a.id); const priorityB = getWalletPriority(b.id); if (priorityA !== priorityB) { return priorityA - priorityB; } return a.id?.localeCompare(b.id); }; const walletEcosystemsComparator = (a, b, order) => { if (!order.length) { return 0; } const ecosystemA = a.chainType; const ecosystemB = b.chainType; if (ecosystemA === ecosystemB) { return 0; } const indexA = order.indexOf(ecosystemA); const indexB = order.indexOf(ecosystemB); // If both are in the order list, sort by their position if (indexA !== -1 && indexB !== -1) { return indexA - indexB; } // If only one is in the order list, prioritize it if (indexA !== -1) { return -1; } if (indexB !== -1) { return 1; } return 0; }; //# sourceMappingURL=useCombinedWallets.js.map