How to calculate UserOperation's costs using the ERC-20 Paymaster
This guide will show you how to estimate your user operation's cost in denomination of the ERC-20 token as well as USD.
When using Pimlico's ERC-20 Paymaster, the pimlico_getTokenQuotes
endpoint helps you calculate the cost of your userOperation. It returns values exchangeRate
and exchangeRateNativeToUsd
. These are useful for determining how much to approve upfront or for displaying the cost to your users.
Steps
Define imports and create the clients
import { createSmartAccountClient } from "permissionless";
import { toSafeSmartAccount } from "permissionless/accounts";
import { createPimlicoClient } from "permissionless/clients/pimlico";
import { createPublicClient, formatUnits, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { entryPoint07Address } from "viem/account-abstraction";
import { base } from "viem/chains";
import { prepareUserOperationForErc20Paymaster } from "permissionless/experimental/pimlico";
const chain = base;
export const publicClient = createPublicClient({
chain,
transport: http("https://mainnet.base.org"),
});
const pimlicoUrl = `https://api.pimlico.io/v2/${chain.id}/rpc?apikey=${process.env.PIMLICO_API_KEY}`;
const pimlicoClient = createPimlicoClient({
chain,
transport: http(pimlicoUrl),
entryPoint: {
address: entryPoint07Address,
version: "0.7",
},
});
const account = await toSafeSmartAccount({
client: publicClient,
owners: [
privateKeyToAccount(
"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
),
],
entryPoint: {
address: entryPoint07Address,
version: "0.7",
},
version: "1.4.1",
});
const smartAccountClient = createSmartAccountClient({
account,
chain,
bundlerTransport: http(pimlicoUrl),
paymaster: pimlicoClient,
userOperation: {
estimateFeesPerGas: async () => {
return (await pimlicoClient.getUserOperationGasPrice()).fast;
},
prepareUserOperation: prepareUserOperationForErc20Paymaster(pimlicoClient),
},
});
Prepare the user operation
Prepare the user operation for the calls you want to make.
const token = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
const tokenDecimals = 6;
const userOperation = await smartAccountClient.prepareUserOperation({
calls: [
{
to: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
value: 0n,
data: "0x1234",
},
],
paymasterContext: {
token,
},
});
Calculate your userOperation's cost
To find the cost of your userOperation in denomination of the ERC-20 & USD, you should use pimlico client's estimateErc20PaymasterCost
action.
const { costInToken, costInUsd } =
await pimlicoClient.estimateErc20PaymasterCost({
userOperation,
token,
});
// constInToken is in token decimals
const humanReadableCostInToken = formatUnits(costInToken, tokenDecimals);
// costInUsd is ALWAYS in 6 decimals
const humanReadableCostInUSD = formatUnits(costInUsd, 6); // this should output $1.05
Note: We divide
costInUsd
is always returned with 6 decimal places and you must format it before displaying it to the user wihformatUnits(costInUsd, 6)
.