[SOLVED] Moralis unable to differentiate between metamask and walletconnect

Hey guys,

I recently posted an issue where I wasn’t able to use walletconnect with my dapp: [SOLVED] Metamask opens to sign transactions when using wallet connect

I solved this issue by explicitly stating my providers as follows:
const web3Provider = await Moralis.enableWeb3({provider: 'walletConnect' || 'metamask'});

When I do this, I am able to connect to WalletConnect. However, now when I disconnect from wallet connect and connect to metamask and try to sign a transaction, it tries to sign the transaction on walletconnect.

I think for some reason Moralis isn’t understanding when to use the relevant provider. Any idea why this is happening and how I can solve this?

Thanks!

How do you do this in code? If you do something like Moralis.enableWeb3() for MetaMask (injected), any code for transactions should then use that new provider.

I think for some reason Moralis isn’t understanding when to use the relevant provider. Any idea why this is happening and how I can solve this?

It should use the current web3 provider that is set from the last enableWeb3() or authenticate().

My disconnect button calls deactivateWeb3.

Here is the code I use to connect (most of it is from the moralis-react-client) with some adjustments to remove the moralis authentication:

Authenticate:

export const AuthenticateModal = ({ isOpen, onClose }: AuthenticateModalProps) => {
    const { authenticate, enableWeb3, isWeb3EnableLoading, isWeb3Enabled, isInitialized } = useMoralis();
    const {switchNetwork} = useChain()
  
    const [authError, setAuthError] = useState<null | Error>(null);
    const [isAuthenticating, setIsAuthenticating] = useState(false);
  
    const handleAuth = async (provider: 'metamask' | 'walletconnect') => {
      setAuthError(null);
      setIsAuthenticating(true);

      await enableWeb3({ throwOnError: true, provider, chainId: 137 });
      if (provider == 'metamask') {
        switchNetwork("0x89")
      }
      const { account, chainId } = Moralis;

      if (!account) {
        throw new Error('Connecting to chain failed, as no connected account was found');
      }
      if (!chainId) {
        throw new Error('Connecting to chain failed, as no connected chain was found');
      }
      onClose();
      setIsAuthenticating(false);
    };

Authenticate Button:

export const AuthenticateButton = ({ onClick }: AuthenticateButtonProps) => {
  const { chainId, account, isWeb3Enabled, deactivateWeb3, enableWeb3, logout } = useMoralis();

  const connectString = useMemo(() => {
    let output = "";
    if (account) {
      output += `${account.substring(0, 5)}...${account.substring(
        account.length - 3
      )}`;
    }
    return output;
  }, [account, chainId]);

  return (
    <button
      className="py-3 md:flex hover:bg-themeDarkYellow text-white text-center justify-center rounded-full min-w-[18rem] md:min-w-[10rem] px-6 bg-themeYellow"
      onClick={!isWeb3Enabled ? onClick : deactivateWeb3}
    >
      {isWeb3Enabled && account ? connectString + "(connected)!" : "Connect"}
    </button>
  );
};

Also, this is an example of a function in my components:

  const createClone = async function () {
    const ethers = Moralis.web3Library;
    const web3Provider = await Moralis.enableWeb3({provider: 'walletConnect' || 'metamask'});
    const signer = web3Provider.getSigner();
    const contract = new ethers.Contract(address, wfABI, signer);

    const transaction = await contract.createClone({
      value: Moralis.Units.ETH("10"),
      gasLimit: 6000000,
    });

    await transaction.wait(3);
    await handleSuccess(transaction);
  };

So it’s the handleAuth() function that is used for connecting to MetaMask?

Check if it is actually triggering that provider - what is the enableWeb3() code used where you select a different provider instead of WalletConnect?

Yes, it’s handleAuth used to connect to either metamask or walletconnect. Then I enableWeb3 the second time as shown below. I don’t select a different provider anywhere, I always use the || operator.

This code will always select walletConnect as the provider. If you need to use a different web3 connection, you need to actually specify the provider you want in enableWeb3() or authenticate().

Check the React client for an example. A different string is passed to handleAuth based on the button clicked, and the provider according to that string option is used.

Is there a function which allows me to check what provider the user has connected with? Then I can use an if statement to manage it.

I’m trying Moralis.getWeb3Provider() however I get an error saying it’s not a function.

Is there no way to get the provider which is already set in the handleAuth?

You can check the current web3 provider with web3. Or you could just use your own state (useState) that is updated when the user connects with a particular option.

1 Like

Awesome! Your post here really helped me! (How to set Moralis Provider when using Web3UIKit Connect Button?)

Going to start looking through the forum more thoroughly before posting a question from now on!

1 Like