EIP-7702 enables Externally Owned Accounts (EOAs) to temporarily gain smart contract wallet functionality. This guide shows how to integrate Alchemy’s Account Kit 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
  • Alchemy Gas Policy ID: For sponsored transactions (optional)
  • Para API Key: From your developer portal

Installation

Install the required packages:
npm install @account-kit/infra @account-kit/smart-contracts @aa-sdk/core @getpara/viem-v2-integration@alpha viem @getpara/web-sdk@alpha --save-exact

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 { alchemy } from "@account-kit/infra";
import { createModularAccountV2Client } from "@account-kit/smart-contracts";
import { WalletClientSigner } from "@aa-sdk/core";
import { createParaAccount, createParaViemClient } from "@getpara/viem-v2-integration";
import { arbitrumSepolia } from "@account-kit/infra";
import { customSignMessage, customSignAuthorization } from "./utils/signature-utils.js";
import { http, type LocalAccount, type WalletClient } from "viem";
import Para from "@getpara/web-sdk";

Client Setup

Initialize Para

const para = new Para(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) => {
  console.log("Signing authorization:", authorization);
  return customSignAuthorization(para, authorization);
};

Setup Viem Client

const viemClient: WalletClient = createParaViemClient(para, {
  account: viemParaAccount,
  chain: arbitrumSepolia,
  transport: http(rpcUrl)
});

Create Alchemy Client

const walletClientSigner = new WalletClientSigner(viemClient, "para");

const alchemyClient = await createModularAccountV2Client({
  mode: "7702",
  transport: alchemy({
    rpcUrl: rpcUrl
  }),
  chain: arbitrumSepolia,
  signer: walletClientSigner,
  policyId: alchemyGasPolicyId // Optional for gas sponsorship
});

Usage Example

Send a transaction using the EIP-7702 enabled account:
import { parseEther } from "viem";

try {
  const userOpResult = await alchemyClient.sendUserOperation({
    uo: {
      target: "0x1234567890123456789012345678901234567890",
      data: "0x",
      value: parseEther("0.01"),
    }
  });
  
  console.log("UserOp hash:", userOpResult.hash);
  
  const receipt = await alchemyClient.waitForUserOperationTransaction({
    hash: userOpResult.hash
  });
  
  console.log("Transaction confirmed:", receipt.transactionHash);
} catch (error) {
  console.error("Transaction failed:", error);
}

Batch Transactions

Execute multiple operations in a single transaction:
const batchResult = await alchemyClient.sendUserOperation({
  uo: [
    {
      target: "0x1234567890123456789012345678901234567890",
      data: "0x",
      value: parseEther("0.01"),
    },
    {
      target: "0x0987654321098765432109876543210987654321",
      data: "0x",
      value: parseEther("0.02"),
    }
  ]
});

console.log("Batch UserOp hash:", batchResult.hash);

Key Features

EIP-7702 Benefits:
  • Temporary smart contract functionality for EOAs
  • Gas sponsorship through Alchemy’s policies
  • Batch transactions and complex operations
  • Enhanced security and user experience
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)
Alchemy Account Kit Features:
  • Modular account architecture
  • Built-in gas policies and sponsorship
  • Developer-friendly SDK and tools
  • Production-ready infrastructure
The custom signature utilities ensure Para’s MPC signatures work correctly with EIP-7702’s specific requirements for authorization signatures, including proper v-value formatting.

Advanced Configuration

Custom Gas Policies

const alchemyClient = await createModularAccountV2Client({
  mode: "7702",
  transport: alchemy({
    rpcUrl: rpcUrl
  }),
  chain: arbitrumSepolia,
  signer: walletClientSigner,
  gasManagerConfig: {
    policyId: alchemyGasPolicyId,
    entryPoint: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
  }
});

Session Management

const sessionKey = await alchemyClient.getAddress();
console.log("EIP-7702 Account Address:", sessionKey);

const isDeployed = await alchemyClient.getAddress();
console.log("Account deployment status:", isDeployed);

Next Steps