import uniqBy from 'lodash.uniqby' import type { WalletInit } from '@web3-onboard/common' import type { InjectedWalletOptions, CustomWindow } from './types.js' import { ProviderLabel } from './types.js' import standardWallets from './wallets.js' import { remove } from './helpers.js' import { validateWalletOptions } from './validation.js' declare const window: CustomWindow export { ProviderIdentityFlag, ProviderLabel } from './types.js' function injected(options?: InjectedWalletOptions): WalletInit { if (typeof window === 'undefined') return () => null if (options) { const result = validateWalletOptions(options) if (result && result.error) throw result.error } return helpers => { const { device } = helpers const { custom = [], filter = {} } = options || {} const allWallets = [...custom, ...standardWallets] const deduped = uniqBy(allWallets, ({ label }) => `${label}`) const filteredWallets = deduped.filter(wallet => { const { label, platforms } = wallet const walletFilters = filter[label] const filteredWallet = walletFilters === false const excludedDevice = Array.isArray(walletFilters) && (walletFilters.includes(device.type) || walletFilters.includes(device.os.name)) const invalidPlatform = !platforms.includes('all') && !platforms.includes(device.type) && !platforms.includes(device.os.name) const supportedWallet = !filteredWallet && !excludedDevice && !invalidPlatform return supportedWallet }) let removeMetaMask = false const validWallets = filteredWallets.filter( ({ injectedNamespace, checkProviderIdentity, label }) => { const provider = window[injectedNamespace] as CustomWindow['ethereum'] if (!provider) return let walletExists if (provider.providers && Array.isArray(provider.providers)) { walletExists = !!provider.providers.filter(provider => checkProviderIdentity({ provider, device }) ).length } else { walletExists = checkProviderIdentity({ provider, device }) } if ( walletExists && provider.isMetaMask && !provider.overrideIsMetaMask && label !== ProviderLabel.MetaMask && label !== 'Detected Wallet' ) { removeMetaMask = true } return walletExists } ) if (validWallets.length) { const moreThanOneWallet = validWallets.length > 1 // if more than one wallet, then remove detected wallet return validWallets .filter( remove({ detected: moreThanOneWallet, metamask: moreThanOneWallet && removeMetaMask }) ) .map(({ label, getIcon, getInterface }) => ({ label, getIcon, getInterface })) } return [] } } export default injected