Calculate gas costs for UserOperations including bundler fees
Estimate gas costs for UserOperations with Para’s AA infrastructure before execution.
You need a deployed smart account to estimate gas for operations.
UserOperations have three gas components:
import { encodeFunctionData, parseAbi } from "viem";
async function estimateGas(
client: any,
operations: Array<{
target: string;
data?: string;
value?: bigint;
}>
) {
try {
const estimation = await client.estimateUserOperationGas({
uo: operations.map(op => ({
target: op.target,
data: op.data || "0x",
value: op.value || 0n
}))
});
console.log("Gas Estimation:");
console.log("- Call Gas Limit:", estimation.callGasLimit);
console.log("- Verification Gas Limit:", estimation.verificationGasLimit);
console.log("- Pre-verification Gas:", estimation.preVerificationGas);
const totalGas = BigInt(estimation.callGasLimit) +
BigInt(estimation.verificationGasLimit) +
BigInt(estimation.preVerificationGas);
console.log("Total Gas:", totalGas.toString());
return estimation;
} catch (error) {
console.error("Gas estimation failed:", error);
throw error;
}
}
import { formatEther } from "viem";
async function calculateGasCost(
client: any,
operations: any[]
) {
const estimation = await client.estimateUserOperationGas({ uo: operations });
const fees = await client.getUserOperationGasPrice();
const totalGasLimit = BigInt(estimation.callGasLimit) +
BigInt(estimation.verificationGasLimit) +
BigInt(estimation.preVerificationGas);
const maxCost = totalGasLimit * BigInt(fees.standard.maxFeePerGas);
console.log("Gas Price (Gwei):", fees.standard.maxFeePerGas / 1e9);
console.log("Max Cost (ETH):", formatEther(maxCost));
return {
gasEstimation: estimation,
gasPrices: fees,
maxCost: formatEther(maxCost),
maxCostWei: maxCost
};
}
import { formatEther } from "viem";
async function estimateL2Gas(
client: any,
operations: any[]
) {
const estimation = await client.estimateUserOperationGas({
uo: operations
});
console.log("L2 Gas Estimation:");
console.log("- Execution Gas:", estimation.callGasLimit);
console.log("- L1 Data Gas:", estimation.preVerificationGas);
const l1GasWarning = BigInt(estimation.preVerificationGas) > 1000000n;
if (l1GasWarning) {
console.warn("⚠️ High L1 data costs detected!");
console.warn("Consider batching operations to amortize L1 costs");
}
const bufferedPreVerificationGas =
(BigInt(estimation.preVerificationGas) * 125n) / 100n;
return {
...estimation,
preVerificationGas: bufferedPreVerificationGas.toString(),
l1DataCost: estimation.preVerificationGas,
hasHighL1Cost: l1GasWarning
};
}
async function sendWithGasOverrides(
client: any,
operations: any[]
) {
const estimation = await client.estimateUserOperationGas({ uo: operations });
const bufferedCallGasLimit =
(BigInt(estimation.callGasLimit) * 120n) / 100n;
const { hash } = await client.sendUserOperation({
uo: operations,
overrides: {
callGasLimit: bufferedCallGasLimit,
verificationGasLimit: BigInt(estimation.verificationGasLimit),
preVerificationGas: BigInt(estimation.preVerificationGas),
maxFeePerGas: await client.getGasPrice() * 2n,
maxPriorityFeePerGas: 2000000000n
}
});
console.log("UserOp sent with gas overrides:", hash);
return hash;
}