Lose web3 instance on refresh

i know how to do this with web3 react, do you specifically want to do it using morlais im not as familiar with there react hooks. howeevr i think you will be able to get around the issue by calling Moralis.enableWeb3 in a useEffect that runs on page render

Thanks, I think this is finally working.

I put the react hooks in useEffect in the parent component like this:

{enableWeb3, isWeb3Enabled} = useMoralis()

useEffect( async () => {
        await enableWeb3()
    },[])

And importantly, conditionally render all the child components that need web3 using the isWeb3Enabled boolean. Since useEffect runs after everything is rendered I otherwise kept getting the web3 error from all children.

{isWeb3Enabled && <DoSomething />}
1 Like

Same problem here, is this completely solve yours?

1 Like

When i refresh the page getting this error: Uncaught (in promise) Error: Missing web3 instance, make sure to call Moralis.enableWeb3() or Moralis.authenticate()

On what line you get that error?

After first authentication everything works perfectly without an error but after refreshing page or re-rendering causing this error.

I mean what requires that web3 instance?

You can also enableWeb3 with useEffect

For useChain hook.
I tried with useEffect but still getting same error.

useEffect(
    () => async () => {
      if (isAuthenticated) {
        await enableWeb3();
      }
    },
    []
  );

All imports are done.

You could try to skip that if and call enableWeb3 directly

I tried that too, actually i’m struggling with this problem since morning :frowning:
Without “if” problem didn’t solve…

What is the like that requires web3 then? As in the line that gives you that error with web3

1 Like

I’m going to take a break because my head is burning lol…
I’ll look at it again, thanks for your help.

Any updates on this? Logging in via authenticate via wallet connect and or metamask reproduces the same outcome. The web3 instance is lost for metamask and I’m not sure if you need web3 enabled for wallet connect because due to mobile devices not supporting web3 instances ? Unless I am wrong on that.

One thing I noticed is that after authenticating, moralis/user information is stored in local storage. Is there a way to reconnect to moralis with that information after a refresh?

At the moment refreshing the page shows that person is authenticated somehow perhaps due to the local storage information but any of its functionality is useless and requires a logout and re-login.

A common solution for regular persisted injected wallet connections is to save the connected state in local storage and then re-run a connection function e.g. that initializes the Web3 provider and requests the account (if that connected state is true or exists).

And then clear the local storage + connection when the user disconnects e.g. via a disconnect wallet button.

I don’t know if there’s a way around that if you’re using a Moralis server sign in, the user has to be prompted to sign the message.

I see some information is stored in the local storage when authenticating but there is no documentation I believe that showcases how to use that data to “re-link” moralis. It is weird because on page refresh my react app is still showcasing that I am authenticated still (perhaps cause of that local storage).

If there really is no way then Moralis login is not scalable - its more so for single page websites and defeats the purposes of having users to stay signed in. :thinking: there must be a way ???

I am also having issues with this - it appears on the ‘ethereum boilerplate’ that isAuthenticated will go from false to true on its own if you have previously authed on the website. But on my own site, I can’t seem to figure out how to get isAuthenticated to become true, is there something I need to do so I can then call enableWeb3? Here is the code I am using, but it never seems to pass the if and run the function.

useEffect(() => {
    const connectorId = window.localStorage.getItem("connectorId");
    if (isAuthenticated && !isWeb3Enabled && !isWeb3EnableLoading)
      enableWeb3({ provider: connectorId });
  }, [isAuthenticated, isWeb3Enabled]);

Thanks in advance!

If you destructure authenticate from useMoralis(); and use it then it should authenticate to true and that useEffect should run and meet the condition of the “if” statement and web3 should enable.

Please note that you don’t always need enableWeb3 as I think that’s more so for connecting via a browser wallet.

await authenticate({
        provider: provider,
        chainId: 4,
        // mobileLinks: [
        //   "metamask",
        //   "trust",
        //   "rainbow",
        //   "argent",
        //   "imtoken",
        //   "pillar",
        // ],
        signingMessage: "Welcome!",
      });

I don’t disagree with what you are saying, but the problem is when I execute the authenticate function for a user that has already authenticated on my site. For example, they authed, then refreshed the page, they would have to resign in with metamask.

What I am looking for, and what the moralis ethereum boilerplate seems to have working is that on a refresh the user does does not have to resign on metamask, they are just authenticated and good to go.

1 Like

Gotcha - so the boilerplate example more so works for metamask.

This is what I was trying to explain when I said that “WalletConnect” does not work persay - even if you set walletconnect as the provider and enable web3 you are really making it continue to work with your browser wallet.

WalletConnect is more so known and or used for connecting wallet via QR code and also for linking wallet apps on mobile with the press of a button.

I haven’t tested using mobile to link a wallet and seeing if the state is persisted but it might not be and so then there goes two main wallet connect features that become unusable at scale and for a non-static site with multiple tabs.

For example, I am trying to leave the connect wallet functionality in the header in a nextjs application.

So for my particular case I am still lost :disappointed_relieved:

Its a little hard to believe that this wasn’t taken into account. It’s core logic to any “login” functionality.

Perhaps it is not that simple in this case cause of how wallet signatures work and etc but then again there should at least be more mention about this in the community and a post from moralis and or walletconnect discussing a potential fix or that they are looking into a persistent login wallet state.

2 Likes