> ## Documentation Index
> Fetch the complete documentation index at: https://docs.privy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrating with EIP-7702

[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) is an upgrade to EVM blockchains that enables externally owned accounts (EOAs) to set their code to that of a smart contract. In practical terms, this means that EOA wallets will gain AA (account abstraction) capabilities such as transaction bundling, gas sponsorship, and custom permissions.

Privy supports all low level interfaces required by 7702 - signing authorizations and sending type 4 transactions, allowing you to use any implementation of EIP-7702. Use the following guides to get started with EIP-7702 in your application:

### Signing EIP-7702 authorizations

Privy provides methods to sign EIP-7702 authorizations using the user's embedded wallet. This authorization is a cryptographic signature that allows an EOA to set its code to that of a smart contract, enabling the EOA to behave like a smart account.

Learn more about signing EIP-7702 authorizations in our [dedicated guide](/wallets/using-wallets/ethereum/sign-7702-authorization).

Learn more about using the signed authorization in the integration guides below!

### Detect current 7702 authorization state and implementation address

You can determine whether an EOA is currently delegated via EIP-7702 and read the authorized implementation address with a single `eth_getCode` call on the EOA address.

Under EIP-7702, an authorized EOA temporarily exposes a small bytecode stub that begins with the magic prefix `0xef0100`, followed immediately by the 20-byte implementation address. If `eth_getCode` returns empty code (`0x` or `0x0`), the EOA is not currently delegated on that chain. The snippets below return the current implementation address or `null`.

<Tabs>
  <Tab title="Viem">
    ```ts theme={"system"}
    import {createPublicClient, http} from 'viem';
    import {mainnet} from 'viem/chains'; // replace with your chain

    const publicClient = createPublicClient({
      chain: mainnet,
      transport: http('your RPC URL here')
    });
    const address = '0x...'; // the EOA address here

    const code = (await publicClient.getCode({address}))?.toLowerCase() ?? '0x';
    const prefixIndex = code.indexOf('0xef0100');
    const authorizedImplementationAddress =
      prefixIndex === -1
        ? null
        : (`0x${code.slice(prefixIndex + 8, prefixIndex + 48)}` as `0x${string}`);
    ```

    <Expandable title="Full helper function (robust & typed)">
      ```ts theme={"system"}
      export function parseEip7702AuthorizedAddress(
        code: string | null | undefined
      ): `0x${string}` | null {
        if (!code || code === '0x' || code === '0x0') return null;
        const normalized = code.toLowerCase();
        const MAGIC = '0xef0100';
        const idx = normalized.indexOf(MAGIC);
        if (idx === -1) return null;
        return ('0x' + normalized.slice(idx + MAGIC.length, idx + MAGIC.length + 40)) as `0x${string}`;
      }
      ```
    </Expandable>
  </Tab>

  <Tab title="Ethers">
    ```ts theme={"system"}
    import {ethers} from 'ethers';

    const provider = new ethers.JsonRpcProvider('your RPC URL here');
    const address = 'the EOA address here';

    const code = (await provider.getCode(address))?.toLowerCase() ?? '0x';
    const prefixIndex = code.indexOf('0xef0100');
    const authorizedImplementationAddress =
      prefixIndex === -1
        ? null
        : (`0x${code.slice(prefixIndex + 8, prefixIndex + 48)}` as `0x${string}`);
    ```

    <Expandable title="Full helper function (robust)">
      ```ts theme={"system"}
      function parseEip7702AuthorizedAddress(code?: string | null) {
        if (!code || code === '0x' || code === '0x0') return null;
        const MAGIC = '0xef0100';
        const idx = code.toLowerCase().indexOf(MAGIC);
        if (idx === -1) return null;
        return ('0x' + code.slice(idx + MAGIC.length, idx + MAGIC.length + 40)) as `0x${string}`;
      }
      ```
    </Expandable>
  </Tab>
</Tabs>

<Info>
  Authorization state is per-chain. Under 7702, an authorized EOA will return non-empty code with
  the `0xef0100` prefix; other non-empty code indicates a deployed contract account.
</Info>

### Using EIP-7702 capabilities

