Gelato
  • Introduction
    • Gelato, The Web3 Cloud Platform
  • Rollup As A Service
    • Introduction
    • Rollup Stacks
      • Arbitrum Orbit
        • Run a Full Orbit Node
      • OP Stack
        • Run OP Node
    • Deploy your Rollup
    • Customization
      • Data Availability
        • Celestia
        • Avail
        • Eigen DA
      • Custom Gas Token
      • Marketplace
        • Gelato Services
        • Data Indexers
        • Block Explorers
        • Oracles
        • Bridges
        • Account Abstraction
        • On & Off-ramp
        • Community
        • Identity & KYC
        • Others
      • Verifier Node Package
    • Public Testnet
  • RPC Nodes
    • Introduction
    • Compute Units
    • Using RPC Nodes
    • Supported Networks
    • Pricing and Plans
    • FAQ
  • Web3 Services
    • Web3 Functions
      • Understanding Web3 Functions
        • Trigger Types
        • Typescript Function
        • Solidity Function
        • Automated Transactions
      • Security Considerations
      • Template & Use Cases
      • Quick Start
        • Writing Typescript Functions
          • Event Trigger
          • Private Typescript Functions
          • Callbacks
        • Test, Deploy & Run Typescript functions
        • Writing Solidity Functions
        • Test, Deploy & Run Solidity Functions
        • Initiate an Automated Transaction
      • Create a Web3 Function Task
        • Using the UI
        • Using the Safe App
        • Using a Smart Contract
        • Using the Automate SDK
      • Analytics & Monitoring
      • Supported Networks
      • Subscription & Payments
      • Legacy Automate Migration Guide
    • Relay
      • What is Relaying?
      • Security Considerations
        • ERC-2771 Delegatecall Vulnerability
      • Templates
      • Quick Start
        • Sponsored Calls
        • Non-Sponsored Calls
      • ERC-2771 (recommended)
        • SponsoredCallERC2771
        • CallWithSyncFeeERC2771
          • Relay Context Contracts ERC2771
      • Non-ERC-2771
        • SponsoredCall
        • CallWithSyncFee
          • Relay Context Contracts
      • Relay API
      • Gelato's Fee Oracle
      • Tracking your Relay Request
      • Supported Networks
      • Subscriptions and Payments
        • 1Balance & Relay
        • SyncFee Payment Tokens
        • Relay Pricing
      • ERC2771 Migration Guide
    • VRF
      • Understanding VRF
      • How does Gelato VRF Work?
      • Security Considerations
      • Template
      • Quick Start
      • Create a VRF Task
        • Create a Fallback VRF
        • Migrating from Chainlink VRF
      • Supported Networks
      • Pricing & Rate Limits
    • Oracles
      • Understanding Gelato Oracles
      • Quick Start
      • Data Providers
        • Stork
        • Choas Labs
      • Migrating from Chainlink Oracles
      • Available Price Feeds
      • Supported Networks
      • Pricing & Rate Limits
    • Account Abstraction
      • Understanding ERC4337
      • Introduction to Gelato Bundler
      • Templates & Examples
      • Quick Start
      • Sponsored UserOps
        • Using 1Balance
        • Using Zerodev Paymaster
      • Non-Sponsored UserOps
        • Pay with Native
        • Pay with ERC20
      • Supported Networks
      • Bundler API Endpoints
        • eth_sendUserOperation
        • eth_estimateUserOperationGas
        • eth_getUserOperationByHash
        • eth_getUserOperationReceipt
        • eth_supportedEntryPoints
        • eth_maxPriorityFeePerGas
        • eth_chainId
    • 1Balance
      • 1Balance Alerts
      • Subscription Plans
      • Subscription Notifications
      • USDC Addresses
    • AI Agents
    • Teams
  • GELATO DAO
    • DAO & Token (GEL)
    • GEL Token Contracts
    • Governance Process
  • Social Media
Powered by GitBook
On this page
  • Example Code
  • 1. Create an account using createKernelAccount from @zerodev/sdk
  • 2. Create an Client using createKernelAccountClient adding Gelato Bundler RPC
  • 3. Send UserOperation using kernelClient
  • 4. Check UserOp status using Relay API
  1. Web3 Services
  2. Account Abstraction
  3. Non-Sponsored UserOps

Pay with Native

This page details the process of paying the gas of user operations (UserOps) using native tokens.

PreviousNon-Sponsored UserOpsNextPay with ERC20

Last updated 2 months ago

Native token payments are currently restricted to testnets as part of our staging environment. For this functionality, please use staging Gelato Bundler RPC as bundler transport. Checkout testnets listed .

After reading this page:

  • You'll know how to pay gas for UserOps using native tokens.

  • You'll learn about how to use Zerodev Kernel and Safe as an smart account to pay gas .

  • You'll see some code which will help you send a Non-Sponsored UserOp within minutes.

This method doesn’t require a paymaster, making it a straightforward and direct way to send UserOps while paying with native tokens from your smart account.

Example Code

1. Create an account using createKernelAccount from @zerodev/sdk

const entryPoint = getEntryPoint("0.7");
const kernelVersion = KERNEL_V3_1;

const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
    signer,
    entryPoint,
    kernelVersion,
});

const account = await createKernelAccount(publicClient, {
    plugins: {
      sudo: ecdsaValidator,
    },
    entryPoint,
    kernelVersion
});

2. Create an Client using createKernelAccountClient adding Gelato Bundler RPC

When using the Gelato Bundler, it's essential to use a specialized gas estimation method when creating the kernelClient.

const gasPrices = await bundlerClient.request<EthGetUserOperationGasPriceRpc>({
            method: "eth_getUserOperationGasPrice",
            params: [],
});
const maxFeePerGas = BigInt(gasPrices.maxFeePerGas),
const maxPriorityFeePerGas = BigInt(gasPrices.maxPriorityFeePerGas),
const kernelClient = createKernelAccountClient({
    account,
    chain: baseSepolia,
    bundlerTransport: http(STAGING_BUNDLER_RPC),
    client: publicClient,
    userOperation: {
      estimateFeesPerGas: async ({ bundlerClient }) => {
        const gasPrices =
          await bundlerClient.request<EthGetUserOperationGasPriceRpc>({
            method: "eth_getUserOperationGasPrice",
            params: [],
          });
        return {
          maxFeePerGas: BigInt(gasPrices.maxFeePerGas),
          maxPriorityFeePerGas: BigInt(gasPrices.maxPriorityFeePerGas),
        };
      },
    },
});

Gas Config Types

type GasPrices = {
  maxFeePerGas: string;
  maxPriorityFeePerGas: string;
};

type EthGetUserOperationGasPriceRpc = {
  ReturnType: GasPrices;
  Parameters: [];
};

3. Send UserOperation using kernelClient

console.log("Preparing dummy transaction");
const callData = await kernelClient.account.encodeCalls([
    {
      to: "0x0000000000000000000000000000000000000000",
      value: BigInt(0),
      data: "0x",
    },
  ]);

console.log("Sending user operation...");
const userOpHash = await kernelClient.sendUserOperation({ callData });
console.log("UserOp taskId:", userOpHash);

4. Check UserOp status using Relay API

The userOpHash, when using the Gelato Bundler, is equivalent to the Task ID. This Task ID can be easily debugged through the Relay API, providing a streamlined method for troubleshooting and monitoring the status of transactions. Checkout .

Explore the complete example code that demonstrates how to pay using native tokens while using Gelato Bundler with the ZeroDev Kernel , as well as how to integrate with a Safe account .

here
here
here
here