8
I am using metamask with kovan to connect to the wallet 
import React, { useState, useEffect} from 'react';
import Web3 from "web3";
import Web3Modal from "web3modal";
import Navbar from './components/navbar';

function App() {
const providerOptions = {};
const web3Modal = new Web3Modal({
  network: "mainnet", // optional
  cacheProvider: true, // optional
  providerOptions // required
});

  const [account, setAccount] = useState('');
  async function connect() {
    try {
      const provider = await web3Modal.connect();
      const web3 = new Web3(provider);
      const accounts = await web3.eth.getAccounts();
      setAccount(accounts[0]);
    } catch (err) {
      console.error(err);
    }
  }


  useEffect(() => {
    if (window.web3) {
      connect();
    }
  }, []);

   async function disconnect() {
    const clear = await web3Modal.clearCachedProvider();
  }

  return (
    <div>
     <Navbar account={account} connect={connect} disconnect={disconnect} />
    </div>
  );
}

export default App;

how do i disconnect from the metamask?

5 Answers 5

6

It's not possible.

The connect/disconnect functionality is entirely in the user's hands due to security and privacy concerns.

You can only pretend a disconnect by resetting a provider, chainId and selectedAccount to null and clearing the cache of the provided you previously used.

P.S.: I know this is a harsh reality. Upvote this as it's the only correct answer that there is! You have to pretend from your app that the user has disconnected. This is the way I do it in my dapp, the way PancakeSwap does, Uniswap too, etc...

1

I think what you can do is to call:

  // TODO: Which providers have close method?
  if(provider.close) {
    await provider.close();

    // If the cached provider is not cleared,
    // WalletConnect will default to the existing session
    // and does not allow to re-scan the QR code with a new wallet.
    // Depending on your use case you may want or want not his behavior.
    await web3Modal.clearCachedProvider();
    provider = null;
  }

You can also find the example here.

2
  • 1
    It does not work anymore.
    – porton
    Commented Dec 14, 2020 at 9:18
  • TypeError: provider.close is not a function Commented Jul 6, 2021 at 13:50
0

you could wait for the event to be fired when disconnecting(User Deletes Connection in Metamask from Dapp) and then dispatch an action with a new address if there are any other accounts currently connected To the Dapp else you can call the disconnect function.

         const provider = await new web3(web3.givenProvider);
         provider.on('accountsChanged', (code: number, reason: string) => {
                        const accountSwitch = code[0];
                        if (accountSwitch){
                            if (accountSwitch) {
                                dispatch({
                                    type: _const.ADDRESS,
                                    payload: { address: accountSwitch }
                                })
                            }
                        }else{
                            DisconnectFromWallet();
                        }
                    });
0

As told by Fredo Corleone we cannot disconnect the wallet in anyways, but rather we can pretend. This is totally true as of today. We can pretend to disconnect by using the following line of code:

web3Modal.clearCachedProvider();

use the above line of code on clicking the disconnect button.

By using the above line of code when the user comes back and clicks on connect it will prompt to select the provider again, if you don't do this then it will automatically select it from the cached provider.

EDIT: it looks like the above function is not working in web3Modal, due to some issue on their side. I tried the following thing, it did not disconnect but at least it is asking user to select provider again in walletconnect:

web3ModalRef.current.clearCachedProvider();
window.localStorage.clear();
setConnectedWallet(false);

hope you find this correction helpful :)

2
  • web3Modal.clearCachedProvider(); does not work
    – mamaye
    Commented May 16, 2022 at 14:39
  • @codevine I edited my solution, please try it now Commented May 22, 2022 at 6:31
0

2024 answer

As this question still popup in first places of Google, here is an updated answer.

There is (now) a disconnect() function in the API ... but, it does not seem to really close the session on the wallet side (at least, not with Phantom).

As the doc does not explain what this function really do, I call it, but I also clear the storage.

modal.disconnect()
window.localStorage.clear()

References:

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.