-1

Metamask wallet will not connect if coinbase is installed.

This is a critical issue for anyone trying to execute transactions on their website. Asking users to remove their coinbase wallet is a major deterrent.

https://docs.metamask.io/guide/ethereum-provider.html#using-the-provider

This link on the metamask website demonstrates that they are aware of the issue but no documentation addresses it.

This issue can't be impossible to fix because sites like uniswap allow users to select which wallet. So I think it would be helpful if this was addressed in the documentation.


This is the original code for the connect function:

const connectMetamask = async (setAlert, setCurrentAccount) => {
  const {ethereum} = window
  const isInstalled = () => {
    return Boolean(ethereum && ethereum.isMetaMask)
  }
  const isConnect = () => {
    return Boolean(ethereum && ethereum.isConnected()) // <-- this is the issue
  }
  try {
    if (!isInstalled()) {
      console.log("No metamask!"); // <-- this works
      setAlert(true);
      return;
    }
    if (!isConnect()) {
      console.log("Metamask not connected!");
      setAlert(true)
      return;
    }
    const chainId = await ethereum.request({ method: "eth_chainId" });
  } catch (error) {
    console.error(error);
  }
};

This code works fine to connect metamask IF coinbase wallet is not installed.


https://docs.cloud.coinbase.com/wallet-sdk/docs/injected-provider-guidance This link suggests what to do- but it doesn't work (for me at least).

 if (window.ethereum.providers?.length) {
      window.ethereum.providers.forEach(async (p) => {
        if (p.isMetaMask) provider = p;
      });
    }

window.ethereum.providers returns an array, first element being the coinbase wallet which works fine, second being a proxy containing metamask. The properties of this proxy object are not accessible.


As per some answers I've written (which is the same as the code in the coinbase example):

const metamaskProvider = await window.ethereum.providers.find((provider) => provider.isMetaMask);
ethereum.setSelectedProvider(metamaskProvider)

Logging metamaskProvider returns undefined. Logging window.ethereum.providers returns an array:

0: v {_events: {…}, _eventsCount: 0, _maxListeners: undefined, _filterPolyfill: e.FilterPolyfill, _subscriptionManager: e.SubscriptionManager, …}
1: Proxy {_events: {…}, _eventsCount: 0, _maxListeners: 100, _log: u, _state: {…}, …}

1 is the metamask provider. It contains the following properties:

1: Proxy
         [[Handler]]: Object 
                      deleteProperty: ()=>!0
                      [[Prototype]]: Object

         [[Target]]: l
                     chainId: "0x1"
                     enable: ƒ ()
                     isMetaMask: true
                     ....

metamaskProvider returns undefined. How do I access the isMetaMask property, and set my selectedProvider to metamaskProvider ?

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Bigboss01
  • 438
  • 6
  • 21

2 Answers2

1

I think if you have multiple wallets are installed, you would not have window.ethereum.providers defined. I currently have only "metamask", I get this error: Uncaught TypeError: Cannot read properties of undefined (reading 'find')

  if (typeof window.ethereum !== "undefined") {
    let provider = window.ethereum;
    // if multiple wallet are installed
    if (window.ethereum.providers?.length) {
      window.ethereum.providers.find(async (p) => {
        if (p.isMetaMask) provider = p;
      });
    }

also you should not destructure

const metamaskProvider = await window.ethereum.providers.find((provider) => provider.isMetaMask);
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • I left out some important information- I am trying to fix an error where if coinbase and metamask wallets are both installed, I can't connect to metamask because coinbase overrides the provider. So actually, you're getting undefined because providers is created when there are multiple. If I remember correctly, its created by coinbase actually. I followed that example from the coinbase docs, but no luck. Do you think you could try installing coinbase wallet and giving it a shot? – Bigboss01 Oct 05 '22 at 09:47
0

My fix:

const connectMetamask = async (setAlert, setCurrentAccount) => {
  let { ethereum } = window;

    try {
      if (!ethereum) {
        console.log("No metamask!");
        setAlert(true);
        return;
      }
      try{
        if (!ethereum.isConnected()) {
        console.log("Metamask not connected!");
        setAlert(true)
        return;
        }
      } catch (error){
        console.error(error)
        try{
          console.log('providers',window.ethereum.providers);
          console.log('ethVar',ethereum)
          ethereum = await window.ethereum.providers.find(
          (provider) => provider.isMetaMask );
          console.log('ethVarAfterFind', ethereum)
        } catch (error){
          console.error(error)
        }
      }

      const chainId = await ethereum.request({ method: "eth_chainId" });
      .....
    } catch (error) {
      console.log('error:')
      console.error(error);
    }
};

export default connectMetamask;

Basically just :

ethereum = await window.ethereum.providers.find( (provider) => provider.isMetaMask );
const chainId = await ethereum.request({ method: "eth_chainId" });

Honestly I'm pretty sure I tried this already and it wasn't working but, it is now ¯\_(ツ)_/¯

Bigboss01
  • 438
  • 6
  • 21