<Tabs>
  <Tab title="Alchemy">
    In this guide, we will transform your Privy embedded wallet into a smart wallet with features like gas sponsorship, batch transactions, granular permissions, and more [using EIP-7702](https://www.alchemy.com/docs/wallets/react/using-7702) support from Alchemy.

    ### 0. Install dependencies

    In your app's repository, install the required dependencies from Privy, Alchemy Account Kit, and [`viem`](https://www.npmjs.com/package/viem):

    ```sh theme={"system"}
    npm i @privy-io/react-auth @account-kit/infra @account-kit/wallet-client @account-kit/smart-contracts @aa-sdk/core viem@2.29.3
    ```

    ### 1. Create an Alchemy account and get your API key

    * **Create an app:** visit the Alchemy [dashboard](https://dashboard.alchemy.com/apps) to create a new app, if you don't already have one.
      * Make sure to enable networks that support EIP-7702 such as Ethereum Mainnet or Sepolia.
      * Save the app's **API Key** that will be used later.

    * **Enable gas sponsorship:** visit the [Gas Manager](https://dashboard.alchemy.com/gas-manager) dashboard and create a new sponsorship policy for the app you created in step 1. This policy will be used to set rules on how much of user's gas you want to sponsor.
      * Make sure to enable gas sponsorship on a chain that support EIP-7702 such as Ethereum Mainnet or Sepolia.
      * Save the **Policy ID** that will be used later.

    Now that you have your API key and Policy ID, you can set up your smart wallets.

    ### 2. Configure Privy settings

    If you're already using a Privy embedded wallet, update your configuration to support EIP-7702 with embedded wallets. If you don't yet have authentication configured, you can follow [this](https://www.alchemy.com/docs/wallets/react/using-7702) guide to get set up.

    Make sure your `PrivyProvider` has the following `embeddedWallets` settings and ensure you set the `defaultChain` and `supportedChains` to the 7702 supported chain you chose in step 1.

    ```tsx theme={"system"}
    import { sepolia } from "@account-kit/infra";
    <PrivyProvider
    	appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID || ""}
    	config={{
    	  embeddedWallets: {
    	    showWalletUIs: false,
    	    createOnLogin: "all-users",
    	  },
    	  defaultChain: sepolia,
    	  supportedChains: [sepolia],
    	}}
    >
    ```

    ### 3. Adapt Privy signer to a smart account signer

    Now that you have authentication working, adapt the Privy signer to be able to sign 7702 authorizations to upgrade to smart accounts.

    **1. Get the Privy embedded wallet**

    ```tsx theme={"system"}
    import {useWallets} from '@privy-io/react-auth';

    const {wallets} = useWallets();
    const embeddedWallet = wallets.find((x) => x.walletClientType === 'privy');
    ```

    **2. Create a `SmartAccountSigner` instance**

    ```tsx theme={"system"}
    import {sepolia, alchemy} from '@account-kit/infra'; // make sure to import your chain from account-kit, not viem
    import {useSign7702Authorization} from '@privy-io/react-auth';
    import {SmartAccountSigner, WalletClientSigner} from '@aa-sdk/core';
    import {createWalletClient, custom, Hex} from 'viem';
    import {Authorization} from 'viem/experimental';

    const {signAuthorization} = useSign7702Authorization();

    async function create7702signer() {
      const baseSigner = new WalletClientSigner(
        createWalletClient({
          account: embeddedWallet!.address as Hex,
          chain: sepolia,
          transport: custom(await embeddedWallet!.getEthereumProvider())
        }),
        'privy'
      );

      const signer: SmartAccountSigner = {
        getAddress: baseSigner.getAddress,
        signMessage: baseSigner.signMessage,
        signTypedData: baseSigner.signTypedData,
        signerType: baseSigner.signerType,
        inner: baseSigner.inner,
        signAuthorization: async (
          unsignedAuth: Authorization<number, false>
        ): Promise<Authorization<number, true>> => {
          const signature = await signAuthorization(unsignedAuth);

          return {
            ...unsignedAuth,
            ...{
              r: signature.r!,
              s: signature.s!,
              v: signature.v!
            }
          };
        }
      };

      return signer;
    }
    ```

    ### 4. Upgrade to smart accounts and send sponsored transactions

    Now that you have a `SmartAccountSigner` instance, follow [this guide](https://www.alchemy.com/docs/wallets/transactions/using-eip-7702#third-party-signers) to create a smart account client (`createModularAccountV2Client` ) and start sending sponsored transactions. You'll need:

    * the `SmartAccountSigner` instance defined in step 3
    * the API key and the policy ID from step 1

    Once you define the client, you can send sponsored transactions with your embedded EOA and access other advanced smart account features! This client will handle all of the logic of delegating to a new smart account, if not already, and signing transactions. If you don't yet have a signer, follow [this guide](https://www.alchemy.com/docs/wallets/react/using-7702) to get set up.

    Looking for a complete working example? See this [working example integrating Privy embedded EOAs with EIP-7702 and Alchemy Smart Wallets](https://github.com/alchemyplatform/alchemy-wallets-7702-thirdparty-example).

    ### Next steps

    You just upgraded your EOA and sent your first sponsored transaction using EIP-7702!

    If you want to leverage other smart account capabilities such as batching and permissions, check out the [Alchemy docs](https://www.alchemy.com/docs/wallets).
  </Tab>

  <Tab title="Biconomy">
    In this guide we'll see a quick example of using the [Biconomy's](https://biconomy.io/) Modular Execution Environment (MEE) stack with Privy!

    <Info>
      To keep things short, this guide will show you a simple example of *single-chain orchestration*
      with cross-chain gas. However, the Biconomy MEE stack supports multi-chain orchestration cases. If
      you're looking to build a multi-chain DeFi strategy - read the [Biconomy
      Docs](https://docs.biconomy.io)
    </Info>

    ## Project Setup

    Create your project using Vite:

    ```bash theme={"system"}
    bun create vite biconomy-mee-embedded-example --template react-ts
    cd biconomy-mee-embedded-example
    ```

    Add the following to your `package.json`:

    ```json theme={"system"}
    "dependencies": {
      "@biconomy/abstractjs": "^1.0.17",
      "@privy-io/react-auth": "^2.14.2",
      "@privy-io/wagmi": "^1.0.4",
      "@tanstack/react-query": "^5.80.7",
      "react": "^19.1.0",
      "react-dom": "^19.1.0",
      "viem": "^2.31.3",
      "wagmi": "^2.15.6"
    }
    ```

    Install dependencies:

    ```bash theme={"system"}
    bun install
    ```

    Set up your `main.tsx`:

    ```tsx theme={"system"}
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from './App.tsx';
    import './index.css';

    import {PrivyProvider} from '@privy-io/react-auth';
    import {WagmiProvider} from 'wagmi';
    import {wagmiConfig} from './wagmi.ts';
    import {QueryClient, QueryClientProvider} from '@tanstack/react-query';

    const appId = 'your-privy-app-id';
    const queryClient = new QueryClient();

    ReactDOM.createRoot(document.getElementById('root')!).render(
      <React.StrictMode>
        <PrivyProvider
          appId={appId}
          config={{
            embeddedWallets: {
              ethereum: {
                createOnLogin: 'all-users'
              }
            }
          }}
        >
          <QueryClientProvider client={queryClient}>
            <WagmiProvider config={wagmiConfig}>
              <App />
            </WagmiProvider>
          </QueryClientProvider>
        </PrivyProvider>
      </React.StrictMode>
    );
    ```

    In `wagmi.ts`:

    ```ts theme={"system"}
    import {createConfig} from '@privy-io/wagmi';
    import {http} from 'wagmi';
    import {baseSepolia, optimismSepolia} from 'viem/chains';

    export const wagmiConfig = createConfig({
      chains: [optimismSepolia, baseSepolia],
      transports: {
        [optimismSepolia.id]: http(),
        [baseSepolia.id]: http()
      }
    });
    ```

    ## ⬇Get the Embedded Wallet Instance

    After logging in the user with Privy, you can find the embedded wallet as follows:

    ```ts theme={"system"}
    import {useWallets} from '@privy-io/react-auth';

    const {wallets} = useWallets();
    const wallet = wallets.find((wallet) => wallet.walletClientType === 'privy');
    ```

    ## Authorizing with EIP-7702

    To install the Biconomy Nexus 1.2.0 smart account on the address of your Privy embedded
    wallet EOA, you need to sign the following authorization. Note: This is using the
    `signAuthorization` method exposed by the `useSignAuthorization` Privy hook.

    ```ts theme={"system"}
    import {useSign7702Authorization} from '@privy-io/react-auth';
    import {baseSepolia} from '@privy-io/chains';

    const {signAuthorization} = useSign7702Authorization();
    const NEXUS_V120 = '0x000000004F43C49e93C970E84001853a70923B03';

    const authorization = await signAuthorization({
      contractAddress: NEXUS_V120,
      chainId: baseSepolia.id, // or 0 for universal
      nonce: 0
    });
    ```

    ## Execute a Cross-Chain Gas Abstracted Transaction

    After signing, you can submit a transaction through Biconomy MEE Relayers. Notice
    few things for this transaction:

    * Gas is paid with USDC
    * Gas is paid on a different chain than the instruction being executed
    * The `amount` arg in the ERC-20 `transfer` call is not fixed to a value, but uses
      `runtimeERC20BalanceOf` which will inject the full amount of USDC available.

    This demonstrates few key points of MEE:

    * Gas abstraction / gas sponsorship
    * Multi-chain execution/orchestration
    * Runtime parameter injection enabling multi-transaction composability

    ```ts {skip-check} theme={"system"}
    const orchestrator = await toMultichainNexusAccount({
      chains: [optimismSepolia, baseSepolia],
      transports: [http(), http()],
      signer: await wallet.getEthereumProvider(),
      accountAddress: wallet.address as Address
    });

    const meeClient = await createMeeClient({account: orchestrator});

    const sendUSDCBase = await orchestrator.buildComposable({
      type: 'default',
      data: {
        abi: erc20Abi,
        chainId: baseSepolia.id,
        to: usdcAddresses[baseSepolia.id],
        functionName: 'transfer',
        args: [
          wallet.address,
          runtimeERC20BalanceOf({
            tokenAddress: usdcAddresses[baseSepolia.id],
            targetAddress: orchestrator.addressOn(baseSepolia.id, true),
            constraints: [greaterThanOrEqualTo(1n)]
          })
        ]
      }
    });

    const quote = await meeClient.getQuote({
      instructions: [sendUSDCBase],
      authorization,
      delegate: true,

      // Paying for gas with USDC on Optimism, while
      // executing a transaction on Base!
      feeToken: {
        address: usdcAddresses[optimismSepolia.id],
        chainId: optimismSepolia.id
      }
    });

    const {hash} = await meeClient.executeQuote({quote});
    ```

    You can then link the user to MEE Scan to track:

    ```ts {skip-check} theme={"system"}
    const link = getMeeScanLink(hash);
    ```

    ## Storing the **Authorization**

    If you've used the `chainId === 0` for your authorization you can store it (e.g. in localStorage or DB) and
    replay it for other chains in the future. This gives your users an even more seamless UX.
  </Tab>

  <Tab title="Pimlico">
    In this guide, we'll demonstrate how to use Pimlico, a bundler and paymaster service for ERC-4337 accounts, to enable your users to send gasless transactions using EIP-7702 authorization.

    <Info>
      Want to see a full end to end example? Check out our starter repo
      [here](https://github.com/pimlicolabs/permissionless-privy-7702)
    </Info>

    ## 0. Install dependencies

    In your app's repository, install the required dependencies from Privy, Permissionless, and Viem:

    ```bash theme={"system"}
    npm i @privy-io/react-auth @privy-io/wagmi permissionless viem wagmi
    ```

    ## 1. Sign up for a Pimlico account and get your API key

    Head to the Pimlico dashboard [here](https://dashboard.pimlico.io/) and create an account. Generate an API key and create a sponsorship policy for the network you plan to use (optional). Make note of your API key and sponsorship policy ID.

    ## 2. Configure Privy settings

    Configure your app to create embedded wallets for all users.

    ```jsx theme={"system"}
    <PrivyProvider
      config={{
        embeddedWallets: {
          createOnLogin: 'all-users'
          showWalletUIs: false
        }
      }}
    >
      ...
    </PrivyProvider>
    ```

    ## 3. Create a simple smart account with Permissionless SDK

    Permissionless provides a simple way to create a smart account client that can send user operations with EIP-7702 authorization. All you need is the user's embedded wallet and the Pimlico API key.

    ```jsx theme={"system"}
    import {useEffect} from 'react';
    import {usePrivy, useSign7702Authorization, useWallets} from '@privy-io/react-auth';
    import {useSetActiveWallet} from '@privy-io/wagmi';
    import {useWalletClient} from 'wagmi';
    import {createPublicClient, http, zeroAddress, Hex} from 'viem';
    import {sepolia} from 'viem/chains';
    import {createSmartAccountClient} from 'permissionless';
    import {createPimlicoClient} from 'permissionless/clients/pimlico';
    import {to7702SimpleSmartAccount} from 'permissionless/accounts';

    // Get the Privy embedded wallet
    const {wallets} = useWallets();
    const {data: walletClient} = useWalletClient();
    const embeddedWallet = wallets.find((wallet) => wallet.walletClientType === 'privy');

    // Set the embedded wallet as active
    const {setActiveWallet} = useSetActiveWallet();
    useEffect(() => {
      if (embeddedWallet) {
        setActiveWallet(embeddedWallet);
      }
    }, [embeddedWallet, setActiveWallet]);

    // Create a public client for the chain
    const publicClient = createPublicClient({
      chain: sepolia,
      transport: http(process.env.NEXT_PUBLIC_SEPOLIA_RPC_URL)
    });

    // Create a Pimlico client
    const pimlicoApiKey = process.env.NEXT_PUBLIC_PIMLICO_API_KEY;
    const pimlicoUrl = `https://api.pimlico.io/v2/${sepolia.id}/rpc?apikey=${pimlicoApiKey}`;
    const pimlicoClient = createPimlicoClient({
      chain: sepolia,
      transport: http(pimlicoUrl)
    });

    // Create a 7702 simple smart account
    const simple7702Account = await to7702SimpleSmartAccount({
      client: publicClient,
      owner: walletClient
    });

    // Create the smart account client
    const smartAccountClient = createSmartAccountClient({
      client: publicClient,
      chain: sepolia,
      account: simple7702Account,
      paymaster: pimlicoClient,
      bundlerTransport: http(pimlicoUrl)
    });
    ```

    ## 4. Sign the EIP-7702 authorization

    Privy provides methods to sign EIP-7702 authorizations using the user's embedded wallet. This authorization is a cryptographic signature that allows an EOA to set its code to that of a smart contract, enabling the EOA to behave like a smart account.

    ```jsx theme={"system"}
    const {signAuthorization} = useSign7702Authorization();

    // Sign the EIP-7702 authorization
    const authorization = await signAuthorization({
      contractAddress: '0xe6Cae83BdE06E4c305530e199D7217f42808555B', // Simple account implementation address
      chainId: sepolia.id,
      nonce: await publicClient.getTransactionCount({
        address: walletClient.account.address
      })
    });
    ```

    ## 5. Send a gas-sponsored transaction

    With the smart account client configured and the authorization signed, you can now send gasless UserOperations:

    ```jsx theme={"system"}
    const transactionHash = await smartAccountClient.sendTransaction({
      to: zeroAddress,
      value: 0n,
      data: '0x',
      authorization,
      paymasterContext: {
        sponsorshipPolicyId: process.env.NEXT_PUBLIC_SPONSORSHIP_POLICY_ID
      }
    });

    console.log(`Transaction hash: ${transactionHash}`);
    console.log(`View on Etherscan: https://sepolia.etherscan.io/tx/${transactionHash}`);
    ```

    ## Conclusion

    That's it! You've just executed a gasless transaction from a normal EOA upgraded with EIP-7702 using Pimlico as the bundler and paymaster service.

    Explore the rest of the [Pimlico docs](https://docs.pimlico.io/) to learn about advanced features like batching transactions, gas estimation, and more.

    <Info>
      Want to see a full end to end example? Check out our starter repo
      [here](https://github.com/pimlicolabs/permissionless-privy-7702)!
    </Info>
  </Tab>

  <Tab title="Porto">
    In this guide, we'll demonstrate how to use [Porto](https://porto.sh/), a universal blockchain account infrastructure with native cross-chain interoperability, together with Privy to upgrade your EOA wallets with EIP-7702.

    ### 0. Install dependencies

    In your app's repository, install the required dependencies from Privy, Porto, and [`viem`](https://www.npmjs.com/package/viem):

    ```sh theme={"system"}
    npm i @privy-io/react-auth porto viem
    ```

    ### 1. Configure Privy settings

    Configure your app to create embedded wallets for all users. Update your `PrivyProvider` configuration:

    ```tsx theme={"system"}
    <PrivyProvider
      config={{
        embeddedWallets: {
          createOnLogin: 'all-users',
          showWalletUIs: false
        }
      }}
    >
      ...
    </PrivyProvider>
    ```

    ### 2. Set up Porto client

    Create a Viem client configured for Porto:

    ```tsx theme={"system"}
    import {createClient, http} from 'viem';
    import {Chains} from 'porto/viem';

    const client = createClient({
      chain: Chains.baseSepolia,
      transport: http('https://rpc.porto.sh')
    });
    ```

    ### 3. Create Porto account with Privy's embedded wallet

    Get the Privy embedded wallet and create a Porto account instance with custom signing:

    ```tsx theme={"system"}
    import {useWallets} from '@privy-io/react-auth';
    import {Account} from 'porto/viem';
    import {Hex} from 'viem';

    // Get the Privy embedded wallet
    const {wallets} = useWallets();
    const embeddedWallet = wallets.find((wallet) => wallet.walletClientType === 'privy');

    // Create a Porto account with secp256k1 signing
    const account = Account.from({
      source: 'privateKey',
      address: embeddedWallet.address as Hex,
      async sign({hash}) {
        const provider = await embeddedWallet.getEthereumProvider();
        const signature = await provider.request({
          method: 'secp256k1_sign',
          params: [hash]
        });
        return signature;
      }
    });
    ```

    ### 4. Upgrade account to Porto

    Use Porto's `RelayActions` to upgrade the account:

    ```tsx theme={"system"}
    import {RelayActions} from 'porto/viem';

    // Upgrade the account to Porto
    const upgradedAccount = await RelayActions.upgradeAccount(client, {
      account
    });
    ```

    ### 5. Send transactions with Porto

    With the account upgraded, you can now send transactions through Porto's relay infrastructure with advanced features like gas sponsorship and cross-chain capabilities:

    ```tsx theme={"system"}
    import {encodeFunctionData} from 'viem';

    // Example: Send a transaction to mint an NFT
    const result = await RelayActions.sendCalls(client, {
      account,
      chain: Chains.baseSepolia,
      calls: [
        {
          to: nftContractAddress,
          data: encodeFunctionData({
            abi: nftAbi,
            functionName: 'mint',
            args: [account.address]
          })
        }
      ]
    });

    console.log('Transaction sent:', result);
    ```

    ### 6. Track transaction status

    Monitor the status of your transactions:

    ```tsx theme={"system"}
    // Get the status of a transaction
    const status = await RelayActions.getCallsStatus(client, {
      account,
      callHash: result.hash
    });

    console.log('Transaction status:', status);
    ```

    ### Next steps

    You've successfully upgraded your EOA with EIP-7702 and Porto! Your users can now:

    * Send transactions with gas sponsorship
    * Execute cross-chain transactions seamlessly
    * Batch multiple operations in a single transaction
    * Benefit from native interoperability across chains

    Explore the [Porto documentation](https://porto.sh/) to learn about additional features.
  </Tab>

  <Tab title="ZeroDev">
    In this guide, we demonstrate using [ZeroDev](https://zerodev.app/), a toolkit for creating smart accounts, together with Privy to enable your users to send gasless (sponsored) transactions.

    <Info>
      Want to see a full end to end example? Check out our starter repo
      [here](https://github.com/privy-io/create-next-app/tree/7702/zerodev)!
    </Info>

    ### 0. Install dependencies

    In your app's repository, install the required dependencies from Privy, ZeroDev and [`viem`](https://www.npmjs.com/package/viem):

    ```sh theme={"system"}
    npm i @privy-io/react-auth @zerodev/sdk viem
    ```

    ### 1. Sign up for a ZeroDev account and create a project

    Head to the [**ZeroDev dashboard**](https://dashboard.zerodev.app/) and create a project on a chain that supports EIP-7702.

    Set up a [gas sponsorship policy](https://dashboard.zerodev.app/paymasters) to enable sending sponsored transactions. Copy the **Bundler RPC** and **Paymaster RPC** for the network you plan to use.

    ### 2. Configure Privy settings

    Configure your app to create embedded wallets for all users. Also configure Privy to not show its default wallet UIs. Instead, we recommend you use your own custom UIs for showing users the user operations they sign.

    Update your `PrivyProvider` configuration to include the following properties:

    ```tsx theme={"system"}
    <PrivyProvider
      config={{
        embeddedWallets: {
          showWalletUIs: false, // [!code ++]
          createOnLogin: 'all-users' // [!code ++]
        }
      }}
    >
      ...
    </PrivyProvider>
    ```

    ### 3. Create a 7702 Kernel account with the ZeroDev SDK

    ZeroDev exposes helper functions that take care of generating the 7702 authorization for you. All you need to provide is the signer for the user's embedded wallet and the Kernel version you want to use.

    ```tsx theme={"system"}
    import {
      createZeroDevPaymasterClient,
      createKernelAccountClient,
      createKernelAccount
    } from '@zerodev/sdk';
    import {KERNEL_V3_3} from '@zerodev/sdk/constants';
    import {getEntryPoint} from '@zerodev/sdk/constants';
    import {createWalletClient, createPublicClient, custom, http, zeroAddress, Hex} from 'viem';
    import {odysseyTestnet} from 'viem/chains';

    // Select the chain and Kernel version you want to use
    const chain = odysseyTestnet;
    const kernelVersion = KERNEL_V3_3;
    const kernelAddresses = KernelVersionToAddressesMap[kernelVersion];

    const entryPoint = getEntryPoint('0.7');

    // Grab the embedded wallet created by Privy
    const {wallets} = useWallets();
    const embeddedWallet = wallets.find((wallet) => wallet.walletClientType === 'privy');

    // Build viem clients for the wallet & public RPC
    const walletClient = createWalletClient({
      account: embeddedWallet.address as Hex,
      chain,
      transport: custom(await embeddedWallet.getEthereumProvider())
    });

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

    // Sign the EIP-7702 authorization
    const authorization = await signAuthorization({
      contractAddress: kernelAddresses.accountImplementationAddress,
      chainId: chain.id
    });

    // Create the 7702 Kernel account (no deployment occurs!)
    const account = await createKernelAccount(publicClient, {
      eip7702Account: walletClient,
      entryPoint,
      kernelVersion,
      eip7702Auth: authorization
    });
    ```

    Behind the scenes ZeroDev generates the EIP-7702 authorization and binds the Kernel implementation code to the EOA, giving it smart-account super-powers while keeping the same address.

    ### 4. Configure the ZeroDev client for sponsored transactions

    ```tsx theme={"system"}
    const paymasterRpc = 'YOUR_PAYMASTER_RPC_URL';
    const bundlerRpc = 'YOUR_BUNDLER_RPC_URL';

    // Create a paymaster client so the user does not need ETH
    const paymasterClient = createZeroDevPaymasterClient({
      chain,
      transport: http(paymasterRpc)
    });

    // Build a Kernel client that will create & submit UserOperations
    const kernelClient = createKernelAccountClient({
      account,
      chain,
      bundlerTransport: http(bundlerRpc),
      paymaster: paymasterClient,
      client: publicClient
    });
    ```

    ### 5. Send a gas-sponsored transaction

    With the client configured, you can now send gasless UserOperations. Below we send an empty call then wait for it to be mined:

    ```tsx theme={"system"}
    // Send a simple UserOperation
    const userOpHash = await kernelClient.sendUserOperation({
      callData: await kernelClient.account.encodeCalls([
        {
          to: zeroAddress,
          value: BigInt(0),
          data: '0x'
        }
      ])
    });

    // Wait for the operation to be included
    const {receipt} = await kernelClient.waitForUserOperationReceipt({
      hash: userOpHash
    });

    console.log(
      'UserOp completed',
      `${chain.blockExplorers.default.url}/tx/${receipt.transactionHash}`
    );
    ```

    ### Conclusion

    That's it! You've just executed a gasless transaction from a normal EOA upgraded with EIP-7702.

    Explore the rest of the [ZeroDev docs](https://docs.zerodev.app/) to learn about batching, session keys, cross-chain actions and more.
  </Tab>
</Tabs>
