import type { CreateConnectorFnExtended } from 'nimbus-wallet-management'; import { createCoinbaseConnector, createMetaMaskConnector, createWalletConnectConnector, getWalletPriority, isWalletInstalled, } from 'nimbus-wallet-management'; import type { Theme } from '@mui/material'; import { useMediaQuery } from '@mui/material'; import { WalletReadyState } from '@solana/wallet-adapter-base'; import type { Wallet } from '@solana/wallet-adapter-react'; import { useWallet } from '@solana/wallet-adapter-react'; import { useMemo } from 'react'; import type { Connector } from 'wagmi'; import { useConnect, useAccount as useWagmiAccount } from 'wagmi'; import { defaultCoinbaseConfig } from '../config/coinbase.js'; import { defaultMetaMaskConfig } from '../config/metaMask.js'; import { defaultWalletConnectConfig } from '../config/walletConnect.js'; import type { WidgetChains, WidgetWalletConfig } from '../types/widget.js'; import { isItemAllowed } from '../utils/item.js'; import type { MVMWallet, TVMWallet } from '../types/wallet.js'; import { ChainType } from '../utils/chainType.js'; const tvmConnector: TVMWallet = { name: 'Ton Connect', icon: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDU2IDU2IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1NiA1NjsiIHhtbDpzcGFjZT0icHJlc2VydmUiIGNsYXNzPSJtZGwtanMiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiMwMDg4Q0M7fQoJLnN0MXtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQo8L3N0eWxlPgo8Y2lyY2xlIGNsYXNzPSJzdDAiIGN4PSIyOCIgY3k9IjI4IiByPSIyOCIvPgo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjAuMiwxOC41aDE1LjdjMC42LDAsMS4xLDAuMSwxLjcsMC40YzAuNywwLjMsMS4xLDAuOCwxLjMsMS4yYzAsMCwwLDAuMSwwLjEsMC4xYzAuMywwLjUsMC41LDEuMSwwLjUsMS44ICBjMCwwLjYtMC4xLDEuMi0wLjUsMS44YzAsMCwwLDAsMCwwbC05LjksMTdjLTAuMiwwLjQtMC42LDAuNi0xLjEsMC42Yy0wLjQsMC0wLjgtMC4yLTEuMS0wLjZsLTkuNy0xN2MwLDAsMCwwLDAsMCAgYy0wLjItMC40LTAuNi0wLjktMC42LTEuN2MtMC4xLTAuNywwLjEtMS4zLDAuNC0xLjljMC4zLTAuNiwwLjgtMS4xLDEuNS0xLjNDMTkuMSwxOC41LDE5LjgsMTguNSwyMC4yLDE4LjV6IE0yNi44LDIwLjloLTYuNiAgYy0wLjQsMC0wLjYsMC0wLjcsMC4xYy0wLjIsMC4xLTAuMywwLjItMC40LDAuNEMxOSwyMS41LDE5LDIxLjcsMTksMjEuOWMwLDAuMSwwLjEsMC4yLDAuMywwLjZjMCwwLDAsMCwwLDBsNy41LDEzVjIwLjl6ICAgTTI5LjIsMjAuOXYxNC43bDcuNi0xMy4xYzAuMS0wLjIsMC4xLTAuNCwwLjEtMC42YzAtMC4yLDAtMC40LTAuMS0wLjVjLTAuMS0wLjEtMC4xLTAuMi0wLjItMC4yYzAsMC0wLjEtMC4xLTAuMS0wLjEgIGMtMC4yLTAuMS0wLjQtMC4xLTAuNy0wLjFIMjkuMnoiLz4KPC9zdmc+', type: 'TVM', id: 'tvm', }; const mvmConnector: MVMWallet = { name: 'Sui Connect', icon: 'https://strapi-dev.scand.app/uploads/sui_c07df05f00.png', type: 'MVM', id: 'mvm', }; export const useWallets = ( walletConfig?: WidgetWalletConfig, chains?: WidgetChains, ) => { const account = useWagmiAccount(); const { connectors } = useConnect(); const { wallets: solanaWallets } = useWallet(); const isDesktopView = useMediaQuery((theme: Theme) => theme.breakpoints.up('sm'), ); const wallets = useMemo(() => { const evmConnectors: (CreateConnectorFnExtended | Connector)[] = Array.from(connectors); if ( !connectors.some((connector) => connector.id.toLowerCase().includes('walletconnect'), ) ) { evmConnectors.unshift( createWalletConnectConnector( walletConfig?.walletConnect ?? defaultWalletConnectConfig, ), ); } if ( !connectors.some((connector) => connector.id.toLowerCase().includes('coinbase'), ) && !isWalletInstalled('coinbase') ) { evmConnectors.unshift( createCoinbaseConnector( walletConfig?.coinbase ?? defaultCoinbaseConfig, ), ); } if ( !connectors.some((connector) => connector.id.toLowerCase().includes('metamask'), ) && !isWalletInstalled('metaMask') ) { evmConnectors.unshift( createMetaMaskConnector( walletConfig?.metaMask ?? defaultMetaMaskConfig, ), ); } const evmInstalled = isItemAllowed(ChainType.EVM, chains?.types) ? evmConnectors.filter( (connector) => isWalletInstalled(connector.id!) && // We should not show already connected connectors account.connector?.id !== connector.id, ) : []; const evmNotDetected = isItemAllowed(ChainType.EVM, chains?.types) ? evmConnectors.filter((connector) => !isWalletInstalled(connector.id!)) : []; const svmInstalled = isItemAllowed(ChainType.SVM, chains?.types) ? solanaWallets?.filter( (connector) => connector.adapter.readyState === WalletReadyState.Installed && // We should not show already connected connectors !connector.adapter.connected, ) : []; const svmNotDetected = isItemAllowed(ChainType.SVM, chains?.types) ? solanaWallets?.filter( (connector) => connector.adapter.readyState !== WalletReadyState.Installed, ) : []; const installedWallets: ( | Connector | CreateConnectorFnExtended | Wallet | TVMWallet | MVMWallet )[] = [...evmInstalled, ...svmInstalled].sort(walletComparator); if (isDesktopView) { const notDetectedWallets = [...evmNotDetected, ...svmNotDetected].sort( walletComparator, ); installedWallets.push(...notDetectedWallets); } // push eclipse connector const isAllowEclipse = isItemAllowed(ChainType.ECLIPSE, chains?.types); if ( isAllowEclipse && !chains?.types?.allow?.includes(ChainType.SVM) && chains?.types?.allow?.includes(ChainType.ECLIPSE) ) { installedWallets.unshift( ...solanaWallets.filter((item) => [ 'Backpack', 'Salmon', 'Connect by Drift', 'Nightly', 'OKX Wallet', ].includes(item.adapter.name), ), ); } // push tvm connector const isAllowTVM = isItemAllowed(ChainType.TVM, chains?.types); if (isAllowTVM) { installedWallets.unshift(tvmConnector); } // push mvm connector const isAllowMVM = isItemAllowed(ChainType.MVM, chains?.types); if (isAllowMVM) { installedWallets.unshift(mvmConnector); } return installedWallets; }, [ account.connector?.id, chains?.types, connectors, isDesktopView, solanaWallets, walletConfig?.coinbase, walletConfig?.metaMask, walletConfig?.walletConnect, ]); return wallets; }; export const walletComparator = ( a: CreateConnectorFnExtended | Connector | Wallet, b: CreateConnectorFnExtended | Connector | Wallet, ) => { let aId = (a as Connector).id || (a as Wallet).adapter?.name; let bId = (b as Connector).id || (b as Wallet).adapter?.name; const priorityA = getWalletPriority(aId); const priorityB = getWalletPriority(bId); if (priorityA !== priorityB) { return priorityA - priorityB; } if (aId < bId) { return -1; } if (aId > bId) { return 1; } return 0; };