Error: WalletLoginError: Failed to connect with wallet. Already connected

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

  • SDK Version: 7.3.1
  • Platform: Mac
  • Browser Console Screenshots:

Also, kindly provide the Web3Auth initialization and login code snippet below. This will help us better understand your issue and provide you with the necessary assistance.

"use client";

// Web3AuthContext.tsx

import React, {createContext, useEffect, useState} from "react";
import {Web3AuthNoModal} from "@web3auth/no-modal";
import RPC from "../web3auth/web3RPC";

import {EthereumPrivateKeyProvider} from "@web3auth/ethereum-provider";
import {
  CHAIN_NAMESPACES,
  IProvider,
  ADAPTER_EVENTS,
  WALLET_ADAPTERS,
  CONNECTED_EVENT_DATA,
  ADAPTER_STATUS,
} from "@web3auth/base";
import {OpenloginAdapter, OpenloginUserInfo} from "@web3auth/openlogin-adapter";
// import {subscribeAuthEvents} from "../web3auth/Web3AuthHelpers";
import {
  getPolygonAddress,
  getBnbAddress,
  getSolanaAddress,
  getTezosAddress,
  getStarkExAddress,
  getStarkNetAddress,
  getPolkadotAddress,
  getEthereumAddress,
} from "../web3auth/ChainProviders";
import {error} from "console";

interface Web3AuthContextType {
  web3auth: Web3AuthNoModal | null;
  login: () => Promise<void>;
  logout: () => Promise<void>;
  isLoading: boolean;
  isLoggedIn: boolean;
  user: Partial<OpenloginUserInfo> | null;
  authenticateUser: () => Promise<void>;
  sendTransaction: () => Promise<void>;
  signMessage: () => Promise<void>;

  userAccounts: {
    polygon: string;
    bnb: string;
    solana: string;
    tezos: string | undefined;
    starkEx: string;
    starkNet: string;
    polkadot: string | undefined;
  } | null;
}

const Web3AuthContext = createContext<Web3AuthContextType | undefined>(
  undefined
);

interface Web3AuthProviderProps {
  children: React.ReactNode;
}

