UNPKG

@reown/appkit-controllers

Version:

The full stack toolkit to build onchain app UX.

159 lines • 7.81 kB
import { HelpersUtil } from '@reown/appkit-common'; import { ApiController } from '../controllers/ApiController.js'; import { ConnectionController } from '../controllers/ConnectionController.js'; import { ConnectorController } from '../controllers/ConnectorController.js'; import { OptionsController } from '../controllers/OptionsController.js'; import { ConnectorUtil } from './ConnectorUtil.js'; import { ConstantsUtil } from './ConstantsUtil.js'; import { CoreHelperUtil } from './CoreHelperUtil.js'; import { StorageUtil } from './StorageUtil.js'; export const WalletUtil = { filterOutDuplicatesByRDNS(wallets) { const connectors = ConnectorController.state.connectors; const recent = StorageUtil.getRecentWallets(); const connectorRDNSs = connectors .map(connector => connector.info?.rdns) .filter(Boolean); const recentRDNSs = recent.map(wallet => wallet.rdns).filter(Boolean); const allRDNSs = connectorRDNSs.concat(recentRDNSs); if (allRDNSs.includes('io.metamask.mobile') && CoreHelperUtil.isMobile()) { const index = allRDNSs.indexOf('io.metamask.mobile'); allRDNSs[index] = 'io.metamask'; } const filtered = wallets.filter(wallet => { // Check RDNS match first if (wallet?.rdns && allRDNSs.includes(String(wallet.rdns))) { return false; } // Some wallets don't have RDNS, so we need to check if the name matches a connector name if (!wallet?.rdns) { const hasMatchingConnectorName = connectors.some(connector => connector.name === wallet.name); if (hasMatchingConnectorName) { return false; } } return true; }); return filtered; }, filterOutDuplicatesByIds(wallets) { const connectors = ConnectorController.state.connectors.filter(connector => connector.type === 'ANNOUNCED' || connector.type === 'INJECTED' || connector.type === 'MULTI_CHAIN'); const recent = StorageUtil.getRecentWallets(); const connectorIds = connectors.map(connector => connector.explorerId || connector.explorerWallet?.id || connector.id); const recentIds = recent.map(wallet => wallet.id); const allIds = connectorIds.concat(recentIds); const filtered = wallets.filter(wallet => !allIds.includes(wallet?.id)); return filtered; }, filterOutDuplicateWallets(wallets) { const uniqueByRDNS = this.filterOutDuplicatesByRDNS(wallets); const uniqueWallets = this.filterOutDuplicatesByIds(uniqueByRDNS); return uniqueWallets; }, /** * Marks wallets as installed based on available connectors and sorts them * according to both installation status and featuredWalletIds order. * * @param wallets - Array of wallets to process * @returns Array of wallets marked as installed and sorted by priority */ markWalletsAsInstalled(wallets) { const { connectors } = ConnectorController.state; const { featuredWalletIds } = OptionsController.state; const installedWalletRdnsMap = connectors .filter(connector => connector.type === 'ANNOUNCED') .reduce((rdnsMap, connector) => { if (!connector.info?.rdns) { return rdnsMap; } rdnsMap[connector.info.rdns] = true; return rdnsMap; }, {}); // Mark each wallet as installed if its RDNS exists in the installed connectors const walletsWithInstallationStatus = wallets.map(wallet => ({ ...wallet, installed: Boolean(wallet.rdns) && Boolean(installedWalletRdnsMap[wallet.rdns ?? '']) })); const sortedWallets = walletsWithInstallationStatus.sort((walletA, walletB) => { const installationComparison = Number(walletB.installed) - Number(walletA.installed); if (installationComparison !== 0) { return installationComparison; } if (featuredWalletIds?.length) { const walletAFeaturedIndex = featuredWalletIds.indexOf(walletA.id); const walletBFeaturedIndex = featuredWalletIds.indexOf(walletB.id); if (walletAFeaturedIndex !== -1 && walletBFeaturedIndex !== -1) { return walletAFeaturedIndex - walletBFeaturedIndex; } // WalletA is featured, place it first if (walletAFeaturedIndex !== -1) { return -1; } // WalletB is featured, place it first if (walletBFeaturedIndex !== -1) { return 1; } } return 0; }); return sortedWallets; }, getConnectOrderMethod(_features, _connectors) { const connectMethodOrder = _features?.connectMethodsOrder || OptionsController.state.features?.connectMethodsOrder; const connectors = _connectors || ConnectorController.state.connectors; if (connectMethodOrder) { return connectMethodOrder; } const { injected, announced } = ConnectorUtil.getConnectorsByType(connectors, ApiController.state.recommended, ApiController.state.featured); const shownInjected = injected.filter(ConnectorUtil.showConnector); const shownAnnounced = announced.filter(ConnectorUtil.showConnector); if (shownInjected.length || shownAnnounced.length) { return ['wallet', 'email', 'social']; } return ConstantsUtil.DEFAULT_CONNECT_METHOD_ORDER; }, isExcluded(wallet) { const isRDNSExcluded = Boolean(wallet.rdns) && ApiController.state.excludedWallets.some(w => w.rdns === wallet.rdns); const isNameExcluded = Boolean(wallet.name) && ApiController.state.excludedWallets.some(w => HelpersUtil.isLowerCaseMatch(w.name, wallet.name)); return isRDNSExcluded || isNameExcluded; }, markWalletsWithDisplayIndex(wallets) { return wallets.map((w, index) => ({ ...w, display_index: index })); }, /** * Filters wallets based on WalletConnect support and platform requirements. * * On mobile only wallets with WalletConnect support and some mandatory wallets are shown. * On desktop with Appkit Core only wallets with WalletConnect support are shown. * On desktop with Appkit all wallets are shown. * * @param wallets - Array of wallets to filter * @returns Filtered array of wallets based on WalletConnect support and platform */ filterWalletsByWcSupport(wallets) { if (ConnectionController.state.wcBasic) { return wallets.filter(wallet => wallet.supports_wc); } if (CoreHelperUtil.isMobile()) { return wallets.filter(wallet => wallet.supports_wc || ConstantsUtil.MANDATORY_WALLET_IDS_ON_MOBILE.includes(wallet.id)); } return wallets; }, getWalletConnectWallets(allWallets) { const wallets = [...ApiController.state.featured, ...ApiController.state.recommended]; if (ApiController.state.filteredWallets?.length > 0) { wallets.push(...ApiController.state.filteredWallets); } else { wallets.push(...allWallets); } const uniqueWallets = CoreHelperUtil.uniqueBy(wallets, 'id'); const walletsWithInstalled = WalletUtil.markWalletsAsInstalled(uniqueWallets); const walletsByWcSupport = WalletUtil.filterWalletsByWcSupport(walletsWithInstalled); return WalletUtil.markWalletsWithDisplayIndex(walletsByWcSupport); } }; //# sourceMappingURL=WalletUtil.js.map