EIP-7702 enables Externally Owned Accounts (EOAs) to temporarily gain smart contract wallet functionality. This guide shows how to integrate ZeroDev’s EIP-7702 implementation with Para’s secure wallet signing.

Prerequisites

You’ll need the following configuration variables:

  • RPC URL: Ethereum network endpoint supporting EIP-7702
  • Bundler RPC: ZeroDev bundler endpoint
  • Paymaster RPC: ZeroDev paymaster endpoint (optional for gas sponsorship)
  • Para API Key: From your developer portal

Installation

Install the required packages:

npm install @zerodev/sdk @zerodev/ecdsa-validator @getpara/viem-v2-integration@alpha viem @getpara/web-sdk@alpha

Signature Utilities

Create signature utilities to handle EIP-7702 compatibility:

utils/signature-utils.ts
import Para from '@getpara/web-sdk';

const SIGNATURE_LENGTH = 130;
const V_OFFSET_FOR_ETHEREUM = 27;

function parseSignature(signature: string): { r: string; s: string; v: number } {
  const cleanSig = signature.startsWith("0x") ? signature.slice(2) : signature;
  const r = cleanSig.slice(0, 64);
  const s = cleanSig.slice(64, 128);
  const vHex = cleanSig.slice(128, 130);
  const v = parseInt(vHex, 16);
  
  return { r, s, v };
}

async function signWithPara(para: Para, data: any, adjustV: boolean = true): Promise<string> {
  const signature = await para.signMessage(data);
  
  if (adjustV && signature.length === SIGNATURE_LENGTH) {
    const { r, s, v } = parseSignature(signature);
    
    if (v < 27) {
      const adjustedV = (v + V_OFFSET_FOR_ETHEREUM).toString(16).padStart(2, "0");
      return signature.slice(0, -2) + adjustedV;
    }
  }
  
  return signature;
}

export async function customSignMessage(para: Para, message: any): Promise<string> {
  return signWithPara(para, message, true);
}

export async function customSignAuthorization(para: Para, authorization: any): Promise<string> {
  const signature = await signWithPara(para, authorization, false);
  const { v } = parseSignature(signature);
  
  if (v !== 0 && v !== 1) {
    throw new Error(`Invalid v value for EIP-7702: ${v}. Expected 0 or 1`);
  }
  
  return signature;
}

Imports

import { createParaAccount } from "@getpara/viem-v2-integration";
import { customSignAuthorization, customSignMessage } from "./utils/signature-utils.js";
import { createPublicClient, http, parseGwei, type LocalAccount } from "viem";
import { arbitrumSepolia } from "viem/chains";
import { 
  create7702KernelAccount, 
  create7702KernelAccountClient,
  createZeroDevPaymasterClient,
  KERNEL_V3_3,
  getEntryPoint
} from "@zerodev/sdk";
import Para, { Environment } from "@getpara/web-sdk";

Client Setup

Initialize Para

const para = new Para(Environment.BETA, YOUR_API_KEY);

Create Para Account with Custom Signing

const viemParaAccount: LocalAccount = createParaAccount(para);
viemParaAccount.signMessage = async ({ message }) => customSignMessage(para, message);
viemParaAccount.signAuthorization = async (authorization) => customSignAuthorization(para, authorization);

Setup ZeroDev Clients

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

const kernelVersion = KERNEL_V3_3;
const entryPoint = getEntryPoint("0.7");

const kernelAccount = await create7702KernelAccount(publicClient, {
  signer: viemParaAccount,
  entryPoint,
  kernelVersion,
});

const paymasterClient = createZeroDevPaymasterClient({
  chain: arbitrumSepolia,
  transport: http(paymasterRpc),
});

const kernelAccountClient = create7702KernelAccountClient({
  account: kernelAccount,
  chain: arbitrumSepolia,
  bundlerTransport: http(bundlerRpc),
  paymaster: paymasterClient,
  client: publicClient,
  userOperation: {
    estimateFeesPerGas: async () => ({
      maxFeePerGas: parseGwei("0.24"),
      maxPriorityFeePerGas: parseGwei("0.001"),
    }),
  },
});

Usage Example

Send a transaction using the EIP-7702 enabled account:

try {
  const userOpHash = await kernelAccountClient.sendUserOperation({
    userOperation: {
      callData: await kernelAccount.encodeCallData({
        to: "0x1234567890123456789012345678901234567890",
        value: parseEther("0.01"),
        data: "0x",
      }),
    },
  });
  
  console.log("UserOp hash:", userOpHash);
  
  const receipt = await kernelAccountClient.waitForUserOperationReceipt({
    hash: userOpHash,
  });
  
  console.log("Transaction confirmed:", receipt.receipt.transactionHash);
} catch (error) {
  console.error("Transaction failed:", error);
}

Key Features

EIP-7702 Benefits:

  • Temporary smart contract functionality for EOAs
  • Gas sponsorship through paymasters
  • Batch transactions
  • Enhanced security features

Para Integration:

  • Secure MPC signing compatible with EIP-7702
  • Support for both session-based and pregen wallets
  • Automatic signature format handling (0/1 vs 27/28 recovery)

ZeroDev Features:

  • Account abstraction infrastructure
  • Gas policy management
  • Bundler and paymaster services

The custom signature utilities ensure Para’s MPC signatures work correctly with EIP-7702’s specific requirements for authorization signatures.

Next Steps