I am facing the following issue when trying to connect my DApp to Metamask:

Normally, Metamask injects ethereum provider authomatically and we just call Web3(window.ethereum) to instantiate the library.

Now, my problem is that having also installed Coinbase Wallet as a browser extension, it seems it is injecting also an ethereum provider, and now I have 2 providers and the selected one by default seem to be the Coinbase one. When I console.log window.ethereum, I am getting the folowing:

window ethereum 
 u {_events: {…}, _eventsCount: 0, _maxListeners: undefined, providers: Array(2), 
  selectedProvider: w, …}
  enable: ƒ ()
  overrideIsMetaMask: true
  providers: (2) [w, Proxy]
  request: ƒ ()
  selectedProvider: w {_events: {…}, _eventsCount: 4, _maxListeners: undefined, 
  _filterPolyfill: e.FilterPolyfill, _subscriptionManager: e.SubscriptionManager, …}
  send: ƒ ()
  sendAsync: ƒ ()
  _events: {}
  _eventsCount: 0
  _maxListeners: undefined
  chainId: (...)
  isMetaMask: (...)
  networkVersion: (...)
  [[Prototype]]: o

As you can see, as selectedProvider I am getting w, while actually Metamask is the other one. In the end, what I am trying to achieve is creating one button to connect to Metamask and another to connect to Coinbase Wallet, but even using web3-react, both buttons are connecting to Coinbase Wallet.

2 Answers 2


In your case you need to get specific provider in window.ethereum:

const metamaskProvider = window.ethereum.providers.find((provider) => provider.isMetaMask);
  • 3
    This isn't working for me on the chrome as window.ethereum.providers is undefined. Any other solution? Feb 1, 2022 at 22:16

In order to provide for both MetaMask ONLY consumers and Coinbase/MetaMask consumers (where both extensions are installed), you must do a check if there is a providers array on the window.ethereum object to see if the array exists, and base your logic on this. I typically write a selector method that's something like:

 * Returns an injected provider
 * @param walletType 'isMetaMask' | 'isCoinbaseWallet'
 * @returns Provider
export function provider(walletType) {
  if (!window.ethereum) { throw new Error("No injected ethereum object."); }
  return Array.isArray(window.ethereum.providers)
    ? window.ethereum.providers.find((provider) => provider[walletType])
    : window.ethereum;

Then you could just do provider('isMetaMask') or provider('isCoinbaseWallet') depending on what you need.

It's a strange pattern, and I wish they would make the provider object structure more normalized to reduce conditional logic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.