export const Web3AuthProvider: React.FC<Web3AuthProviderProps> = ({
  children,
}) => {
  const [web3auth, setWeb3Auth] = useState<Web3AuthNoModal | null>(null);
  const [provider, setProvider] = useState<IProvider | null>(null);
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
  const [user, setUser] = useState<Partial<OpenloginUserInfo> | null>(null);
  const [userAccounts, setUserAccounts] = useState<{
    polygon: string;
    bnb: string;
    solana: string;
    tezos: string | undefined;
    starkEx: string;
    starkNet: string;
    polkadot: string | undefined;
  } | null>(null);

  useEffect(() => {
    const init = async () => {
      try {
        const clientId =
          client_id

        // ETH_Goerli
        const chainConfig = {
          chainNamespace: CHAIN_NAMESPACES.EIP155,
          chainId: "0x1",
          rpcTarget: "https://rpc.ankr.com/eth",
          displayName: "Ethereum Mainnet",
          blockExplorer: "https://goerli.etherscan.io",
          ticker: "ETH",
          tickerName: "Ethereum",
        };

        const web3authInstance: Web3AuthNoModal = new Web3AuthNoModal({
          clientId,
          chainConfig,
          web3AuthNetwork: "sapphire_devnet",
        });

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

        const openloginAdapter = new OpenloginAdapter({
          privateKeyProvider: privateKeyProvider,
          loginSettings: {
            mfaLevel: "mandatory",
          },
          adapterSettings: {
            whiteLabel: {
              appName: "Your app Name",
              logoLight: "https://web3auth.io/images/web3auth-logo.svg",
              logoDark: "https://web3auth.io/images/web3auth-logo---Dark.svg",
              defaultLanguage: "en",
              mode: "auto", // "light" or "dark" or "auto"
            },
            loginConfig: {
              google: {
                name: "google",
                verifier: "google_auth",
                typeOfLogin: "google",
                clientId:
                  "googleclient_id",
              },
            },
            mfaSettings: {
              deviceShareFactor: {
                enable: true,
                priority: 1,
                mandatory: true,
              },
              backUpShareFactor: {
                enable: true,
                priority: 2,
                mandatory: false,
              },
              socialBackupFactor: {
                enable: true,
                priority: 3,
                mandatory: false,
              },
              passwordFactor: {
                enable: true,
                priority: 4,
                mandatory: false,
              },
            },
          },
        });

        web3authInstance.configureAdapter(openloginAdapter);

        await web3authInstance.init();
        subscribeAuthEvents(web3authInstance);

        setWeb3Auth(web3authInstance);
        setProvider(web3authInstance.provider);
      } catch (error) {
        console.error(error);
      }
    };

    init();

 
    };
  }, []);

 

  const handleLogin = async () => {
    if (!web3auth) {
      console.log("web3auth not initialized yet");
      return;
    }

    try {
      setIsLoading(true);
      console.log(!!web3auth);
      console.log("before :", isLoading, isLoggedIn);

      if (web3auth.status !== ADAPTER_STATUS.CONNECTED) {
        await web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, {
          loginProvider: "google",
        });
        setIsLoading(false);
        setIsLoggedIn(true);
        return;
      }

      const web3authProvider = await web3auth.connectTo(
        WALLET_ADAPTERS.OPENLOGIN,
        {
          loginProvider: "google",
        }
      );
      console.log("Logged in Successfully!");
      setIsLoading(false);
      setIsLoggedIn(true);
      setProvider(web3authProvider);
      const loggedInUser = await web3auth?.getUserInfo();
      setUser(loggedInUser);

      const accounts = await fetchUserAccounts(provider);
      setUserAccounts(accounts);

      console.log(isLoggedIn);
    } catch (error) {
      console.log("error: ", error);
    }
  };

  const handleLogout = async () => {
    if (!web3auth) {
      console.log("web3auth not initialized yet");
      return;
    }
    await web3auth.logout();
    setWeb3Auth(null);
    setProvider(null);
    setUser(null); // Clear user data on logout
    setUserAccounts(null);
    setIsLoading(false);
    setIsLoggedIn(false);
  };

  const subscribeAuthEvents = (web3auth: Web3AuthNoModal): void => {
    web3auth.on(ADAPTER_EVENTS.CONNECTED, (data: CONNECTED_EVENT_DATA) => {
      console.log("connected to wallet", data);
      // web3auth.provider will be available here after the user is connected
    });

    web3auth.on(ADAPTER_EVENTS.CONNECTING, () => {
      console.log("connecting");
    });

    web3auth.on(ADAPTER_EVENTS.DISCONNECTED, () => {
      console.log("disconnected");
    });

    web3auth.on(ADAPTER_EVENTS.ERRORED, (error) => {
      console.log("error", error);
    });
  };

  const fetchUserAccounts = async (provider: IProvider | null) => {
    try {
      const polygon = await getPolygonAddress(provider);
      const bnb = await getBnbAddress(provider);
      const solana = await getSolanaAddress(provider);
      const tezos = await getTezosAddress(provider);
      const starkEx = await getStarkExAddress(provider);
      const starkNet = await getStarkNetAddress(provider);
      const polkadot = await getPolkadotAddress(provider);
      const ethereum = await getEthereumAddress(provider);

      return {
        polygon,
        bnb,
        solana,
        tezos,
        starkEx,
        starkNet,
        polkadot,
        ethereum,
      };
    } catch (error) {
      console.error("Error fetching user accounts:", error);
      return null;
    }
  };

  const authenticateUser = async () => {
    try {
      if (!web3auth) {
        console.log("web3auth not initialized yet");
        return;
      }

      const idToken = await web3auth.authenticateUser();
      console.log(idToken);
    } catch (error) {
      console.log("Authentication error: " + error);
    }
  };

  const sendTransaction = async () => {
    try {
      if (!provider) {
        console.log("provider not initialized yet");
        return;
      }

      const rpc = new RPC(provider);
      const receipt = await rpc.sendTransaction();
      console.log(receipt);
    } catch (error) {
      console.log("Send Transaction error: " + error);
    }
  };

  const signMessage = async () => {
    try {
      if (!provider) {
        console.log("provider not initialized yet");
        return;
      }

      const rpc = new RPC(provider);
      const signedMessage = await rpc.signMessage();
      console.log(signedMessage);
    } catch (error) {
      console.log("Sign Message error: " + error);
    }
  };

  return (
    <Web3AuthContext.Provider
      value={{
        web3auth,
        login: handleLogin,
        logout: handleLogout,
        isLoading,
        isLoggedIn,
        user,
        userAccounts,
        authenticateUser,
        sendTransaction,
        signMessage,
      }}
    >
      {children}
    </Web3AuthContext.Provider>
  );
};

export const useWeb3Auth = (): Web3AuthContextType => {
  const context = React.useContext(Web3AuthContext);
  if (!context) {
    throw new Error("useWeb3Auth must be used within a Web3AuthProvider");
  }
  return context;
};

I’m exporting this as a provider for use in another file with “useWeb3auth()” but for some reason the state for logging in is not updating accordingly and I’m getting a wallet already connected error, and when I logout and try to login again, I get a web3auth not initialized error

@prinzuty Welcome Aboard!

This error means that your initialization function is not properly executed.

Use the following in this order:

  • Instantiate Web3Auth
  • Instantiate Openlogin Adapter
  • web3auth.configureAdapter(openloginAdapter);
  • await web3auth.initModal();
  • await web3auth.connect();

For the Web3Auth events, please ensure to call init() after registering the event handler as shown in the example below:

