When a new user logs in, they do not yet have a Web3 wallet by default. You can create a wallet for them by calling the createWallet function on the user object. Here’s a basic example:
The useUser hook returns a user context object that provides access to the base library's user object in the 'user' field, and adds some Web3 specific fields. The returned object has different types depending on these cases:
If the user has a wallet,
typeExistingWeb3UserContext=UserContext& { walletAddress:"0x..."// the address of the embedded wallet wallet:// a Viem WalletClient}
An easy way to distinguish between the two is to use the userHasWallet type guard.
Using the Wallet
The CivicAuth Web3 SDK uses Wagmi and Viem to expose the embedded wallet to your app, simplifying wallet interactions on both the front end and back end.
React Apps: Civic Auth is optimized for React, with easy access to Wagmi hooks for a seamless experience.
Non-React Apps: For non-React frameworks, use Viem directly to interact with the wallet.
Using the Wallet with Wagmi
To use the embedded wallet with Wagmi, follow these steps:
Ensure you have created the user's wallet first as described above.
1. Add the Embedded Wallet to Wagmi Config
Include embeddedWallet() in your Wagmi configuration as shown below:
Initiate the connection to the embedded wallet using Wagmi’s connect method.
const { connectors,connect } =useConnect();// connect to the "civic" connectorconstconnector= connectors[0];connect(connector);
Use Wagmi Hooks
Once connected, you can use Wagmi hooks to interact with the embedded wallet. Common hooks include:
useBalance: Retrieve the wallet balance.
useAccount: Access account details.
useSendTransaction: Send transactions from the wallet.
useSignMessage: Sign messages with the wallet.
For more detailed documentation on how to use these hooks, see the Wagmi docs.
A Full Example
See below for a full minimal example of a Wagmi app using Civic Auth for an embedded wallet. This is based on this GitHub repository that contains a sample implementation.
import { QueryClient, QueryClientProvider } from"@tanstack/react-query";import { WagmiProvider, createConfig, useAccount, useConnect, useBalance, http } from'wagmi';import { embeddedWallet, userHasWallet } from'@civic/auth-web3';import { CivicAuthProvider, UserButton, useUser } from'@civic/auth-web3/react';import { mainnet, sepolia } from"wagmi/chains";constwagmiConfig=createConfig({ chains: [ mainnet, sepolia ], transports: { [mainnet.id]:http(), [sepolia.id]:http(), }, connectors: [embeddedWallet(), ],});// Wagmi requires react-queryconstqueryClient=newQueryClient();// Wrap the content with the necessary providers to give access to hooks: react-query, wagmi & civic auth providerconstApp= () => {return (<QueryClientProvider client={queryClient}><WagmiProvider config={wagmiConfig}><CivicAuthProvider clientId="< YOUR CLIENT ID >"><AppContent /></CivicAuthProvider></WagmiProvider></QueryClientProvider> );};// Separate component for the app content that needs access to hooksconstAppContent= () => {// The civic user hookconstuserContext=useUser();// Add the wagmi hooksconst { connect,connectors } =useConnect();const { isConnected } =useAccount();constbalance=useBalance({ address:userHasWallet(userContext) ?userContext.walletAddress as`0x${string}`:undefined, });// A function to connect to an existing civic embedded walletconstconnectExistingWallet= () =>connect({ connector: connectors[0], });// A function that creates the wallet if the user doesn't have one alreadyconstcreateWallet= () => {if (userContext.user &&!userHasWallet(userContext)) {// Once the wallet is created, we can connect it straight awayreturnuserContext.createWallet().then(connectExistingWallet) } }return (<><UserButton /> {userContext.user && <div> {!userHasWallet(userContext) && <p><button onClick={createWallet}>Create Wallet</button></p> } {userHasWallet(userContext) && <> <p>Wallet address: {userContext.walletAddress}</p> <p>Balance: { balance?.data ? `${(BigInt(balance.data.value) / BigInt(1e18)).toString()} ${balance.data.symbol}` : 'Loading...' }</p> {isConnected ? <p>Wallet is connected</p> : ( <button onClick={connectExistingWallet}>Connect Wallet</button> )} </> } </div> }</> );};exportdefault App;
Using the Wallet with Viem
If you are not using Wagmi, you may also use Viem directly to access the same wallet capabilities: