How to maintain the user’s login state with web3auth.connect after a page refresh

When asking for help in this category, please make sure to provide the following details:

  • SDK Version(package.json):
    @web3auth/auth-adapter”: “^9.0.2”,
    @web3auth/base”: “^9.0.2”,
    @web3auth/ethereum-provider”: “^9.0.2”,
    @web3auth/no-modal”: “^9.1.0”,
  • Platform: web

“I am using the no-modal SDK version 9 and developing with SMS login. After logging in, the user is redirected to the home page. However, when the home page is refreshed, web3auth.connect is lost. Does this mean that the user is logged out? Is there a way to maintain web3auth.connect even after a refresh?

const web3AuthClientId = process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID || "";

const chainConfig = {
    chainNamespace: CHAIN_NAMESPACES.EIP155,
    chainId: "0xB04F",
    rpcTarget: process.env.NEXT_PUBLIC_RPC_URL || "",
    displayName: "OPStack",
    blockExplorer: "example",
    ticker: "ETH",
    tickerName: "Ethereum",
    sessionTime: 604800
};

const privateKeyProvider = new EthereumPrivateKeyProvider({
    config: {
        chainConfig
    },
});

export const web3auth = new Web3AuthNoModal({
    clientId: web3AuthClientId,
    web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
    privateKeyProvider,
});

export const signUpAdapter = new AuthAdapter({
    adapterSettings: {
        uxMode: UX_MODE.REDIRECT,
        // redirectUrl: "https://app.zab.cash/sign-up/pwd",
        redirectUrl: "http://localhost:3000/sign-up/pwd",
        replaceUrlOnRedirect: true,
        whiteLabel: {
            appName: "Examle",
            appUrl: "https://example/",
            defaultLanguage: "ko",
            theme: {
                primary: "#FFFFFF",
            } as WHITE_LABEL_THEME,
            useLogoLoader: true,
        } as WhiteLabelData,
    },
    privateKeyProvider,
})

web3auth.configureAdapter(signUpAdapter);

This code is how i set web3auth config

Also, during the upgrade from version 8 to 9, when I call the connectTo function, I get an error like the one in the attached picture. I understand that web3auth.init() has been removed in version 9, and I implemented the connectTo logic as it was, but could you help me figure out what’s wrong?

     try {
            const cleanedNumber = smsNumber.replace(/[-\s]/g, "");
            const formattedNumber = `+82-${cleanedNumber.slice(-10)}`;

            const web3authProvider = await web3auth.connectTo(WALLET_ADAPTERS.AUTH, {
                loginProvider: "sms_passwordless",
                extraLoginOptions: {
                    login_hint: formattedNumber,
                },
            });
            

            if (web3auth.connected) {
                initProvider();
            }
            setLoggedIn(true);

        } catch (error) {
            console.error("Login failed:", error);
        }

and this problems seems to show only when i test at http://192.168.0.5:3000 (example IP)
It works fine on localhost:3000.

Thank You!

Hi Do Yeon Kim!

Let’s address your two concerns one by one:

1. Maintaining Login State after Page Refresh:

The issue of losing web3auth.connect upon refreshing the page indicates there might be a problem with session management. Typically, you’d need to save the user’s session information to local storage or a cookie and then reinitialize it on page load. However, in version 9, the Web3AuthNoModal SDK should manage sessions via its internal mechanisms.

Here’s a general approach:

  • After a successful login, store the necessary session or user details in localStorage or sessionStorage.
  • On page load, check if this data exists and if so, reinitialize web3auth using this information.

Unfortunately, detailed code snippets specific to this scenario may require some tweaks depending on your setup. Your current snippet does not show how you’re managing session data. Perhaps adding some logic to store the user’s state after login would solve your problem.

2. Error on connectTo function call after upgrading to version 9:

The error you’re seeing related to the connectTo function could be due to a few underlying issues with how the function is being called or how the adapter is configured.

Your error screenshot is essential here; however, it is not opening correctly. Could you try re-uploading or describing the error message?

General troubleshooting steps:

  1. Ensure your Web3Auth SDK and adapters are upgraded correctly.
  2. Verify that your adapters are correctly configured to accept the login providers.
  3. Ensure that your environment variables are set correctly in the context the app runs.

Given the structure of your code, it appears you’re doing many things right, but the inner workings of web3auth.connectTo might require a closer look.

Your current connectTo call:

const web3authProvider = await web3auth.connectTo(WALLET_ADAPTERS.AUTH, {
  loginProvider: "sms_passwordless",
  extraLoginOptions: {
    login_hint: formattedNumber,
  },
});

Let’s verify the following:

  • Ensure WALLET_ADAPTERS.AUTH is correctly defined and imported.
  • Validate that loginProvider: "sms_passwordless" is supported correctly.
  • If possible, try catching errors around this call to get more insights:
try {
  const web3authProvider = await web3auth.connectTo(WALLET_ADAPTERS.AUTH, {
    loginProvider: "sms_passwordless",
    extraLoginOptions: {
      login_hint: formattedNumber,
    },
  });
} catch(e) {
  console.error('ConnectTo error:', e);
}

Could you provide more details if the error persists or if specific errors are shown in the console?

This response was generated by the Web3Auth Bot. A member of our support team will further review and provide a detailed solution to your inquiry shortly. Thank you!

Hey @doyeon.kim,

Please have a look at our Next.js No Modal Example. You can see how we’ve used useEffect to maintain the session after a page refresh. This should help you resolve the issue of losing the user’s login state after a refresh. Let me know if you have any questions!

Thanks for your help!

I have another question, is this tihe safe way to get user’s private key?
and is this code still available at version 9?

const privateKey = await web3auth.provider.request({
                    method: "eth_private_key"
                });


or is there any signing function on Web3auth version 9?

Hey @doyeon.kim,

If you’re requesting the private key just to sign or send a transaction, check out this code snippet here.

Using the provider returned by Web3Auth upon login, when using ethers.js, you can get an ethersProvider by passing it into the BrowserProvider constructor. From there, you can obtain a signer to send a transaction or sign a message, eliminating the need to explicitly use the private key unless absolutely required.

Also, Web3Auth now offers an option to disable private key export via the dashboard. Navigate to the Add-on tab in your project’s dashboard and switch off the “Enable Key Export” toggle.

HI

i no longer need to get Private Key
I found the signing logic without getting Private key,
but the error happened

can you help?

              useEffect(() => {
        const handleOnsitePayment = async () => {
            if (password.length === 6) {
                try {
                    if (!web3auth.provider) {
                        await initWeb3auth();
                        initProvider()
                      }

                      if (web3auth.provider && provider) {
                        
                        const signer = await provider.getSigner();
                        const timeStamp = String(Date.now());
                        const signature = await signer.signMessage(timeStamp);
              
                        await onSitePayment(signature, timeStamp, userId, storeId, totalAmount, paymentType, password);
                      }

                    router.replace("/payment/onsite/complete");
                } catch (error) {
                    router.replace(`/payment/onsite/error?message=${error}`);
                }
            }
        };

        handleOnsitePayment();
    }, [password]);


this is error message
i think const signer = await provider.getSigner(); this is the error spot

and i want ethers v6 code! Sample code seems v5

Hey @doyeon.kim,

Just to clarify, the commented-out code is for ethers v5. If you’re working with ethers v6, please use the uncommented code. We maintain both versions to support different users, depending on the version they’re using.

As for the error you’re facing, the provider is always available, so instead of using the conditional:

if (web3auth.provider && provider) {

Please replace it with:

if (web3auth.status === "connected") {

This ensures that the user is authenticated and that Web3Auth has returned a compatible provider that works with ethers.