Web3.js – Automatically Get User’s Wallet Info Without MetaMask Popup

javascriptmetamaskweb3js

I don't want metamask to pop up on page load forcing a user to connect, so we only connect via a button – but after a user is connected if they refresh the page – they need to press the button again to connect (although nothing happens in metamask, it just calls ethereum.enable() and closes).

I'd like to be able to do something like:

If user has already connected (after reloading the page or coming back next week), call enable and get their wallet info/address.

If the user has not already connected – do not call the connect function for metamask until the user presses the connect button.

Here is my code for connecting a wallet and I'm unsure how to do the initial check for – "if they have already connected".

export const loadUserWeb3 = async () => {
  try {
    if (window.ethereum) {
      window.web3 = new Web3(window.ethereum);
      await window.ethereum.enable();
      window.ethereum.on("chainChanged", () => {
        document.location.reload();
      });
      return window.web3;
    } else if (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider);
      return window.web3;
    } else {
      window.web3 = new Web3(
        new Web3.providers.HttpProvider(INFURA_ENDPOINT[1])
      );
      return window.web3;
    }
  } catch {
    window.web3 = new Web3(new Web3.providers.HttpProvider(INFURA_ENDPOINT[1]));
    return window.web3;
  }
};

Again the key here is that if they have not already connected then it would not call enable() because that would show the metamask pop up without the user asking for it to be shown.

TL;DR:

How to get the user's wallet info if their wallet is ALREADY connected and they just reload the page – without forcing metamask to ask them to connect if they HAVEN'T connected.

Best Answer

The solution will depend a little bit on your front-end. This is how I did to cover your requirements with React in TypeScript:

    React.useEffect(() => {
       const checkConnection = async () => {

           // Check if browser is running Metamask
           let web3: any;
           if (window.ethereum) {
               web3 = new Web3(window.ethereum);
           } else if (window.web3) {
               web3 = new Web3(window.web3.currentProvider);
           };

           // Check if User is already connected by retrieving the accounts
           web3.eth.getAccounts()
               .then(async (addr: string) => {
                   // Set User account into state
               });
       };
       checkConnection();
   }, []);

When Users connect to the web page, I check if there is a web3 plugin in browser and try to retrieve the accounts. If I get any result, it means the User is already connected to Metamask and don't need to trigger any pop-up to connect.

If the User is not connected to Metamask, then you can trigger the pop-up by pressing the button you mentioned, and you will execute a similar code but including await window.ethereum.enable();

If you are not using React, then you just need to execute this function the first time you load the page and skip the useEffect method.

Related Topic