UserOp.js ships with common presets that can help you get started even quicker with certain use cases.

The builder interface is flexible enough to support any implementation of an ERC-4337 Contract Account. However, there are already a few common implementations used within the ecosystem already. Rather then create the same builder and middleware functions over and over again, we've shipped a few useful presets for commonly used implementations.


Preset for [insert favourite contract account] is not included?? :(

No worries! UserOp.js is open for PRs. Alternatively, let us know what type of presets you'd like to see and we'll work together to get it shipped. 🤝


Builder presets are pre-configured builders over a known contract account implementation. Presets can be used as-is or modified with the get and set functions.


The SimpleAccount preset is an abstraction to build UserOperations for an ERC-4337 account based on SimpleAccount.sol. Like all presets, it can be used as-is, modified, or expanded for your specific application.


Looking for a concrete example?

SimpleAccount preset is used throughout the ERC-4337 examples repo. A code sample for executing a ETH transfer can be found here.

import { Client, Presets } from "userop";

const simpleAccount = await Presets.Builder.SimpleAccount.init(
  signer, // Any object compatible with ethers.Signer
const client = await Client.init(config.rpcUrl, config.entryPoint);

const res = await client.sendUserOperation(
  simpleAccount.execute(target, value, "0x"),
  { onBuild: (op) => console.log("Signed UserOperation:", op) }
console.log(`UserOpHash: ${res.userOpHash}`);

console.log("Waiting for transaction...");
const ev = await res.wait();
console.log(`Transaction hash: ${ev?.transactionHash ?? null}`);


Middleware presets are common implementations of middleware functions that can be re-used for different builder instances.


A middleware function for sending UserOperations to the eth_estimateUserOperationGas endpoint in order to estimate reasonable gas limits for preVerificationGas, verificationGasLimit, and callGasLimit.

import { Presets } from "userop";

// provider is an ethers.js JSON-RPC provider.
builder = builder.useMiddleware(Presets.Middleware.estimateUserOperationGas(provider))


A middleware function for getting the latest values for maxFeePerGas and maxPriorityFeePerGas.

import { Presets } from "userop";

// provider is an ethers.js JSON-RPC provider.
builder = builder.useMiddleware(Presets.Middleware.getGasPrice(provider))


A middleware function for requesting gas sponsorship from a paymaster service. The middleware assumes that the service implements this proposed JSON-RPC API for verifying paymasters.

import { Presets } from "userop";

builder = builder.useMiddleware(
  Presets.Middleware.verifyingPaymaster(paymasterRpc, paymasterCtx)


A middleware function for signing the UserOperation with a EOA private key.

import { ethers } from "ethers";
import { Presets } from "userop";

// signer is an ethers.js Wallet instance.
const signer = new ethers.Wallet(signingKey);
builder = builder.useMiddleware(Presets.Middleware.EOASignature(signer))