Skip to content
LogoLogo

estimateUserOperationGas

Estimates the gas values for a User Operation to be executed successfully.

Usage

import {  } from 'viem'
import { ,  } from './config'
 
const  = await .({ 
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }]
})

Account Hoisting

If you do not wish to pass an account to every estimateUserOperationGas, you can also hoist the Account on the Bundler Client (see config.ts).

Learn more.

// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { parseEther } from 'viem'
import { bundlerClient } from './config'
 
const gas = await bundlerClient.estimateUserOperationGas({ 
  calls: [{
    to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    value: parseEther('1')
  }]
})

Contract Calls

The calls property also accepts Contract Calls, and can be used via the abi, functionName, and args properties.

// @filename: abi.ts
export const wagmiAbi = [
  // ...
  {
    inputs: [],
    name: "mint",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
  // ...
] as const;
// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { parseEther } from 'viem'
import { bundlerClient, publicClient } from './config'
import { wagmiAbi } from './abi'
 
const gas = await bundlerClient.estimateUserOperationGas({ 
  calls: [{
    abi: wagmiAbi,
    functionName: 'mint',
    to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  }],
})

Returns

{
  callGasLimit: bigint;
  preVerificationGas: bigint;
  verificationGasLimit: bigint;
  paymasterVerificationGasLimit: bigint | undefined;
  paymasterPostOpGasLimit: bigint | undefined;
}

The estimated gas values.

Parameters

account

  • Type: SmartAccount

The Account to use for User Operation execution.

const  = await .({
  , 
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }]
})

calls

  • Type: { data: Hex, to: Address, value: bigint }[]

The calls to execute in the User Operation.

const  = await .({
  ,
  : [{ 
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', 
    : ('1') 
  }] 
})

callGasLimit (optional)

  • Type: bigint

The amount of gas to allocate the main execution call.

const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : 69420n, 
})

factory (optional)

  • Type: Address

Account Factory address.

// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { parseEther } from 'viem'
import { account, bundlerClient } from './config'
// ---cut---
const gas = await bundlerClient.estimateUserOperationGas({
  account,
  calls: [{
    to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    value: parseEther('1')
  }],
  factory: '0x1234567890123456789012345678901234567890', 
  factoryData: '0xdeadbeef',
})

factoryData (optional)

  • Type: Hex

Call data to execute on the Account Factory to deploy a Smart Account.

// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { parseEther } from 'viem'
import { account, bundlerClient } from './config'
// ---cut---
const gas = await bundlerClient.estimateUserOperationGas({
  account,
  calls: [{
    to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    value: parseEther('1')
  }],
  factory: '0x1234567890123456789012345678901234567890',
  factoryData: '0xdeadbeef', 
})

maxFeePerGas (optional)

  • Type: bigint

Maximum fee per gas for User Operation execution.

const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : 420n, 
})

maxPriorityFeePerGas (optional)

  • Type: bigint

Maximum priority fee per gas for User Operation execution.

const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : 420n, 
  : 10n, 
})

nonce (optional)

  • Type: bigint

Nonce for the User Operation.

const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : 10n, 
})

paymaster (optional)

  • Type: Address | true | PaymasterClient | PaymasterActions

Sets Paymaster configuration for the User Operation.

  • If paymaster: Address, it will use the provided Paymaster contract address for sponsorship.
  • If paymaster: PaymasterClient, it will use the provided Paymaster Client for sponsorship.
  • If paymaster: true, it will be assumed that the Bundler Client also supports Paymaster RPC methods (e.g. pm_getPaymasterData), and use them for sponsorship.
  • If custom functions are provided to paymaster, it will use them for sponsorship.

Using a Paymaster Contract Address

// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { account, bundlerClient } from './config'
// ---cut---
const hash = await bundlerClient.estimateUserOperationGas({
  account,
  calls: [{
    to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    value: parseEther('1')
  }],
  paymaster: '0x942fD5017c0F60575930D8574Eaca13BEcD6e1bB', 
  paymasterData: '0xdeadbeef',
})

Using a Paymaster Client

import { ,  } from 'viem'
import {  } from 'viem/account-abstraction'
 
const  = ({ 
  : ('https://api.pimlico.io/v2/1/rpc?apikey={API_KEY}') 
}) 
 
const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : , 
})

Using the Bundler Client as Paymaster

// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { account, bundlerClient } from './config'
// ---cut---
const hash = await bundlerClient.estimateUserOperationGas({
  account,
  calls: [{
    to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    value: parseEther('1')
  }],
  paymaster: true, 
})

paymasterContext (optional)

  • Type: unknown

Paymaster specific fields.

import { ,  } from 'viem'
import {  } from 'viem/account-abstraction'
 
const  = ({
  : ('https://public.pimlico.io/v2/11155111/rpc')
})
 
const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : ,
  : { 
    : 'abc123'
  }, 
})

paymasterData (optional)

  • Type: Address

Call data to execute on the Paymaster contract.

// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { parseEther } from 'viem'
import { account, bundlerClient } from './config'
// ---cut---
const gas = await bundlerClient.estimateUserOperationGas({
  account,
  calls: [{
    to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    value: parseEther('1')
  }],
  paymaster: '0x942fD5017c0F60575930D8574Eaca13BEcD6e1bB',
  paymasterData: '0xdeadbeef', 
})

paymasterPostOpGasLimit (optional)

  • Type: bigint

The amount of gas to allocate for the Paymaster post-operation code.

// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { parseEther } from 'viem'
import { account, bundlerClient } from './config'
// ---cut---
const gas = await bundlerClient.estimateUserOperationGas({
  account,
  calls: [{
    to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    value: parseEther('1')
  }],
  paymaster: '0x942fD5017c0F60575930D8574Eaca13BEcD6e1bB',
  paymasterData: '0xdeadbeef',
  paymasterPostOpGasLimit: 69420n, 
})

paymasterVerificationGasLimit (optional)

  • Type: bigint

The amount of gas to allocate for the Paymaster validation code.

// @filename: config.ts
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toCoinbaseSmartAccount } from 'viem/account-abstraction'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const account = await toCoinbaseSmartAccount({
  client,
  owners: [privateKeyToAccount('0x...')],
  version: '1.1',
})
 
export const bundlerClient = createBundlerClient({
  client,
  transport: http('https://public.pimlico.io/v2/1/rpc')
})
// @filename: example.ts
// ---cut---
import { parseEther } from 'viem'
import { account, bundlerClient } from './config'
// ---cut---
const gas = await bundlerClient.estimateUserOperationGas({
  account,
  calls: [{
    to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    value: parseEther('1')
  }],
  paymaster: '0x942fD5017c0F60575930D8574Eaca13BEcD6e1bB',
  paymasterData: '0xdeadbeef',
  paymasterVerificationGasLimit: 69420n, 
})

preVerificationGas (optional)

  • Type: bigint

Extra gas to pay the Bundler.

const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : 69420n, 
})

signature (optional)

  • Type: Hex

Signature for the User Operation.

const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : '0x...', 
})

stateOverride (optional)

The state override set is an optional address-to-state mapping, where each entry specifies some state to be ephemerally overridden prior to executing the call.

const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : [ 
    { 
      : '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', 
      : ('1'), 
      : [ 
        { 
          : '0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0', 
          : '0x00000000000000000000000000000000000000000000000000000000000001a4', 
        }, 
      ], 
    } 
  ], 
})

verificationGasLimit (optional)

  • Type: bigint

The amount of gas to allocate for the verification step.

const  = await .({
  ,
  : [{
    : '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
    : ('1')
  }],
  : 69420n, 
})