diff --git a/global-wallets-env.d.ts b/global-wallets-env.d.ts index 30a431cc89..d15d104098 100644 --- a/global-wallets-env.d.ts +++ b/global-wallets-env.d.ts @@ -12,6 +12,7 @@ declare global { solana: any; phantom: any; xfi: any; + coinbaseWalletExtension: any; coinbaseSolana: any; coin98: any; keplr: any; diff --git a/wallets/provider-coinbase/src/helpers.ts b/wallets/provider-coinbase/src/helpers.ts index a1c8527d71..3c7d4429cf 100644 --- a/wallets/provider-coinbase/src/helpers.ts +++ b/wallets/provider-coinbase/src/helpers.ts @@ -1,4 +1,25 @@ -import { Networks, ProviderConnectResult } from '@rango-dev/wallets-shared'; +import type { ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; + +export function coinbase() { + const { coinbaseWalletExtension, coinbaseSolana } = window; + + const instances = new Map(); + if (coinbaseWalletExtension) { + instances.set(Networks.ETHEREUM, coinbaseWalletExtension); + } + + if (!!coinbaseSolana) { + instances.set(Networks.SOLANA, coinbaseSolana); + } + + if (instances.size === 0) { + return null; + } + + return instances; +} export async function getSolanaAccounts( instance: any diff --git a/wallets/provider-coinbase/src/index.ts b/wallets/provider-coinbase/src/index.ts index c882fb5ef6..46a0966e90 100644 --- a/wallets/provider-coinbase/src/index.ts +++ b/wallets/provider-coinbase/src/index.ts @@ -13,7 +13,6 @@ import { canEagerlyConnectToEvm, canSwitchNetworkToEvm, chooseInstance, - getCoinbaseInstance as coinbase_instance, getEvmAccounts, Networks, switchNetworkForEvm, @@ -26,7 +25,7 @@ import { solanaBlockchain, } from 'rango-types'; -import { getSolanaAccounts } from './helpers'; +import { coinbase as coinbase_instance, getSolanaAccounts } from './helpers'; import signer from './signer'; const WALLET = WalletTypes.COINBASE; diff --git a/wallets/provider-metamask/src/helpers.ts b/wallets/provider-metamask/src/helpers.ts index b8253a1c90..4734a62719 100644 --- a/wallets/provider-metamask/src/helpers.ts +++ b/wallets/provider-metamask/src/helpers.ts @@ -1,17 +1,95 @@ -import { getCoinbaseInstance } from '@rango-dev/wallets-shared'; +function isMetamaskProvider(ethereum: any): boolean { + const isMetamask = !!ethereum?.isMetaMask; + if (!isMetamask) { + return false; + } + /* + * Brave tries to make itself look like MetaMask + * Could also try RPC `web3_clientVersion` if following is unreliable + */ + if (ethereum.isBraveWallet && !ethereum._events && !ethereum._state) { + return false; + } + if (ethereum.isApexWallet) { + return false; + } + if (ethereum.isAvalanche) { + return false; + } + if (ethereum.isBitKeep) { + return false; + } + if (ethereum.isBlockWallet) { + return false; + } + if (ethereum.isCoin98) { + return false; + } + if (ethereum.isFordefi) { + return false; + } + if (ethereum.__XDEFI) { + return false; + } + if (ethereum.isMathWallet) { + return false; + } + if (ethereum.isOkxWallet || ethereum.isOKExWallet) { + return false; + } + if (ethereum.isOneInchIOSWallet || ethereum.isOneInchAndroidWallet) { + return false; + } + if (ethereum.isOpera) { + return false; + } + if (ethereum.isPortal) { + return false; + } + if (ethereum.isRabby) { + return false; + } + if (ethereum.isDefiant) { + return false; + } + if (ethereum.isTokenPocket) { + return false; + } + if (ethereum.isTokenary) { + return false; + } + if (ethereum.isZeal) { + return false; + } + if (ethereum.isZerion) { + return false; + } + return true; +} export function metamask() { - const isCoinbaseWalletAvailable = !!getCoinbaseInstance(); const { ethereum } = window; - // Some wallets overriding the metamask. So we need to get it properly. - if (isCoinbaseWalletAvailable) { - // Getting intance from overrided structure from coinbase. - return getCoinbaseInstance('metamask'); - } else { - if (!!ethereum && ethereum.isMetaMask) { - return ethereum; + if (Array.isArray(ethereum?.providers)) { + /* + * When alternative EVM wallets are enabled and take precedence over MetaMask, + * they append MetaMask or other EVM wallets to the ethereum.providers array. + * example: 'Core' wallet + */ + let providers = ethereum.providers; + //Exceptions exist, such as when only 'MetaMask' and 'Coinbase' are enabled. + if ( + providers.length > 0 && + Array.isArray(ethereum.providers[0]?.providers) && + providers[0]?.providers.length > 0 + ) { + providers = providers[0]?.providers; + } + + const metamaskProvider = providers.find(isMetamaskProvider); + if (metamaskProvider) { + return metamaskProvider; } } - return null; + return ethereum?.isMetaMask ? ethereum : null; } diff --git a/wallets/provider-xdefi/src/helpers.ts b/wallets/provider-xdefi/src/helpers.ts index 10b6b2f7b3..bc5c3a3a2e 100644 --- a/wallets/provider-xdefi/src/helpers.ts +++ b/wallets/provider-xdefi/src/helpers.ts @@ -8,7 +8,7 @@ import { SUPPORTED_ETH_CHAINS, SUPPORTED_NETWORKS } from './constants'; type Provider = Map; export function xdefi() { - const { xfi, ethereum } = window; + const { xfi } = window; if (!xfi) { return null; @@ -30,8 +30,8 @@ export function xdefi() { if (xfi.binance) { instances.set(Networks.BINANCE, xfi.binance); } - if (ethereum?.__XDEFI) { - instances.set(Networks.ETHEREUM, ethereum); + if (xfi.ethereum) { + instances.set(Networks.ETHEREUM, xfi.ethereum); } if (xfi.dogecoin) { instances.set(Networks.DOGE, xfi.dogecoin); diff --git a/wallets/provider-xdefi/src/index.ts b/wallets/provider-xdefi/src/index.ts index 053376da96..e99858e0b4 100644 --- a/wallets/provider-xdefi/src/index.ts +++ b/wallets/provider-xdefi/src/index.ts @@ -42,9 +42,6 @@ export const connect: Connect = async ({ instance, meta }) => { const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); const solInstance = chooseInstance(instance, meta, Networks.SOLANA); const cosmosInstance = chooseInstance(instance, meta, Networks.COSMOS); - if (!ethInstance || !ethInstance.__XDEFI) { - throw new Error("Please 'Prioritise' XDEFI and refresh the page."); - } const evmResult = await getEvmAccounts(ethInstance); const nonEvmResults = await getNonEvmAccounts(instance); diff --git a/wallets/shared/src/helpers.ts b/wallets/shared/src/helpers.ts index a7dbc29770..1fd49f7a59 100644 --- a/wallets/shared/src/helpers.ts +++ b/wallets/shared/src/helpers.ts @@ -156,42 +156,6 @@ export const getSolanaAccounts: Connect = async ({ instance }) => { }; }; -export function getCoinbaseInstance( - lookingFor: 'coinbase' | 'metamask' = 'coinbase' -) { - const { ethereum, coinbaseSolana } = window; - const instances = new Map(); - if (ethereum) { - const checker = - lookingFor === 'metamask' ? 'isMetaMask' : 'isCoinbaseWallet'; - - // If only Coinbase Wallet is installed - if (lookingFor === 'coinbase' && ethereum[checker]) { - instances.set(Networks.ETHEREUM, ethereum); - } - // If Coinbase Wallet and Metamask is installed at the same time. - else if (ethereum.providers?.length) { - const ethInstance = ethereum.providers.find((provider: any) => { - return provider[checker]; - }); - instances.set(Networks.ETHEREUM, ethInstance); - } - } - if (!!coinbaseSolana && lookingFor === 'coinbase') { - instances.set(Networks.SOLANA, coinbaseSolana); - } - - if (instances.size === 0) { - return null; - } - - if (lookingFor === 'metamask') { - return instances.get(Networks.ETHEREUM); - } - - return instances; -} - export function sortWalletsBasedOnState(wallets: Wallet[]): Wallet[] { return wallets.sort( (a, b) =>