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

# Pay with Native Tokens

## Overview

Users can pay gas fees directly with native tokens from their smart accounts. This provides a familiar payment method while still benefiting from the enhanced features of smart wallets.

## Implementations

<Tabs>
  <Tab title="Using Gelato Gasless SDK">
    ## 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>

    ### Example: Gelato Smart Account

    <Steps>
      <Step title="Import Dependencies">
        ```typescript theme={null}
        import { createGelatoBundlerClient, toGelatoSmartAccount, token } from '@gelatocloud/gasless';
        import { baseSepolia } from "viem/chains";
        import { createPublicClient, http } from 'viem';
        import { privateKeyToAccount } from "viem/accounts";
        ```
      </Step>

      <Step title="Create Gelato Smart Account">
        ```typescript theme={null}
        const owner = privateKeyToAccount(process.env.PRIVATE_KEY);

        const client = createPublicClient({
          chain: baseSepolia,
          transport: http(),
        });

        const account = await toGelatoSmartAccount({
          client,
          owner,
        });
        ```
      </Step>

      <Step title="Create Gelato Bundler Client">
        ```typescript theme={null}
        const tokenAddress = "0x0000000000000000000000000000000000000000"; // Native

        const bundler = await createGelatoBundlerClient({
          account,
          apiKey: process.env.GELATO_API_KEY,
          client,
          payment: token(tokenAddress),
          pollingInterval: 100
        });
        ```
      </Step>

      <Step title="Send User Operation">
        ```typescript theme={null}
        const hash = await bundler.sendUserOperation({
          calls: [
            {
              data: '0xd09de08a',
              to: '0xE27C1359cf02B49acC6474311Bd79d1f10b1f8De'
            }
          ]
        });
        console.log(`User operation hash: ${hash}`);

        const { receipt } = await bundler.waitForUserOperationReceipt({ hash });
        console.log(`Transaction hash: ${receipt.transactionHash}`);
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Using Viem">
    ## Viem

    To start sending transactions while paying gas with native tokens using Viem, follow these steps:

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

        ```typescript theme={null}
        const publicClient = createPublicClient({ chain: baseSepolia, transport: http() });
        const signer = privateKeyToAccount(PRIVATE_KEY as any);

        const account = await toSoladySmartAccount({
          client: publicClient,
          owner: signer,
        });
        ```
      </Step>

      <Step title="Create a 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/${chainId}/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="Send a UserOperation">
        Send a `UserOperation` with the `bundlerClient`. The smart account must hold native tokens (ETH) to pay for gas fees.

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

        console.log("UserOperation Hash: ", userOperationHash);

        const receipt = await bundlerClient.waitForUserOperationReceipt({ hash: userOperationHash });
        console.log("Transaction Hash: ", receipt.receipt.transactionHash);
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Using Permissionless">
    ## Permissionless

    <CodeGroup>
      ```bash npm theme={null}
      npm install permissionless viem
      ```

      ```bash yarn theme={null}
      yarn add permissionless viem
      ```

      ```bash pnpm theme={null}
      pnpm add permissionless viem
      ```
    </CodeGroup>

    ## Basic Setup

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

      <Step title="Create Smart Account">
        ```typescript theme={null}
        const owner = privateKeyToAccount(process.env.PRIVATE_KEY);

        const publicClient = createPublicClient({
          chain: baseSepolia,
          transport: http(),
        });

        const account = await toKernelSmartAccount({
          client: publicClient,
          owners: [owner],
          entryPoint: {
            address: entryPoint07Address,
            version: "0.7",
          },
          version: "0.3.3",
        });
        ```
      </Step>

      <Step title="Create Bundler Client with Gelato">
        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({
          client: publicClient,
          transport: http(`https://api.gelato.digital/bundlers/${chainId}/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="Send User Operation">
        The smart account must hold native tokens (ETH) to pay for gas fees.

        ```typescript theme={null}
        const userOpHash = await bundlerClient.sendUserOperation({
          account,
          calls: [
            {
              to: "0xE27C1359cf02B49acC6474311Bd79d1f10b1f8De",
              data: "0xd09de08a", // increment()
              value: 0n,
            },
          ],
        });

        console.log("UserOperation Hash: ", userOpHash);

        const receipt = await bundlerClient.waitForUserOperationReceipt({
          hash: userOpHash,
        });
        console.log(`Transaction successful: ${receipt.receipt.transactionHash}`);
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Using API Endpoints">
    ### Authentication

    Use `https://api.gelato.cloud` for both mainnets and testnets.

    Pass the API key in the `X-API-Key` header.

    ### Basic Example

    <Steps>
      <Step title="Send User Operation">
        ```typescript theme={null}
        const tokenAddress = "0x0000000000000000000000000000000000000000"; // Native

        const response = await fetch(
          `https://api.gelato.cloud/rpc/${chainId}?payment=token&token=${tokenAddress}`,
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "X-API-Key": process.env.GELATO_API_KEY
            },
            body: JSON.stringify({
              jsonrpc: "2.0",
              method: "eth_sendUserOperation",
              params: [userOperation, entryPoint],
              id: 1,
            }),
          }
        );

        const data = await response.json();
        const userOpHash = data.result;
        ```
      </Step>

      <Step title="Estimate Gas">
        ```typescript theme={null}
        const tokenAddress = "0x0000000000000000000000000000000000000000"; // Native

        const response = await fetch(
          `https://api.gelato.cloud/rpc/${chainId}?payment=token&token=${tokenAddress}`,
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "X-API-Key": process.env.GELATO_API_KEY
            },
            body: JSON.stringify({
              jsonrpc: "2.0",
              method: "eth_estimateUserOperationGas",
              params: [userOperation, entryPoint],
              id: 1,
            }),
          }
        );

        const data = await response.json();
        const gasEstimate = data.result;
        ```
      </Step>

      <Step title="Get User Operation Receipt">
        ```typescript theme={null}
        const response = await fetch(
          `https://api.gelato.cloud/rpc/${chainId}`,
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "X-API-Key": process.env.GELATO_API_KEY
            },
            body: JSON.stringify({
              jsonrpc: "2.0",
              method: "eth_getUserOperationReceipt",
              params: [userOpHash],
              id: 1,
            }),
          }
        );

        const data = await response.json();
        const receipt = data.result;
        ```
      </Step>
    </Steps>

    ### Available Endpoints

    <Columns cols={2}>
      <Card title="eth_sendUserOperation" icon="send" href="/paymaster-&-bundler/bundler-api-endpoints/bundlers/eth_senduseroperation">
        Send a user operation to the bundler
      </Card>

      <Card title="eth_estimateUserOperationGas" icon="calculator" href="/paymaster-&-bundler/bundler-api-endpoints/bundlers/eth_estimateuseroperationgas">
        Estimate gas for a user operation
      </Card>

      <Card title="eth_getUserOperationReceipt" icon="receipt" href="/paymaster-&-bundler/bundler-api-endpoints/bundlers/eth_getuseroperationreceipt">
        Get receipt for a user operation
      </Card>

      <Card title="eth_getUserOperationByHash" icon="search" href="/paymaster-&-bundler/bundler-api-endpoints/bundlers/eth_getuseroperationbyhash">
        Get user operation by hash
      </Card>
    </Columns>
  </Tab>
</Tabs>

## Additional Resources

* [Supported Networks](/paymaster-&-bundler/additional-resources/supported-networks) - Check network availability
