Skip to main content

Installation

npm install @coinbase/cdp-react @coinbase/cdp-hooks @coinbase/cdp-core viem

Setup Instructions

1

Create Coinbase CDP Project

  1. Visit the Coinbase CDP Portal
  2. Create a new project or select an existing one
  3. Configure your project settings
  4. Copy your Project 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_PROJECT_ID=your_coinbase_cdp_project_id
NEXT_PUBLIC_GELATO_API_KEY=your_gelato_api_key

Implementation

1

Import Dependencies

import { CDPReactProvider } from "@coinbase/cdp-react";
import { AuthButton } from "@coinbase/cdp-react/components/AuthButton";
import { useCurrentUser, useEvmAddress } from "@coinbase/cdp-hooks";
import { toViemAccount } from "@coinbase/cdp-core";
import { baseSepolia } from "viem/chains";
import { createPublicClient, http } from "viem";
import {
  createBundlerClient,
  toCoinbaseSmartAccount,
} from "viem/account-abstraction";
2

Configure Providers

Set up the CDP React Provider in your app:
"use client";

import { CDPReactProvider } from "@coinbase/cdp-react";

function Providers({ children }: { children: React.ReactNode }) {
  return (
    <CDPReactProvider
      config={{
        projectId: process.env.NEXT_PUBLIC_PROJECT_ID as string,
        ethereum: {
          createOnLogin: "eoa", 
        },
        appName: "Your App Name",
      }}
    >
      {children}
    </CDPReactProvider>
  );
}
3

Create Bundler Client

Set up your component to use Coinbase CDP hooks and create a bundler client:
"use client";

import { AuthButton } from "@coinbase/cdp-react/components/AuthButton";
import { useCurrentUser, useEvmAddress } from "@coinbase/cdp-hooks";
import { toViemAccount } from "@coinbase/cdp-core";
import { baseSepolia } from "viem/chains";
import { createPublicClient, http } from "viem";
import {
  createBundlerClient,
  toCoinbaseSmartAccount,
} from "viem/account-abstraction";

export default function Home() {
  const { evmAddress } = useEvmAddress();
  const { currentUser } = useCurrentUser();

  const createAccount = async () => {
    if (!currentUser?.evmAccounts) return;
    
    const viemAccount = await toViemAccount(currentUser?.evmAccounts[0]);

    const client = createPublicClient({
      chain: baseSepolia,
      transport: http(),
    });

    const account = await toCoinbaseSmartAccount({
      client,
      owners: [viemAccount],
      version: "1.1",
    });
    
    const bundlerClient = createBundlerClient({
      client: client,
      transport: http(
        `https://api.gelato.digital/bundlers/${baseSepolia.id}/rpc?apiKey=${process.env.NEXT_PUBLIC_GELATO_API_KEY}&sponsored=true`
      ),
    });

    console.log("Bundler client created:", bundlerClient);
    console.log("Smart account address:", account.address);
  };

  return (
    <div>
      <AuthButton />
      <div>{evmAddress}</div>
      <button onClick={createAccount}>Create Account</button>
    </div>
  );
}
4

Send User Operations

Send sponsored user operations using the bundler client:
const sendUserOperation = async () => {
  const response = await bundlerClient.sendUserOperation({
    account,
    calls: [
      {
        to: account.address,
        value: BigInt(0),
        data: "0x",
      },
    ],
    maxFeePerGas: BigInt(0),
    maxPriorityFeePerGas: BigInt(0),
  });

  console.log("User operation response:", response);
};

Additional Resources