Wgami V2 with Web3Auth Sfa Custom Auth Connecot

I have created the wagmi config for SFA it also get connected with the site as well but when i tried to use
Connector form useConnector() and try to get the user Account it says provider not found
here is the error


here is my code
of custom connector
import {
ChainNotConfiguredError,
createConnector,
normalizeChainId,
} from ‘@wagmi/core’;
import type { IWeb3Auth } from ‘@web3auth/base’;
import * as pkg from ‘@web3auth/base’;
import { Provider } from ‘@web3auth/web3auth-wagmi-connector’;
import {
Chain,
getAddress,
SwitchChainError,
UserRejectedRequestError,
} from ‘viem’;
import { googleLogout } from ‘@react-oauth/google’;
const { ADAPTER_STATUS, ADAPTER_EVENTS, CHAIN_NAMESPACES, log } = pkg;
interface ConnectParams {
chainId?: number;
loginParams?: any;
}

export function Web3AuthSFAConnector(parameters:any) {
  let walletProvider: Provider | null = null;
  const { web3AuthInstance ,loginParams} = parameters;

  return createConnector<Provider>((config) => ({
    id: 'web3auth-sfa',
    name: 'Web3Auth SFA',
    type: 'Web3Auth',
    async connect({ chainId }: ConnectParams = {}) {
      try {
        config.emitter.emit('message', {
          type: 'connecting',
        });
        const web3 = await web3AuthInstance;
        walletProvider = web3.provider;
        const provider = await this.getProvider();
        provider.on('accountsChanged', this.onAccountsChanged);
        provider.on('chainChanged', this.onChainChanged);
        provider.on('disconnect', this.onDisconnect.bind(this));

        // const provider = await this.getProvider();
        // provider.on('accountsChanged', this.onAccountsChanged);
        // provider.on('chainChanged', this.onChainChanged);
        // provider.on('disconnect', this.onDisconnect.bind(this));
        if (!web3.connected) {
          // Handling dynamic arguments for SFA connection
          console.log('WEB3 intance===>', await web3AuthInstance);
          const connector = await web3AuthInstance?.connect(loginParams);
          console.log('yoo--.', connector);
          web3AuthInstance.on(ADAPTER_EVENTS.CONNECTED, (data) => {
            walletProvider = web3AuthInstance.provider;
            console.log('IM CONNECTED WITH YOU ');
            config.emitter.emit('change', {
              accounts: data.accounts.map((x) => getAddress(x)),
              chainId: normalizeChainId(data.chainId),
            });
          });

          web3AuthInstance.on(ADAPTER_EVENTS.DISCONNECTED, () => {
            config.emitter.emit('disconnect');
          });
        } else {
          // web3AuthInstance.on(ADAPTER_EVENTS.CONNECTED, (data) => {
          //   console.log('IM CONNECTED WITH YOU ');
          //   config.emitter.emit('change', {
          //     accounts: data.accounts.map((x) => getAddress(x)),
          //     chainId: normalizeChainId(data.chainId),
          //   });
          // });
          walletProvider = web3AuthInstance.provider;
        }
        let currentChainId = await this.getChainId();
        if (chainId && currentChainId !== chainId) {
          const chain = await this.switchChain!({ chainId }).catch((error) => {
            if (error.code === UserRejectedRequestError.code) throw error;
            return { id: currentChainId };
          });
          currentChainId = chain?.id ?? currentChainId;
        }

        const accounts = await this.getAccounts();

        return { accounts, chainId: currentChainId };
      } catch (error) {
        log.error('error while connecting', error);
        this.onDisconnect();
        throw new UserRejectedRequestError(
          'Something went wrong' as unknown as Error,
        );
      }
    },
    async getAccounts() {
      const provider = await this.getProvider();
      console.log('hello world', provider);
      if (!provider) {
        console.log('provider not found',web3AuthInstance)
        console.log("PROVIDER NOT FOUND BRO WHAT ARE YOU DOING")
        if(web3AuthInstance) {
          return await web3AuthInstance.provider;
        }
      }
      const accounts:any =  await web3AuthInstance?.provider.request({ method: 'eth_accounts' })
      const acc = accounts?.map(
        getAddress,
      )
      console.log('got account',acc)
      return acc     
    },
    async getChainId() {
      const provider = await this.getProvider();
      const chainId = await provider.request<unknown, number>({
        method: 'eth_chainId',
      });
      return normalizeChainId(chainId);
    },
    async getProvider(): Promise<Provider> {
      try {

        if (walletProvider) {
          return walletProvider;
        }
        let web3 = await web3AuthInstance;
        if (loginParams && web3.status === ADAPTER_STATUS.READY) {
          await web3AuthInstance.connect(loginParams);
        }
        walletProvider = await web3.provider;
        console.log("Wallet Provdier",walletProvider,web3)
        return walletProvider as Provider;
      } catch (error) {
        console.log('Error while retrieving provider:', error);
        throw new Error('Failed to get provider');
      }
    },
    async isAuthorized() {
      try {
        const accounts = await this.getAccounts();
        return !!accounts.length;
      } catch {
        return false;
      }
    },
    async switchChain({ chainId }): Promise<Chain> {
      try {
        const chain = config.chains.find((x) => x.id === chainId);
        if (!chain) throw new SwitchChainError(new ChainNotConfiguredError());

        await web3AuthInstance.addChain({
          chainNamespace: CHAIN_NAMESPACES.EIP155,
          chainId: `0x${chain.id.toString(16)}`,
          rpcTarget: chain.rpcUrls.default.http[0],
          displayName: chain.name,
          blockExplorerUrl: chain.blockExplorers?.default.url[0] || '',
          ticker: chain.nativeCurrency?.symbol || 'ETH',
          tickerName: chain.nativeCurrency?.name || 'Ethereum',
          decimals: chain.nativeCurrency?.decimals || 18,
          logo: chain.nativeCurrency?.symbol
            ? `https://images.toruswallet.io/${chain.nativeCurrency?.symbol.toLowerCase()}.svg`
            : 'https://images.toruswallet.io/eth.svg',
        });

        await web3AuthInstance.switchChain({
          chainId: `0x${chain.id.toString(16)}`,
        });

        config.emitter.emit("change", {
          chainId,
        });

        return chain;
      } catch (error: unknown) {
        log.error('Error: Cannot change chain', error);
        throw new SwitchChainError(error as Error);
      }
    },
    async disconnect(): Promise<void> {
      await web3AuthInstance.logout();
      googleLogout();
      const provider = await this.getProvider();
      provider.removeListener('accountsChanged', this.onAccountsChanged);
      provider.removeListener('chainChanged', this.onChainChanged);
    },
    onAccountsChanged(accounts) {
      if (accounts.length === 0) config.emitter.emit("disconnect");
      else
        config.emitter.emit("change", {
          accounts: accounts.map((x) => getAddress(x)),
        });
    },
    onChainChanged(chain) {
      const chainId = normalizeChainId(chain);
      config.emitter.emit("change", { chainId });
    },
    onDisconnect(): void {
      config.emitter.emit("disconnect");
    },
  }));
}
  useEffect(() => {
    if (disabled) return;
    (async () => {
      const filteredConnectors = connectors.reduce(
        (acc, connector: Connector) => {
          if (acc.find((c) => c.id === connector.id)) return acc;
          return [...acc, connector];
        },
        [] as Connector[],
      );

      console.log(filteredConnectors, 'yoooo-->');

      const accountsPromises = filteredConnectors.map(async (connector) => {
        const connectorAddresses = await connector.getAccounts();
        const connectorAddress = connectorAddresses[0]?.toLowerCase();;
        if (!connectorAddresses.length) return;
        const smartAccount = await getSmartAccountClient({
          useWeb3Auth: connector.id === 'web3auth',
        });

        const isAuthorized = await connector.isAuthorized();
        if (!isAuthorized) return;

        if (!connectorAddress) return;
        if (
          connector.id === 'web3auth' &&
          (!smartAccount?.account?.address || !web3AuthInstance.connected)
        )
          return;

        const account = {
          address: (connector.id === 'web3auth'
            ? smartAccount?.account?.address ?? ''
            : connectorAddress) as Address,
          connector,
          isWeb3Auth: connector.id === 'web3auth',
          eoa: connectorAddress as Address,
        };
        return account;
      });

      const newAccounts: Account[] = (await Promise.all(accountsPromises))
        .filter((a) => !!a)
        .reduce((accounts, account) => {
          // remove duplicates
          if (!account) return accounts;
          if (accounts.find((a) => a.address === account.address))
            return accounts;
          return [...accounts, account];
        }, [] as Account[]) as Account[];

      if (newAccounts.length) setConnectedAddresses(newAccounts);
    })();
  }, [
    connectors,
    getSmartAccountClient,
    disabled,
    setConnectedAddresses,
    address,
  ]); this code im usgin to get my connector

Hi Parifi Dev,

Thanks for providing the detailed information and your code. From your description and the code snippets, it looks like you’re encountering a “provider not found” error when trying to get the user account using the useConnector() hook with the Web3Auth SFA custom auth connector in Wgami V2.

There might be a couple of areas to investigate, so I’ll summarize the provided information and indicate what’s in place and what might be helpful for further troubleshooting:

Key Details

  • SDK Details: Single Factor Auth Web SDK
  • Issue: “provider not found” error when fetching user account
  • Platform: Web
  • Code Snippets: Provided for both custom connector initialization and usage in useEffect
  • Error Screenshot: Provided

Important Observations

  • The provided error [object Object] suggests the provider is not available when it is trying to fetch the user accounts.
  • You are initializing the web3AuthInstance and potentially connecting it with login parameters.
  • There are check conditions to handle whether web3AuthInstance is ready and whether it is connected, which seem appropriate.

Potential Areas to Check

  1. Initialization and Connection Order: Ensure that the connect method gets called correctly and the web3AuthInstance.provider is properly set before any calls to getAccounts.

  2. Provider Assignment: There are multiple conditions checking web3AuthInstance status and setting walletProvider. Ensure this logic is flowing correctly, and the provider is accessible.

  3. Event Handlers and Provider Readiness: Verify if the event handlers (e.g., ADAPTER_EVENTS.CONNECTED) are setting the correct provider.

