> ## 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.

# Estimate Gas

<Check>
  **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](/paymaster-&-bundler/how-to-guides/estimate-gas#state-overrides) section.
</Check>

## Implementations

<Tabs>
  <Tab title="Gelato Gasless SDK">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @gelatocloud/gasless viem
      ```

      ```bash yarn theme={null}
      yarn add @gelatocloud/gasless viem
      ```

      ```bash pnpm theme={null}
      pnpm add @gelatocloud/gasless viem
      ```
    </CodeGroup>

    <Steps>
      <Step title="Create an API Key">
        Check out our [How-To Guide](/paymaster-&-bundler/how-to-guides/create-a-api-key) for detailed instructions on generating an API key.
      </Step>

      <Step title="Create Bundler Client">
        ```typescript theme={null}
        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,
        });
        ```
      </Step>

      <Step title="Estimate Gas (Basic)">
        Use `estimateUserOperationGas()` to get gas limits for a UserOperation:

        ```typescript theme={null}
        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);
        ```
      </Step>

      <Step title="Get Fee Quote (with Token Payment)">
        Use `getUserOperationQuote()` to get gas estimation plus fee in your payment token:

        ```typescript theme={null}
        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);
        ```
      </Step>

      <Step title="Get Gas Prices">
        Use `getUserOperationGasPrice()` to get current gas prices:

        ```typescript theme={null}
        const gasPrice = await bundler.getUserOperationGasPrice();

        console.log("maxFeePerGas:", gasPrice.maxFeePerGas);
        console.log("maxPriorityFeePerGas:", gasPrice.maxPriorityFeePerGas);
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Viem">
    <Steps>
      <Step title="Create an API Key">
        Check out our [How-To Guide](/paymaster-&-bundler/how-to-guides/create-a-api-key) for detailed instructions on generating an API key.
      </Step>

      <Step title="Import Dependencies">
        ```typescript theme={null}
        import { createPublicClient, http } from 'viem'
        import { createBundlerClient, toSoladySmartAccount } from "viem/account-abstraction";
        import { privateKeyToAccount } from "viem/accounts";
        import { baseSepolia } from "viem/chains";
        ```
      </Step>

      <Step title="Setup Smart Account">
        Any smart account that implements viem's `Account` type can be used here.
        Check out other available smart accounts [here](https://viem.sh/account-abstraction/accounts/smart).

        <Note>
          You can also use smart accounts from [permissionless](https://docs.pimlico.io/permissionless) like `toKernelSmartAccount`, `toLightSmartAccount`, etc. The bundler client setup and gas estimation work the same way.
        </Note>

        ```typescript theme={null}
        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,
        });
        ```
      </Step>

      <Step title="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](https://viem.sh/account-abstraction/clients/bundler).

        ```typescript theme={null}
        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),
              };
            },
          },
        })
        ```
      </Step>

      <Step title="Estimate Gas">
        Estimate gas for a `UserOperation` with the `bundlerClient` and the `account`.

        ```typescript theme={null}
        const results = await bundlerClient.estimateUserOperationGas({
          account,
          calls: [{ to: account.address, value: 0n, data: "0x" }],
        })

        console.log("Estimated gas values: ", results);
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Bundler API Endpoints">
    Use `https://api.gelato.cloud` for both mainnets and testnets. Pass the API key in the `X-API-Key` header.

    <Steps>
      <Step title="Create an API Key">
        Check out our [How-To Guide](/paymaster-&-bundler/how-to-guides/create-a-api-key) for detailed instructions on generating an API key.
      </Step>

      <Step title="Get Gas Prices">
        ```typescript theme={null}
        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);
        ```
      </Step>

      <Step title="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.)

        ```typescript theme={null}
        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);
        ```
      </Step>
    </Steps>

    <Check>
      Check out the required parameters for estimating gas in the following scenarios:

      * [Using Gas Tank](https://github.com/gelatodigital/how-to-use-bundler-api-endpoints/blob/main/eth_estimateUserOperationGas/Gas-Tank/SponsoredGas.ts)
      * [Using Onchain Paymasters](https://github.com/gelatodigital/how-to-use-bundler-api-endpoints/tree/main/eth_estimateUserOperationGas/OnChain-Paymasters)
      * [Using Native Payments](https://github.com/gelatodigital/how-to-use-bundler-api-endpoints/blob/main/eth_estimateUserOperationGas/Native-Payments/NativeGasPayments.ts)
    </Check>
  </Tab>
</Tabs>

## State Overrides

While estimating gas, you can include state overrides such as balance, code, etc. to test the gas cost with different state values.

<Tabs>
  <Tab title="Gelato Gasless SDK / Viem">
    ```typescript theme={null}
    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);
    ```
  </Tab>

  <Tab title="Bundler API Endpoints">
    Include a state override object in your API request:

    ```typescript theme={null}
    import { toHex } from 'viem';

    const stateOverride = {
      [account.address]: {
        //code: "",
        //nonce: "",
        balance: toHex(100000000000000000000n),
        //state:{},
        //stateDiff:{},
      },
    };
    ```
  </Tab>
</Tabs>

Checkout parameters for state overrides [here](https://viem.sh/account-abstraction/actions/bundler/estimateUserOperationGas#stateoverride-optional) and full example code [here](https://github.com/gelatodigital/how-to-use-bundler-api-endpoints/blob/main/eth_estimateUserOperationGas/State-Overrides/stateOverrideExample.ts).

## 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` |
