Skip to main content

Installation

npm install @web3auth/modal @tanstack/react-query viem

Setup Instructions

1

Create Web3Auth Project

  1. Visit the Web3Auth Dashboard
  2. Create a new project or select an existing one
  3. Configure your project settings and authentication methods
  4. Enable Smart Accounts
  5. Copy your Client ID from project settings
2

Get Gelato API Key

  1. Visit the Gelato App
  2. Navigate to Paymaster & Bundler > API Keys
  3. Create a new API Key and select your required networks
  4. Copy the generated API Key
3

Set Environment Variables

Create a .env.local file in your project root:
NEXT_PUBLIC_CLIENT_ID=your_web3auth_client_id
NEXT_PUBLIC_GELATO_API_KEY=your_gelato_api_key

Implementation

1

Import Dependencies

import {
  Web3AuthProvider,
} from "@web3auth/modal/react";
import { WagmiProvider } from "@web3auth/modal/react/wagmi";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Web3AuthContextConfig } from "@web3auth/modal/react";
import { WEB3AUTH_NETWORK } from "@web3auth/modal";
import { baseSepolia } from "viem/chains";
2

Configure Providers

In the context configuration, add your network environment, network details, and smart account type.
const queryClient = new QueryClient();

const clientId = process.env.NEXT_PUBLIC_CLIENT_ID as string;

const web3AuthContextConfig: Web3AuthContextConfig = {
  web3AuthOptions: {
    clientId,
    web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET,
    accountAbstractionConfig: {
      smartAccountType: "metamask",
      chains: [
        {
          chainId: toHex(baseSepolia.id),
          bundlerConfig: {
            url: `https://api.gelato.digital/bundlers/${baseSepolia.id}/rpc?apiKey=${process.env.NEXT_PUBLIC_GELATO_API_KEY}&sponsored=true`,
          },
        },
      ],
    },
  },
};

export function Providers() {
  return (
    <Web3AuthProvider config={web3AuthContextConfig}>
      <QueryClientProvider client={queryClient}>
        <WagmiProvider>
          <App />
        </WagmiProvider>
      </QueryClientProvider>
    </Web3AuthProvider>
  );
}
3

Create Bundler Client

import { useWeb3Auth, useWeb3AuthConnect } from "@web3auth/modal/react";
import { zeroAddress } from "viem";

function App() {
  const { web3Auth, status } = useWeb3Auth();
  const { connect, loading, isConnected, error } = useWeb3AuthConnect();

  const createBundlerClient = async () => {   
    const accountAbstractionProvider = web3Auth?.accountAbstractionProvider;
    
    if (!accountAbstractionProvider) {
      console.error("Account abstraction provider not available");
      return;
    }

    const bundlerClient = accountAbstractionProvider.bundlerClient;
    const smartAccount = accountAbstractionProvider.smartAccount;

    if (!bundlerClient || !smartAccount) {
      console.error("Bundler client or smart account not available");
      return;
    }

    console.log("Bundler client:", bundlerClient);
  };

  return (
    <div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
      <button onClick={() => connect()}>Connect</button>
      <div>
        <p>Status: {status}</p>
        <p>Loading: {loading ? "Yes" : "No"}</p>
        <p>Is Connected: {isConnected ? "Yes" : "No"}</p>
        <p>Error: {error ? error.message : "No error"}</p>
      </div>
      <button onClick={createBundlerClient}>Create Bundler Client</button>
    </div>
  );
}
4

Send User Operations

const results = await bundlerClient.sendUserOperation({
  calls: [{
    to: "0xa8851f5f279eD47a292f09CA2b6D40736a51788E",
    data: "0xd09de08a",
    value: BigInt(0),
  }],
  maxFeePerGas: BigInt(0),
  maxPriorityFeePerGas: BigInt(0),
  account: smartAccount,
});

console.log("User operation result:", results);

Additional Resources