Debug Steps

  • Verify the web3AuthInstance Connection Status: During the initial load, log the web3AuthInstance status and ensure the connect call is successful.
  • Event Listeners: Ensure the ‘accountsChanged’, ‘chainChanged’, and ‘disconnect’ events are correctly set on the provider.
  • Provider Logs: Add logs before returning the provider in getProvider to trace its path and confirm it’s set correctly.

If you can share the exact initialization and login code snippets of the Web3Auth instance part, or any additional browser console logs, it would help pinpoint the issue further.

I’ll summarize the issue for the support team and they will be able to provide more precise guidance:

Issue Summary for Support Team

  • SDK: Single Factor Auth Web SDK
  • Platform: Web
  • Problem: “provider not found” error while fetching user accounts using the useConnector() hook in Wgami V2 setup.
  • Relevant Code/Snippets: Custom connector code and useEffect using the connector are provided.
  • Error Screenshot: Provided
  • Additional Info Needed (if applicable): Initialization and login code for Web3Auth instance, and additional browser console logs/errors.

This response was generated by the Web3Auth Bot and a person from the Web3Auth team will come and provide an answer to your query as well.

Hey,

The Web3Auth WAGMI Connector doesn’t work for SFA integrations. You can check in this issue, where someone has raised something similar: Wagmi v2 with Web3auth SFA custom auth Connector - #5 by edmond

For this integration, you need to create your own wagmi connector You have to add the id token and everything directly into the connector code. Wagmi will only trigger login function, within which you need to do the authentication by your auth provider and also web3auth login. As mentioned our connector won’t support it since it doesn’t have the code to trigger login for your authentication service within it.

You can fork our connector and add your service inside the connect function and it should be working for you.

That being said, we are working on an example to help you create your own wagmi connector. Please give a us week, we will be publishing that.