Presets
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 Smart 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.
View the source code for Presets on GitHub.
Preset for [insert favorite 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
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.
Looking for a concrete example?
All builder presets are also used in the ERC-4337 examples repo. For each preset, you can find working code samples in the scripts directory.
SimpleAccount
The SimpleAccount preset is an abstraction to build User Operations for an ERC-4337 account based on SimpleAccount.sol.
import { Client, Presets } from "userop";
const simpleAccount = await Presets.Builder.SimpleAccount.init(
signer, // Any object compatible with ethers.Signer
config.rpcUrl
);
const client = await Client.init(config.rpcUrl);
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}`);
Kernel
The Kernel preset is an abstraction to build User Operations for an ERC-4337 account based on ZeroDev Kernel V2 - a modular contract account framework. It deploys with the ECDSA validator by default.
Only available on Polygon Mumbai
Kernel V2 factories and validators are currently only deployed on Polygon Mumbai.
import { Client, Presets } from "userop";
const kernel = await Presets.Builder.Kernel.init(
signer, // Any object compatible with ethers.Signer
config.rpcUrl,
);
const client = await Client.init(config.rpcUrl);
const res = await client.sendUserOperation(
kernel.execute({to, value, data: "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
Middleware presets are common implementations of middleware functions that can be re-used for different builder instances.
View middleware functions on GitHub.
estimateUserOperationGas
estimateUserOperationGas
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))
getGasPrice
getGasPrice
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))
verifyingPaymaster
verifyingPaymaster
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)
)
EOASignature
EOASignature
A middleware function for signing the User Operation with an 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))
Updated about 1 year ago