Documentation Index
Fetch the complete documentation index at: https://docs.gelato.cloud/llms.txt
Use this file to discover all available pages before exploring further.
Best Practices/Recommendations:
- We recommend users to rely on the exact values returned by the gas estimation endpoints rather than applying buffers, as the values provided by our bundler are designed to handle gas price volatility effectively.
- In case you want to estimate gas cost with some state overrides such as balance, code, etc., you can check our state override section.
Implementations
Gelato Gasless SDK
Viem
Bundler API Endpoints
npm install @gelatocloud/gasless viem
Create an API Key
Check out our How-To Guide for detailed instructions on generating an API key. Create Bundler Client
import {
createGelatoBundlerClient,
token,
} from "@gelatocloud/gasless";
import { createPublicClient, http, type Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
import { toSoladySmartAccount } from "viem/account-abstraction";
const owner = privateKeyToAccount(process.env.PRIVATE_KEY as Hex);
const client = createPublicClient({
chain: baseSepolia,
transport: http(),
});
const account = await toSoladySmartAccount({
client,
owner,
});
const bundler = await createGelatoBundlerClient({
account,
client,
apiKey: process.env.GELATO_API_KEY,
});
Estimate Gas (Basic)
Use estimateUserOperationGas() to get gas limits for a UserOperation:const gasEstimate = await bundler.estimateUserOperationGas({
calls: [
{
to: "0xE27C1359cf02B49acC6474311Bd79d1f10b1f8De",
data: "0xd09de08a",
},
],
});
console.log("callGasLimit:", gasEstimate.callGasLimit);
console.log("verificationGasLimit:", gasEstimate.verificationGasLimit);
console.log("preVerificationGas:", gasEstimate.preVerificationGas);
Get Fee Quote (with Token Payment)
Use getUserOperationQuote() to get gas estimation plus fee in your payment token:const USDC_ADDRESS = "0x036CbD53842c5426634e7929541eC2318f3dCF7e"; // Base Sepolia
const bundlerWithToken = await createGelatoBundlerClient({
account,
client,
apiKey: process.env.GELATO_API_KEY,
payment: token(USDC_ADDRESS),
});
const quote = await bundlerWithToken.getUserOperationQuote({
calls: [
{
to: "0xE27C1359cf02B49acC6474311Bd79d1f10b1f8De",
data: "0xd09de08a",
},
],
});
console.log("Fee:", quote.fee); // Fee in USDC
console.log("Total gas:", quote.gas); // Total gas
console.log("L1 fee:", quote.l1Fee); // L1 data fee (L2 chains)
console.log("callGasLimit:", quote.callGasLimit);
Get Gas Prices
Use getUserOperationGasPrice() to get current gas prices:const gasPrice = await bundler.getUserOperationGasPrice();
console.log("maxFeePerGas:", gasPrice.maxFeePerGas);
console.log("maxPriorityFeePerGas:", gasPrice.maxPriorityFeePerGas);
Create an API Key
Check out our How-To Guide for detailed instructions on generating an API key. Import Dependencies
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toSoladySmartAccount } from "viem/account-abstraction";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
Setup Smart Account
Any smart account that implements viem’s Account type can be used here.
Check out other available smart accounts here.You can also use smart accounts from permissionless like toKernelSmartAccount, toLightSmartAccount, etc. The bundler client setup and gas estimation work the same way. const publicClient = createPublicClient({
chain: baseSepolia,
transport: http()
});
const signer = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const account = await toSoladySmartAccount({
client: publicClient,
owner: signer,
});
Create Bundler Client
Create a BundlerClient with the account and publicClient. Use https://api.gelato.digital/bundlers as the bundler endpoint.Pass the API key as a query parameter. Learn more about Bundler Client here.const bundlerClient = createBundlerClient({
account,
client: publicClient,
transport: http(`https://api.gelato.digital/bundlers/${baseSepolia.id}/rpc?apiKey=${process.env.GELATO_API_KEY}`),
userOperation: {
estimateFeesPerGas: async ({ bundlerClient }) => {
const gasPrices = await bundlerClient.request({
method: "eth_getUserOperationGasPrice",
params: [],
});
return {
maxFeePerGas: BigInt(gasPrices.maxFeePerGas),
maxPriorityFeePerGas: BigInt(gasPrices.maxPriorityFeePerGas),
};
},
},
})
Estimate Gas
Estimate gas for a UserOperation with the bundlerClient and the account.const results = await bundlerClient.estimateUserOperationGas({
account,
calls: [{ to: account.address, value: 0n, data: "0x" }],
})
console.log("Estimated gas values: ", results);
Use https://api.gelato.cloud for both mainnets and testnets. Pass the API key in the X-API-Key header.Create an API Key
Check out our How-To Guide for detailed instructions on generating an API key. Get Gas Prices
const chainId = 84532; // Base Sepolia
const response = await fetch(
`https://api.gelato.cloud/rpc/${chainId}?payment=sponsored`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.GELATO_API_KEY
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "eth_getUserOperationGasPrice",
params: []
})
}
);
const data = await response.json();
console.log("maxFeePerGas:", data.result.maxFeePerGas);
console.log("maxPriorityFeePerGas:", data.result.maxPriorityFeePerGas);
Estimate User Operation Gas
Configure the UserOperation with:
- Set
maxFeePerGas and maxPriorityFeePerGas to 0 (0x0) for sponsored transactions
- Leave paymaster-related fields empty (
paymaster, paymasterData, etc.)
const response = await fetch(
`https://api.gelato.cloud/rpc/${chainId}?payment=sponsored`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.GELATO_API_KEY
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "eth_estimateUserOperationGas",
params: [
{
sender: "0xYourSmartAccountAddress",
nonce: "0x0",
callData: "0xCalldata",
maxFeePerGas: "0x0",
maxPriorityFeePerGas: "0x0",
signature: "0xDummySignature"
},
"0xEntryPointAddress"
]
})
}
);
const data = await response.json();
console.log("callGasLimit:", data.result.callGasLimit);
console.log("verificationGasLimit:", data.result.verificationGasLimit);
console.log("preVerificationGas:", data.result.preVerificationGas);
Check out the required parameters for estimating gas in the following scenarios:
State Overrides
While estimating gas, you can include state overrides such as balance, code, etc. to test the gas cost with different state values.
const results = await bundler.estimateUserOperationGas({
stateOverride: [
{
address: account.address,
balance: 100000000000000000000n,
},
],
calls: [{ to: account.address, value: 0n, data: "0x" }],
});
console.log("Estimated gas values:", results);
Include a state override object in your API request:import { toHex } from 'viem';
const stateOverride = {
[account.address]: {
//code: "",
//nonce: "",
balance: toHex(100000000000000000000n),
//state:{},
//stateDiff:{},
},
};
Checkout parameters for state overrides here and full example code here.
SDK Methods Reference
| Method | Description | Returns |
|---|
estimateUserOperationGas() | Standard ERC-4337 gas estimation | Gas limits only |
getUserOperationQuote() | Gas estimation + fee in payment token | Gas limits + fee |
getUserOperationGasPrice() | Current gas prices | maxFeePerGas, maxPriorityFeePerGas |