1 Like

Hi vjgee, i’m using the NoModal and when I try to use web3auth.connect in my login function, its not an option, I only get connectTo

this is my instantiation

  useEffect(() => {
    const init = async () => {
      try {
        const clientId =
          "client_id"
        // ETH_Goerli
        const chainConfig = {
          chainNamespace: CHAIN_NAMESPACES.EIP155,
          chainId: "0x1",
          rpcTarget: "https://rpc.ankr.com/eth",
          displayName: "Ethereum Mainnet",
          blockExplorer: "https://goerli.etherscan.io",
          ticker: "ETH",
          tickerName: "Ethereum",
        };

        const web3authInstance: Web3AuthNoModal = new Web3AuthNoModal({
          clientId,
          chainConfig,
          web3AuthNetwork: "sapphire_devnet",
        });

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

        const openloginAdapter = new OpenloginAdapter({
          privateKeyProvider: privateKeyProvider,
          loginSettings: {
            mfaLevel: "mandatory",
          },
          adapterSettings: {
            whiteLabel: {
              appName: "Your app Name",
              logoLight: "https://web3auth.io/images/web3auth-logo.svg",
              logoDark: "https://web3auth.io/images/web3auth-logo---Dark.svg",
              defaultLanguage: "en",
              mode: "auto", // "light" or "dark" or "auto"
            },
            loginConfig: {
              google: {
                name: "google",
                verifier: "google_auth",
                typeOfLogin: "google",
                clientId:
                  "myId"
              },
            },
            mfaSettings: {
              deviceShareFactor: {
                enable: true,
                priority: 1,
                mandatory: true,
              },
              backUpShareFactor: {
                enable: true,
                priority: 2,
                mandatory: false,
              },
              socialBackupFactor: {
                enable: true,
                priority: 3,
                mandatory: false,
              },
              passwordFactor: {
                enable: true,
                priority: 4,
                mandatory: false,
              },
            },
          },
        });

        web3authInstance.configureAdapter(openloginAdapter);

        await web3authInstance.init();
        subscribeAuthEvents(web3authInstance);

        setWeb3Auth(web3authInstance);
        setProvider(web3authInstance.provider);
      } catch (error) {
        console.error(error);
      }
    };

    init();

  }, []);

and I connect it here

const handleLogin = async () => {
    if (!web3auth) {
      console.log("web3auth not initialized yet");
      return;
    }

    try {
      setIsLoading(true);
      console.log(!!web3auth);
      console.log("before :", isLoading, isLoggedIn);

      const web3authProvider = await web3auth.connectTo(
        WALLET_ADAPTERS.OPENLOGIN,
        {
          loginProvider: "google",
        }
      );
      console.log("Logged in Successfully!");
      setIsLoading(false);
      setIsLoggedIn(true);
      setProvider(web3authProvider);
      const loggedInUser = await web3auth?.getUserInfo();
      setUser(loggedInUser);

      const accounts = await fetchUserAccounts(provider);
      setUserAccounts(accounts);

      console.log(isLoggedIn);
    } catch (error) {
      console.log("error: ", error);
    }
  };

okay I believe I’ve figured out the login issue, but now when I try to get all of the user’s accounts with fetchUserAccounts(provider) I get undefined, but I have set the provider useState during initialization

Hey @prinzuty,
I hope you are ensuring to use the keyword await while fetching the user accounts, since this is an asynchronous line of code.
If you are, then please share the method fetchUserAccounts that accepts a provider to return user accounts.

Hi @maharshi, yes I’m using the await,

const accounts = await fetchUserAccounts(web3auth.provider);
        setUserAccounts(accounts);

and this is the function

const fetchUserAccounts = async (provider: IProvider | null) => {
    try {
      const polygon = await getPolygonAddress(provider);
      const bnb = await getBnbAddress(provider);
      const solana = await getSolanaAddress(provider);
      const tezos = await getTezosAddress(provider);
      const starkEx = await getStarkExAddress(provider);
      const starkNet = await getStarkNetAddress(provider);
      const polkadot = await getPolkadotAddress(provider);
      const ethereum = await getEthereumAddress(provider);

      return {
        polygon,
        bnb,
        solana,
        tezos,
        starkEx,
        starkNet,
        polkadot,
        ethereum,
      };
    } catch (error) {
      console.error("Error fetching user accounts:", error);
      return null;
    }
  };

Hey @prinzuty
Thanks for the code snippet. I see no reason why you should get undefined. By any chance, have you pushed this code to some repo that you could share so that I can try it out on my local?

Okay so I found the issue while looking at another post, apparently, web3auth still doesn’t work well with web3 version 4.0 and up. You have to downgrade to 1.8 or below.

Nonetheless, I ran into another issue, how come if you store clientIDs in a .env file, web3auth cannot read it? Thanks!