Prerequisites
Para SDK Setup Required
Installation
- Alchemy
- ZeroDev
Copy
Ask AI
npm install @account-kit/infra @account-kit/smart-contracts @aa-sdk/core @getpara/viem-v2-integration viem @getpara/web-sdk --save-exact
Copy
Ask AI
npm install @zerodev/sdk @zerodev/ecdsa-validator @getpara/viem-v2-integration viem @getpara/web-sdk --save-exact
Setup
- Alchemy
- ZeroDev
Copy
Ask AI
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 { http, type LocalAccount, type WalletClient } from "viem";
import Para from "@getpara/web-sdk";
const para = new Para(YOUR_API_KEY);
const viemParaAccount: LocalAccount = createParaAccount(para);
viemParaAccount.signMessage = async ({ message }) => {
const signature = await para.signMessage(message);
const cleanSig = signature.startsWith("0x") ? signature.slice(2) : signature;
const v = parseInt(cleanSig.slice(128, 130), 16);
if (v < 27) {
const adjustedV = (v + 27).toString(16).padStart(2, "0");
return signature.slice(0, -2) + adjustedV;
}
return signature;
};
viemParaAccount.signAuthorization = async (authorization) => {
const signature = await para.signMessage(authorization);
const cleanSig = signature.startsWith("0x") ? signature.slice(2) : signature;
const v = parseInt(cleanSig.slice(128, 130), 16);
if (v !== 0 && v !== 1) {
throw new Error(`Invalid v value for EIP-7702: ${v}. Expected 0 or 1`);
}
return signature;
};
const viemClient: WalletClient = createParaViemClient(para, {
account: viemParaAccount,
chain: arbitrumSepolia,
transport: http(rpcUrl)
});
const walletClientSigner = new WalletClientSigner(viemClient, "para");
const alchemyClient = await createModularAccountV2Client({
mode: "7702",
transport: alchemy({
rpcUrl: rpcUrl
}),
chain: arbitrumSepolia,
signer: walletClientSigner,
policyId: alchemyGasPolicyId
});
const userOpResult = await alchemyClient.sendUserOperation({
uo: {
target: "0x1234567890123456789012345678901234567890",
data: "0x",
value: parseEther("0.01"),
}
});
Copy
Ask AI
import { createParaAccount } from "@getpara/viem-v2-integration";
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 from "@getpara/web-sdk";
const para = new Para(YOUR_API_KEY);
const viemParaAccount: LocalAccount = createParaAccount(para);
viemParaAccount.signMessage = async ({ message }) => {
const signature = await para.signMessage(message);
const cleanSig = signature.startsWith("0x") ? signature.slice(2) : signature;
const v = parseInt(cleanSig.slice(128, 130), 16);
if (v < 27) {
const adjustedV = (v + 27).toString(16).padStart(2, "0");
return signature.slice(0, -2) + adjustedV;
}
return signature;
};
viemParaAccount.signAuthorization = async (authorization) => {
const signature = await para.signMessage(authorization);
const cleanSig = signature.startsWith("0x") ? signature.slice(2) : signature;
const v = parseInt(cleanSig.slice(128, 130), 16);
if (v !== 0 && v !== 1) {
throw new Error(`Invalid v value for EIP-7702: ${v}. Expected 0 or 1`);
}
return signature;
};
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"),
}),
},
});
const userOpHash = await kernelAccountClient.sendUserOperation({
userOperation: {
callData: await kernelAccount.encodeCallData({
to: "0x1234567890123456789012345678901234567890",
value: parseEther("0.01"),
data: "0x",
}),
},
});