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:
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