Web3Auth.on('connected') is getting called multiple times

When I connect at first time that when I call loginWithGoogle or loginWithEmail and login.
The console CONNECTING and CONNECTED is coming multiple times and fetchAddress is getting called multiple times.

Any solution for this?

  • SDK Version(package.json):
"@web3auth/auth-adapter": "^9.4.0",
"@web3auth/base": "^9.4.0",
"@web3auth/base-provider": "^9.4.0",
"@web3auth/no-modal": "^9.4.0",
import { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { CommonPrivateKeyProvider } from "@web3auth/base-provider";
import { Web3AuthNoModal as Web3Auth } from "@web3auth/no-modal";
import { ADAPTER_EVENTS, WALLET_ADAPTERS, WEB3AUTH_NETWORK } from "@web3auth/base";
import { AuthAdapter } from "@web3auth/auth-adapter";
import {  UPDATE_AUTH_DETAILS } from "@reducers/account.reducer";
import { AUTH_TYPES, KEPLER_WEBSITE_LINK, chainID, web3AuthChainConfig, web3AuthCliedId } from "@root/constants";
import { getPublicCompressed } from "@toruslabs/eccrypto";
import accountServices from "@services/account.services";

let web3auth;

const initWeb3Auth = async () => {
  try {
    const privateKeyProvider = new CommonPrivateKeyProvider({
      config: { chainConfig: web3AuthChainConfig },
    });

    web3auth = new Web3Auth({
      clientId: web3AuthCliedId,
      privateKeyProvider,
      web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET,
    });

    const authAdapter = new AuthAdapter({
      adapterSettings: {},
    });

    web3auth.configureAdapter(authAdapter);
    await web3auth.init();
  } catch (error) {
    console.log("ERROR_INIT_WEB3AUTH", error);
  }
};
initWeb3Auth();

const useAuth = () => {
  const dispatch = useDispatch();
  const [loading, setLoading] = useState(false);
  const { accessToken, address,  authProvider } = useSelector(state => state.account.auth);

  const loginWithKeplr = async () => {
    try {
      if (!window.keplr) {
        window.open(KEPLER_WEBSITE_LINK);
        return;
      }
      await window.keplr.enable(chainID);
      const offlineSigner = window.keplr.getOfflineSigner(chainID);
      const accounts = await offlineSigner.getAccounts();
      const address = accounts[0].address;
      dispatch(UPDATE_AUTH_DETAILS({  accessToken: "", address, authProvider: AUTH_TYPES.KEPLR }));
    } catch (e) {
      console.log("ERROR_loginWithKeplr", e);
    }
  };
    
  const loginWithGoogle = async () => {
    try {
      if (!web3auth) { return;}
      await web3auth.connectTo(WALLET_ADAPTERS.AUTH, { loginProvider: "google" });
    } catch (e) {
      console.log("ERROR_loginWithGoogle", e);
    }
  };

  const loginWithEmail = async (email) => {
    try {
      if (!web3auth) { return;}
      await web3auth.connectTo(WALLET_ADAPTERS.AUTH, { extraLoginOptions: { login_hint: email }, loginProvider: "email_passwordless" });
    } catch (e) {
      console.log("ERROR_loginWithGoogle", e);
        
    }
  };

  const logout = useCallback( async () => {
    try {
      if (!web3auth) { return; }
      if (window.keplr) {
        await window.keplr.disable();
        dispatch(UPDATE_AUTH_DETAILS({  accessToken: "", address: "", authProvider: AUTH_TYPES.NONE  }));    
      }
      if (accessToken && accessToken.length > 0) {
        await web3auth.logout();
      }
    } catch (e) {
      console.log(e);
    }
  }, [accessToken, dispatch]);


    
  useEffect(() => {
    const fetchAddress = async () => {
      try {
        if (accessToken && accessToken.length > 0 && [AUTH_TYPES.EMAIL_PASSWORDLESS, AUTH_TYPES.GOOGLE].includes(authProvider)) {
          const details = await accountServices.fetchUserDetailsWithPublicKey({ publicKey: `${accessToken}` });
          const expiresIn = new Date(details?.expiredAt) - new Date();
          if (expiresIn > 0) {
            if (address.length === 0 && address !== details.sentinelAddress) {
              dispatch(UPDATE_AUTH_DETAILS({ address: details.sentinelAddress }));
            }
            return;
          }
          logout();
          return;
        }
      } catch (e) {
        console.log("ERROR_fetchAddress", e);
        return;
      } finally {
        setLoading(false);
      }
    };
    fetchAddress();
  }, [accessToken, address, authProvider, dispatch, logout]);

  const handleConnecting = () => {
    console.log("-- CONNECTING --");
    setLoading(true);
  };

  const handleConnected = useCallback(async () => {
    console.log("-- CONNECTED --");
    const user = await web3auth.getUserInfo();
    const idToken = await web3auth.authenticateUser();
    const privateKey = await web3auth.provider.request({ method: "private_key" });

    if (privateKey) {
      const appPubKey = getPublicCompressed(Buffer.from(privateKey.padStart(64, "0"), "hex")).toString("hex");
      const token = await accountServices.fetchPublicKey({ appPubKey, idToken: idToken.idToken });
      if (accessToken !== token && user.typeOfLogin !== authProvider) {
        dispatch(UPDATE_AUTH_DETAILS({ accessToken: token, authProvider: user.typeOfLogin }));
      }
    }
  }, [accessToken, authProvider, dispatch]);

  const handleDisconnected = useCallback(() => {
    console.log("-- DISCONNECTED --");
    dispatch(UPDATE_AUTH_DETAILS({ accessToken: "", address: "", authProvider: AUTH_TYPES.NONE }));
  }, [dispatch]);

  const handleErrored = () => {
    console.log("-- ERRORED --");
    setLoading(false);
  };

  useEffect(() => {
    web3auth.on(ADAPTER_EVENTS.CONNECTING, handleConnecting);
    web3auth.on(ADAPTER_EVENTS.CONNECTED, handleConnected);
    web3auth.on(ADAPTER_EVENTS.DISCONNECTED, handleDisconnected);
    web3auth.on(ADAPTER_EVENTS.ERRORED, handleErrored);

    return () => {
      web3auth.off(ADAPTER_EVENTS.CONNECTING, handleConnecting);
      web3auth.off(ADAPTER_EVENTS.CONNECTED, handleConnected);
      web3auth.off(ADAPTER_EVENTS.DISCONNECTED, handleDisconnected);
      web3auth.off(ADAPTER_EVENTS.ERRORED, handleErrored);
    };
  }, [dispatch, handleConnected, handleDisconnected]);


  return { loading, loginWithEmail, loginWithGoogle, loginWithKeplr, logout };
};


export default useAuth;

Hello Srinath! Thank you for reaching out with your issue about Web3Auth.on('connected') being called multiple times.

Here’s a summary of the information you’ve provided for our support team:

SDK Details:

  • SDK: PnP Web SDK
  • Version: @web3auth/auth-adapter: ^9.4.0, @web3auth/base: ^9.4.0, @web3auth/base-provider: ^9.4.0, @web3auth/no-modal: ^9.4.0

Issue Details:

  • Problem: Web3Auth.on('connected') is triggered multiple times, along with multiple calls to fetchAddress.

Code Snippet:

  • You’ve provided the relevant code snippet detailing the Web3Auth setup and the event handlers.

Proposed Considerations:

  1. Ensure that the event listeners are only added once when the component mounts.

  2. Double-check any additional calls that might inadvertently cause multiple logins or reconnections.

  3. Make sure you are not accidentally reinitializing the Web3Auth instance which could lead to multiple event listeners being attached.

If you have any console screenshots or additional logs regarding this issue, adding them would be quite helpful for the support team.

Feel free to share any further details or questions you might have!

Note: This response was generated by an AI bot and may require further verification. The Web3Auth support team has tracked this issue and will be responding as soon as possible.