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