Confused by Web3 and best practices

I want to create a simple front-end for my DApp. The DApp fetches values about the smart contract to display on the site. If the reader wants to interact (eg. buy) with the smart contract, I have a ‘connect’ button that prompts the user to allow MetaMask access.

How do I approach separating something basic like this – the separation between read-only values Web3 needs, and the user-calling Web3 performs?

Here’s the issue I’m facing;

export function App() {
async function connectPrompt() {
const chainId = await web3.eth.getChainId()

if(chainId != 80001) {
alert(“Wrong network! Switch to Polygon (Matic)”);

const provider = await web3Modal.connect();
setWeb3(new Web3(provider))
const firstAccount = await web3.eth.getAccounts()

async function disconnect() {
await web3Modal.clearCachedProvider();

const [account, setAccount] = useState(”);
const [web3, setWeb3] = useState(new Web3(‘’));

const providerOptions = {};
const web3Modal = new Web3Modal({
network: “mainnet”,
cacheProvider: true,
providerOptions // required

const address = ‘0x…0’

const contract = new web3.eth.Contract(abi, contract)

return ( //rest of app…)

This is my setup. I use Web3 to connect to Matic, where my contract is. I can then use this to get whatever read-only values I want (eg. totalSupply). The user can click a button which calls connectPrompt(), which handles logging in. If the user isn’t on Matic, don’t connect. If they are, connect.

The issue I’m having is that if the user is that web3 is always on Matic, since I set it that way in useState. If I use givenProvider() instead to check, like;

async function connectPrompt() {
const tempWeb3 = new Web3(Web3.givenProvider)
const chainId = await tempWeb3.eth.getChainId()
//const chainId = await web3.eth.getChainId()

if(chainId != 80001) {
alert(“Wrong network! Switch to Polygon (Matic)”);

this sort of works, but it’s super janky. Sometimes, on the first click, it will actually connect, but then it’ll trigger the alert on subsequent connects after disconnecting.

Then there’s the issue of connecting with Matic, but then the user switching networks. This breaks everything. I also find that the app just breaks randomly for seemingly no reason. Sometimes if I just refresh a couple times the error will go away

This approach seems fundamentally misguided – what do I do? Again, I just want to be able to get all my read-only values printed on whatever pages I need them. Then, if the user wants to interact with the DApp (buy something), they can login and click whichever buttons to do whatever.

Do I need to use two instances of Web3 – one that’s always connected to the matic to get my read-only values, and another that’s connected to whatever the user is using? This has to be redundant, right?

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings


  1. You might want to take a look at `useMetamask` and the projects `web3-react`, `scaffold-eth` and `useDapp`. Here are links from the CryptoDevHub Wiki:

    `useMetamask` is a React hook you can use which takes care of all the edge cases you could potentially run into. The other 3 resources are boilerplates / templates which will show you best practices in terms of Smart Contract / Web 3 development, integrating wallets, etc.

    Also feel free to drop by the CryptoDevHub Discord to meet other developers and ask further questions:

    **Edit**: Added `useDapp` to the list (as pointed out by /u/JayWelsh in the comments below)

  2. Having two instances doesn’t seem like a good choice as it breaks an important goal for good and responsive apps: Having the user feel “in control”. If I change my network in MetaMask from Polyong to Mainnet I expect your app to read values from mainnet (or show a message that your contract is only on Polygon). It just supports that expectation and e.g. Uniswap does the same, where you can switch from Mainnet to Polygon and the website automatically adapts. This would also be my recommendation: Take a look how Uniswap did this [](

    I also really like this template for a web3+React website with a simple connect button: [](

What I Learned After One Year of Trading Cryptocurrencies | by Misha |

SuperHeavyBoosters($SHB) | New Elon Tweet Token | Launching Soon | No Dev Wallets | A simple SafeMoon fork | 100% Safe Contract | Super Hyped Community | Join us for a ride to the moon!