Etherspot has partnered with Web3Auth, to bring users a frictionless Web3 experience by combining the power of Web3auth’s social login onboarding and Etherspot’s Smart Wallet infrastructure.
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.
You should have installed the appropriate Etherspot Prime and Web3Auth packages before proceeding.
Packages
Below is an example of a working Web3Auth social login implementation using the Etherspot Prime SDK.
A full example which you can build and deploy can be found here.
Variables to replace
WEB3AUTH_CHAIN_ID_HEX is the chain id in hex, for example 0xaa36a7 for Sepolia.
For the Etherspot Prime SDK part of this we only look at:
- If it’s a chain we support.
- Whether it’s a mainnet or test net chain. Then we only generate wallets on either of these.
WEB3AUTH_CLIENT_ID is the web3auth client id specific to your project. You can learn at how to get one here.
Code example
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';
const web3auth = new Web3AuthNoModal({
chainConfig: {
chainNamespace: "eip155",
chainId: process.env.WEB3AUTH_CHAIN_ID_HEX,
},
clientId: process.env.WEB3AUTH_CLIENT_ID as string,
});
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('');
const logout = async () => {
setWalletAddress('');
try {
await web3auth.logout({ cleanup: true });
web3auth.clearCache();
} catch (e) {
console.error(e);
}
}
const loginWithProvider = async (loginProvider: string) => {
if (isConnecting) return;
setIsConnecting(true);
setErrorMessage('');
setWalletAddress('');
let newErrorMessage;
if (web3auth.status !== 'connected') {
await web3auth.init();
try {
await web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, {
loginProvider,
mfaLevel: 'none',
});
} catch (e) {
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);
}
const mappedProvider = new Web3WalletProvider(web3auth.provider);
await mappedProvider.refresh();
const etherspotPrimeSdk = new PrimeSdk(mappedProvider, {
chainId: ethers.BigNumber.from(process.env.WEB3AUTH_CHAIN_ID_HEX as string).toNumber()
});
try {
const address = await etherspotPrimeSdk.getCounterFactualAddress();
} catch (e) {
console.error(e);
}
if (!address) {
setErrorMessage('Something went wrong, please try again later.');
setIsConnecting(false);
}
setWalletAddress(address);
setIsConnecting(false);
}
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;