Web3Auth isn’t a wallet itself, but serves as an essential wallet infrastructure that can be integrated seamlessly into any application. Its primary function is to offer more tailored flows for decentralized applications (dApps) or even blockchain wallets alike, solving the user onboarding and key management problem.

Users can easily login with a number of different platforms such as Twitter or Google mail. An Etherspot smart contract wallet is then created for them and they are ready to interact with your dapp.

Start by installing the Web3Auth packages:

npm
npm i @web3auth/[email protected] --save
npm i @web3auth/[email protected] --save
npm i @web3auth/[email protected] --save

Below is a code example of how get up and running with social logins.

import React from 'react';
import styled from 'styled-components';
import { Web3AuthNoModal } from '@web3auth/no-modal';
import { OpenloginAdapter } from '@web3auth/openlogin-adapter';
import { CHAIN_NAMESPACES, WALLET_ADAPTERS } from '@web3auth/base';
import { Oval } from 'react-loader-spinner';
import { LOGIN_PROVIDER } from '@toruslabs/base-controllers';
import { PrimeSdk, Web3WalletProvider } from '@etherspot/prime-sdk';
import { ethers } from 'ethers';

// Initialise web3auth with our custom values
const web3auth = new Web3AuthNoModal({
  chainConfig: {
    chainNamespace: "eip155",
    chainId: "hex chain id",
  },
  clientId: "client id from web3auth dashboard",
});

// Define the openLoginAdapter
const openloginAdapter = new OpenloginAdapter();
web3auth.configureAdapter(openloginAdapter);

const App = () => {
  const [isConnecting, setIsConnecting] = React.useState(false);
  const [errorMessage, setErrorMessage] = React.useState('');
  const [walletAddress, setWalletAddress] = React.useState('');

  // Logout function to clear web3auth cache
  const logout = async () => {
    setWalletAddress('');
    try {
      await web3auth.logout({ cleanup: true });
      web3auth.clearCache();
    } catch (e) {
      console.error(e);
    }
  }

  // Function to pass in specific platform to web3auth
  // E.g Twitter, gmail
  const loginWithProvider = async (loginProvider: string) => {
    if (isConnecting) return;
    setIsConnecting(true);
    setErrorMessage('');
    setWalletAddress('');
    let newErrorMessage;

    if (web3auth.status !== 'connected') {
      await web3auth.init();
      try {
        // Auth via loginProvider
        await web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, {
          loginProvider,
          mfaLevel: 'none',
        });
      } catch (e) {
        // @ts-ignore
        newErrorMessage = e?.message;
      }
    }

    if (newErrorMessage) {
      setErrorMessage(newErrorMessage);
      setIsConnecting(false);
    }

    if (web3auth.status !== 'connected' || !web3auth.provider) {
      setErrorMessage('Something went wrong, please try again later.');
      setIsConnecting(false);
    }

    // Initialising web3Auth Provider as Web3 Injectable
    const mappedProvider = new Web3WalletProvider(web3auth.provider);
    await mappedProvider.refresh();

    // Instantiate Etherspot Prime SDK with wrapped web3auth provider
    const etherspotPrimeSdk = new PrimeSdk(mappedProvider, {
      chainId: ethers.BigNumber.from(process.env.WEB3AUTH_CHAIN_ID_HEX as string).toNumber()
    });
    // Get smart account address
    try {
      const address = await etherspotPrimeSdk.getCounterFactualAddress();
    } catch (e) {
      console.error(e);
    }

    if (!address) {
      setErrorMessage('Something went wrong, please try again later.');
      setIsConnecting(false);
    }

    // Set smart wallet address generated by Etherspot Prime SDK
    setWalletAddress(address);
    setIsConnecting(false);
  }

  // GUI
  return (
    <Wrapper>
      {walletAddress && (
        <ConnectedWallet>
          <ConnectedWalletTitle>
            Your address on Ethereum blockchain:
          </ConnectedWalletTitle>
          <ConnectedWalletText>
            <strong>{walletAddress}</strong>
          </ConnectedWalletText>
          <LogoutButton onClick={logout}>Logout</LogoutButton>
        </ConnectedWallet>
      )}
      {isConnecting && (
        <Oval
          height={30}
          width={30}
          color="#fff"
          secondaryColor="#cc29ff"
          strokeWidth={6}
          strokeWidthSecondary={6}
          wrapperStyle={{ display: 'flex', justifyContent: 'center' }}
        />
      )}
      {!isConnecting && !walletAddress && (
        <>
          <ConnectButton onClick={() => loginWithProvider(LOGIN_PROVIDER.GOOGLE)}>
            Login with Google
          </ConnectButton>
          <ConnectButton onClick={() => loginWithProvider(LOGIN_PROVIDER.LINKEDIN)}>
            Login with LinkedIn
          </ConnectButton>
          <ConnectButton onClick={() => loginWithProvider(LOGIN_PROVIDER.GITHUB)}>
            Login with GitHub
          </ConnectButton>
        </>
      )}
      {errorMessage && <ErrorMessage>{errorMessage}</ErrorMessage>}
    </Wrapper>
  )
}

export default App;