> ## Documentation Index
> Fetch the complete documentation index at: https://seilabs-docs-evm-cookbook.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Thirdweb EIP-7702 Integration Guide

> Learn how to integrate thirdweb's Account Abstraction SDK with Sei network to build decentralized applications with seamless wallet connectivity.

## Overview

This guide shows how to integrate thirdweb's EIP-7702 Account Abstraction SDK into your dApp. EIP-7702 is the next generation of account abstraction. It lets externally owned accounts (EOAs) temporarily behave like smart contracts. This makes gasless transactions and advanced wallet features possible. Users do not need to migrate to new wallet addresses.

## What this guide covers

* Understanding EIP-7702
* Setting up a React application with thirdweb's EIP-7702 implementation
* Implementing social logins with smart account features
* Creating gasless transactions on Sei

## Prerequisites

Before you start, make sure that you have:

* Node.js v18 or later installed
* Basic knowledge of React and TypeScript
* A thirdweb account with an API key from the [thirdweb dashboard](https://thirdweb.com/dashboard)
* **For Sei Mainnet**: An active thirdweb Pay As You Go subscription (\$5/month minimum) for gas sponsorship

## What is EIP-7702?

EIP-7702 is an Ethereum Improvement Proposal that introduces native account abstraction. It lets EOAs temporarily delegate execution to smart contracts. This approach has several advantages over traditional ERC-4337 implementations:

* **Same address**: Users keep their existing EOA address. They do not need to migrate to a new smart contract wallet.
* **Native protocol support**: It is built into the protocol layer and does not need external bundler infrastructure.
* **Lower gas costs**: It is more efficient than ERC-4337, because it does not need separate UserOperation bundling.
* **Temporary delegation**: EOAs can temporarily act as smart contracts for a single transaction and then return to normal behavior.
* **Backward compatible**: It works with existing wallets and infrastructure without breaking changes.

## Sei network configuration

**Sei Testnet:**

* **RPC URL**: `https://evm-rpc-testnet.sei-apis.com`
* **Chain ID**: 1328
* **Block explorer**: [Seiscan Testnet](https://testnet.seiscan.io)

**Sei Mainnet:**

* **RPC URL**: `https://evm-rpc.sei-apis.com`
* **Chain ID**: 1329
* **Block explorer**: [Seiscan](https://seiscan.io)

## Step 1: Deploy a Storage contract

For this example, deploy a simple Storage contract that stores and retrieves numbers. The contract demonstrates gasless transactions and smart account features with EIP-7702.

### Storage contract (Solidity)

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Storage {
    uint256 private value;

    function store(uint256 num) public {
        value = num;
    }

    function retrieve() public view returns (uint256) {
        return value;
    }
}
```

Deploy this contract with [Remix](https://remix.ethereum.org/) or your preferred deployment tool. Save the contract address, because you need it later.

## Step 2: Project setup

### Create a new project

```bash theme={null}
npm create vite@latest eip7702-demo -- --template react-ts
cd eip7702-demo
npm install
```

### Install dependencies

```bash theme={null}
npm install thirdweb@^5
```

### Install and configure Tailwind CSS

Install Tailwind CSS and its dependencies:

```bash theme={null}
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

Update `tailwind.config.js`:

```javascript theme={null}
/** @type {import('tailwindcss').Config} */
export default {
  content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {}
  },
  plugins: []
};
```

Replace the contents of `src/index.css` with this code:

```css theme={null}
@tailwind base;
@tailwind components;
@tailwind utilities;
```

### Configure environment variables

Create a `.env` file in your project root:

```env theme={null}
VITE_TEMPLATE_CLIENT_ID=your_thirdweb_client_id_here
VITE_STORAGE_CONTRACT_ADDRESS=your_deployed_contract_address_here
```

Get your Client ID from the [thirdweb dashboard](https://thirdweb.com/dashboard) under **Project** → **Overview**.

### Enable gas sponsorship (production)

To sponsor gas on Sei Mainnet:

1. Go to the [billing settings](https://thirdweb.com/dashboard/settings/billing) in the thirdweb dashboard.
2. Subscribe to the **Pay As You Go** plan (\$5/month minimum).
3. Enable gas sponsorship in your project settings.

## Step 3: Configure Vite

Create or update `vite.config.ts`:

```typescript theme={null}
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()]
});
```

## Step 4: Configure thirdweb client

Create `src/client.ts`:

```typescript theme={null}
import { createThirdwebClient } from 'thirdweb';

export const client = createThirdwebClient({
  clientId: import.meta.env.VITE_TEMPLATE_CLIENT_ID
});
```

## Step 5: Setup ThirdwebProvider

First, update `src/main.tsx` to include `ThirdwebProvider`:

```typescript theme={null}
import React from 'react'
import ReactDOM from 'react-dom/client'
import { ThirdwebProvider } from "thirdweb/react"
import App from './App.tsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ThirdwebProvider>
      <App />
    </ThirdwebProvider>
  </React.StrictMode>,
)
```

## Step 6: EIP-7702 smart account implementation

Replace `src/App.tsx` with the complete EIP-7702 implementation.

**Key configuration:**
The `executionMode` configuration enables EIP-7702 features:

* `mode: "EIP7702"`: Enables EIP-7702 account abstraction. The EOA temporarily acts as a smart contract.
* `sponsorGas: true`: Enables gasless transactions. thirdweb pays the gas for users.

```typescript theme={null}
import React, { useState } from "react";
import {
  ConnectButton,
  TransactionButton,
  useActiveAccount,
  useWalletBalance,
  useReadContract,
} from "thirdweb/react";
import { inAppWallet } from "thirdweb/wallets";
import { client } from "./client";
import {
  getContract,
  prepareContractCall,
  sendAndConfirmTransaction,
} from "thirdweb";
import { defineChain } from "thirdweb/chains";

const { VITE_TEMPLATE_CLIENT_ID: THIRDWEB_API_KEY } = import.meta.env;
// Configure Sei network
const rpc = `https://1329.rpc.thirdweb.com/${THIRDWEB_API_KEY}`;
const seiChain = defineChain({
  id: 1329,
  rpc,
});

// Choose your target chain - EIP-7702 enabled chains
const targetChain = seiChain;

// Get contract address from environment
const CONTRACT_ADDRESS = import.meta.env.VITE_STORAGE_CONTRACT_ADDRESS;

// Configure the Storage contract
const storageContract = getContract({
  client,
  chain: targetChain,
  address: CONTRACT_ADDRESS,
});

// Configure EIP-7702 enabled wallet
const wallets = [
  inAppWallet({
    auth: {
      options: [
        "google",
        "email",
        "passkey",
        "apple",
        "facebook",
        "discord",
        "x",
        "telegram",
        "phone",
        "guest",
      ],
    },
    // Enable EIP-7702 smart account features
    executionMode: {
      mode: "EIP7702",
      sponsorGas: true, // Enable gasless transactions
    },
  }),
];

function App() {
  const account = useActiveAccount();
  const [transactionStatus, setTransactionStatus] = useState<string>("");

  // Get wallet balance
  const { data: balance } = useWalletBalance({
    client,
    chain: targetChain,
    address: account?.address,
  });

  const { data: storeValue } = useReadContract({
    contract: storageContract,
    method: "function retrieve() view returns (uint256)",
  });

  // Custom store function with status updates
  const handleCustomStore = async (storeNumber: number) => {
    if (!account) return;

    setTransactionStatus("Preparing transaction...");

    try {
      const transaction = prepareContractCall({
        contract: storageContract,
        method: "function store(uint256 num)",
        params: [BigInt(storeNumber)],
      });

      setTransactionStatus("Sending transaction...");

      const result = await sendAndConfirmTransaction({
        transaction,
        account,
      });

      setTransactionStatus(`Success! Transaction: ${result.transactionHash}`);

      // Reset status after 5 seconds
      setTimeout(() => setTransactionStatus(""), 5000);
    } catch (error) {
      console.error("Store failed:", error);
      setTransactionStatus(
        `Error: ${
          error instanceof Error ? error.message : "Transaction failed"
        }`
      );

      // Reset status after 5 seconds
      setTimeout(() => setTransactionStatus(""), 5000);
    }
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 py-8">
      <div className="max-w-4xl mx-auto px-4">
        <div className="text-center mb-8">
          <h1 className="text-4xl font-bold text-gray-900 mb-2">
            EIP-7702 Account Abstraction Demo
          </h1>
        </div>

        {/* Connection Section */}
        <div className="bg-white  shadow-lg p-6 mb-6">
          <h2 className="text-2xl font-semibold mb-4 text-gray-800">
            Connect Your Smart Account
          </h2>
          <p className="text-gray-600 mb-4">
            Connect with social login and get instant smart account features -
            no wallet setup required!
          </p>
          <ConnectButton
            client={client}
            wallets={wallets}
            chain={targetChain}
            connectButton={{
              label: "Connect with EIP-7702 Smart Account",
              className:
                "!bg-indigo-600 !hover:bg-indigo-700 !text-white !py-3 !px-6 ! !font-medium",
            }}
          />

          {/* Display account info */}
          {account && (
            <div className="mt-4 p-4 bg-green-50 ">
              <h3 className="font-semibold text-green-800 mb-2">
                ✅ Smart Account Connected
              </h3>
              <p className="text-sm text-gray-700">
                <strong>Address:</strong> {account.address}
              </p>
              <p className="text-sm text-gray-700">
                <strong>Balance:</strong> {balance?.displayValue}{" "}
                {balance?.symbol}
              </p>
            </div>
          )}
        </div>

        {account && (
          <>
            {/* Contract Information */}
            <div className="bg-white  shadow-lg p-6 mb-6">
              <div className="flex items-center justify-center gap-4">
                <div className="text-center p-4 bg-blue-50 ">
                  <p className="text-sm text-gray-600 mb-1">Current Stored Value</p>
                  <p className="text-2xl font-bold text-purple-600">
                    {storeValue?.toString() || "0"}
                  </p>
                </div>
              </div>
            </div>

            {/* Transaction Section */}
            <div className="bg-white  shadow-lg p-6 mb-6">
              <div className="space-y-6">
                <div className="border-l-4 border-blue-500 pl-4">
                  <h4 className="font-semibold text-gray-800 mb-2">Store</h4>
                  <TransactionButton
                    transaction={() =>
                      prepareContractCall({
                        contract: storageContract,
                        method: "function store(uint256 num)",
                        params: [BigInt(37)],
                      })
                    }
                    onTransactionSent={(result) => {
                      console.log("Transaction sent:", result.transactionHash);
                      setTransactionStatus(
                        "Transaction sent, waiting for confirmation..."
                      );
                    }}
                    onTransactionConfirmed={(result) => {
                      console.log(
                        "Transaction confirmed:",
                        result.transactionHash
                      );
                      setTransactionStatus(
                        `Stored successfully! TX: ${result.transactionHash}`
                      );
                      setTimeout(() => setTransactionStatus(""), 5000);
                    }}
                    onError={(error) => {
                      console.error("Transaction error:", error);
                      setTransactionStatus(`❌ Error: ${error.message}`);
                      setTimeout(() => setTransactionStatus(""), 5000);
                    }}
                  >
                    Store 37
                  </TransactionButton>
                </div>
              </div>
            </div>

            {/* Custom Store Button */}
            <div className="bg-white  shadow-lg p-6 mb-6">
              <div className="border-l-4 border-green-500 pl-4">
                <h4 className="font-semibold text-gray-800 mb-2">
                  Custom Implementation
                </h4>
                <button
                  onClick={() => {
                    const amount = prompt("Enter number to store");
                    const num = Number(amount);
                    if (!isNaN(num)) {
                      handleCustomStore(num);
                    }
                  }}
                  className="bg-green-600 hover:bg-green-700 text-white px-4 py-2  font-medium transition-colors"
                >
                  Store Custom Number
                </button>
              </div>
            </div>

            {/* Status Display */}
            {transactionStatus && (
              <div className="bg-white  shadow-lg p-6 mb-6">
                <h4 className="font-semibold mb-2">Transaction Status</h4>
                <p className="text-sm text-gray-700 font-mono bg-gray-100 p-3 rounded">
                  {transactionStatus}
                </p>
              </div>
            )}
          </>
        )}
      </div>
    </div>
  );
}

export default App;

```

## Step 7: Package configuration

Update your `package.json`:

```json theme={null}
{
  "name": "eip7702-storage-abstraction-demo",
  "private": true,
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "thirdweb": "^5"
  },
  "devDependencies": {
    "@types/react": "^18.2.56",
    "@types/react-dom": "^18.2.19",
    "@vitejs/plugin-react": "^4.2.1",
    "autoprefixer": "^10.4.18",
    "postcss": "^8.4.35",
    "tailwindcss": "^3.4.1",
    "typescript": "^5.2.2",
    "vite": "^5.0.8"
  }
}
```

## Step 8: Run the application

### Start development server

```bash theme={null}
npm run dev
```

### Test EIP-7702 features

1. Open `http://localhost:5173` in your browser.
2. Connect with any social login, such as Google or email.
3. Observe that the smart account is created automatically, without gas.
4. Test the gasless storage operations:
   * To store the predefined value (37), click **Store 37**.
   * To store a custom number, click **Store Custom Number**.
   * Read the stored value that the interface displays.
5. Monitor the console for transaction hashes and status updates.
6. View more details in your thirdweb dashboard.

## Troubleshooting

### Network issues

If you have connectivity problems:

1. Check the [thirdweb status page](https://status.thirdweb.com).
2. Make sure that your API key is active and has sufficient credits.
3. Make sure that you are connected to the correct network: EVM chain ID 1329 for Sei Mainnet, or 1328 for Sei Testnet.

### Transaction verification

After a successful transaction, you can verify it on the block explorer:

* **Sei Mainnet**: [Seiscan](https://seiscan.io)
* **Sei Testnet**: [Seiscan Testnet](https://testnet.seiscan.io)

Search for your transaction hash to see the full details, including gas used, status, and event logs.

## Resources

### thirdweb documentation & tools

* **[thirdweb Portal](https://portal.thirdweb.com/)**: SDK documentation
* **[EIP-7702 documentation](https://portal.thirdweb.com/connect/account-abstraction/eip-7702)**: Official thirdweb EIP-7702 guide
* **[thirdweb dashboard](https://thirdweb.com/dashboard)**: Manage projects and API keys
* **[GitHub repository](https://github.com/thirdweb-dev)**: Source code and examples
* **[Developer blog](https://blog.thirdweb.com/)**: Latest updates and tutorials
* **[EIP-7702 specification](https://eips.ethereum.org/EIPS/eip-7702)**: Official Ethereum Improvement Proposal


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.