4

I'm using the following to get the user's account on login to the site:

import detectEthereumProvider from '@metamask/detect-provider';

.....

let ethereum: any;
ethereum = await detectEthereumProvider();
var result = await ethereum.request({ method: 'eth_requestAccounts' });

This gets me an array of the accounts the user connects via Metamask. Our site is using the polygon chain, so I'm wanting to make sure at this point that those accounts have a polygon wallet. Is there any way at this point to check if the account is on polygon?

5 Answers 5

2

Summary

The easiest way, is to check the chainId of the provider.

const chainId = await provider.request({ method: 'eth_chainId' })
if(chainId == 137){
  // do something
}

Please note, that you used to be able to just do ethereum.chainId or provider.chainId, but it's recently been deprecated.

if(ethereum.chainId == 137){
  // do something
}

The Extra Mile

What you can do if they are not on the chain you want, is request to switch chains. You'll need to use the hex '0x89' since that's the hex of the Polygon chain ID of 137.

await provider.request({
  method: 'wallet_switchEthereumChain',
  params: [{ chainId: '0x89' }]
})

This may throw an error as they might not have the polygon chain in their metamask. One solution is to offer to add it from your front end, as such:

await provider.request({
  method: 'wallet_addEthereumChain',
  params: [{
    chainName: 'Polygon Mainnet',
    chainId: '0x89',
    nativeCurrency: { name: 'MATIC', decimals: 18, symbol: 'MATIC' },
    rpcUrls: ['https://polygon-rpc.com/']
  }]
})

Note: I don't always recommend this, as public RPCs have been known to not be very reliable.

Full Example of detecting chainId in HTML

<!DOCTYPE html>
<html>
    <head>
        <title>Hello</title>
    </head>

    <body>
        <button id="findIdButton">Find Chain Id</button>
    </body>

    <script src="https://unpkg.com/@metamask/detect-provider/dist/detect-provider.min.js"></script>
    <script type="text/javascript">
        const findIdButton = document.getElementById("findIdButton")
        findIdButton.onclick = findChainId
        async function findChainId(){
            const provider = await detectEthereumProvider()
            if (provider) {
                console.log(provider.chainId)
            } else {
                console.log("No provider found...")
            }
        }
    </script>
</html>

Full Example of detecting chainId in NextJS (ReactJS)

import type { NextPage } from "next";
import detectEthereumProvider from "@metamask/detect-provider";

const Home: NextPage = () => {
  async function findId() {
    const provider = (await detectEthereumProvider()) as any;
    if (provider) {
      const chainId = await provider.request({ method: "eth_chainId" });
      console.log(chainId);
    } else {
      console.log("No provider found...");
    }
  }

  return (
    <div>
      <button onClick={findId}>Find ChainId</button>
    </div>
  );
};

export default Home;

1
+50

you can check what network metamask is connected to. if they have the private to an address it will work for them on any EVM compatible chain.

Here's some react code which will invoke switch if metamask is on the wrong network, and will invoke add network if the network isn't already configured in metamask. In this case, Polygon's Mumbai testnet, but you can adapt to mainnet and check the user is on the right network.

const switchNetwork = async () => {
if (window.ethereum) {
  try {
    // Try to switch to the Mumbai testnet
    await window.ethereum.request({
      method: 'wallet_switchEthereumChain',
      params: [{ chainId: '0x13881' }], // Check networks.js for hexadecimal network ids
    });
  } catch (error) {
    // This error code means that the chain we want has not been added to MetaMask
    // In this case we ask the user to add it to their MetaMask
    if (error.code === 4902) {
      try {
        await window.ethereum.request({
          method: 'wallet_addEthereumChain',
          params: [
            {   
              chainId: '0x13881',
              chainName: 'Polygon Mumbai Testnet',
              rpcUrls: ['https://rpc-mumbai.maticvigil.com/'],
              nativeCurrency: {
                  name: "Mumbai Matic",
                  symbol: "MATIC",
                  decimals: 18
              },
              blockExplorerUrls: ["https://mumbai.polygonscan.com/"]
            },
          ],
        });
      } catch (error) {
        console.log(error);
      }
    }
    console.log(error);
  }
} else {
  // If window.ethereum is not found then MetaMask is not installed
  alert('MetaMask is not installed. Please install it to use this app: https://metamask.io/download.html');
} 
  }
1
import Web3 from "web3";
import detectEthereumProvider from "@metamask/detect-provider";

  const provider = await detectEthereumProvider();
  if (provider) {
    const web3 = new Web3(provider);
    const chainId = await web3.eth.getChainId();
     if (!chainId) {
        throw new Error("Cannot retrieve network. Please refresh the browser.");
  }
  //Polygon chainId is 137. testnetworks have different chainId
  // I am sure chainId return value is number. if not use string but != will handle both case
  if (chainId!=137){
      // or you show a different ui to the client
     throw new Error("connect to polygon")
 }}
 
1

Hi Dev advocate at Chainstack here!

This is the code that you need to prompt a switch from the current selected network to Polygon, using the window.ethereum global API injected directly by MetaMask.

// Prompt the user to switch to the Polygon mainnet

async function switchNetwork() {
   await window.ethereum.request({
   method: 'wallet_switchEthereumChain',
   params: [{ chainId: '0x311' }],    // chainId must be in HEX with 0x in front
   });
}

The MetaMask docs also show how to prompt to add that network in case is not already configured.

You can do it using the following code.

try {

// Prompt user to switch to Polygon

  await ethereum.request({
    method: 'wallet_switchEthereumChain',
    params: [{ chainId: '0x89' }],
  });

} catch (switchError) {

  // This error code indicates that the chain has not been added to MetaMask.

  if (switchError.code === 4902) {
    try {

// Prompt user to add Polygon to MetaMask if not already configured

      await ethereum.request({
        method: 'wallet_addEthereumChain',
        params: [
          {
            chainId: '0x89',
            chainName: 'Polygon mainnet',
            rpcUrls: ['https://polygon-rpc.com/'] /* ... */,
          },
        ],
      });
    } catch (addError) {
      // handle "add" error
    }
  }
  // handle other "switch" errors
}
1

I understand your point and if you are using Metamask to get accounts, then you don't need to worry if the accounts has exists on polygon chain. Because Metamask only support EVM chains and also most of EVM chains (include Ethereum, polygon, Binance...) use same wallet generate method so if you create one wallet on Metamask (this means you have one private key on one EVM chain), then you can create exact same account which have the same address on other EVM chain.

So this means if you make an account on Metamask, then all the chains that can imported to Metamask will have the account.

And at this point, you can need to check if the Metamask is on the polygon chain and if not, how to change the current chain to polygon on Metamask. I think sola24 already answered about this. :)

Your Answer

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

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