Builder
A UserOperation is a pseudo-transaction object used to execute actions through a smart contract account. Although it can be quite complex to create, the UserOperationBuilder
simplifies this process using the builder pattern.
Interfaces
These interfaces are built using common ethers.js types. More specifically BigNumberish and BytesLike.
UserOperation
An interface for an ERC-4337 User Operation. Building a UserOperation
involves constructing multiple parts and merging them together.
tsx
interface IUserOperation {
sender: string;
nonce: BigNumberish;
initCode: BytesLike;
callData: BytesLike;
callGasLimit: BigNumberish;
verificationGasLimit: BigNumberish;
preVerificationGas: BigNumberish;
maxFeePerGas: BigNumberish;
maxPriorityFeePerGas: BigNumberish;
paymasterAndData: BytesLike;
signature: BytesLike;
}
interface IUserOperation {
sender: string;
nonce: BigNumberish;
initCode: BytesLike;
callData: BytesLike;
callGasLimit: BigNumberish;
verificationGasLimit: BigNumberish;
preVerificationGas: BigNumberish;
maxFeePerGas: BigNumberish;
maxPriorityFeePerGas: BigNumberish;
paymasterAndData: BytesLike;
signature: BytesLike;
}
UserOperationBuilder
An instance of UserOperationBuilder
can help build a UserOperation
that can be passed to the client.
tsx
const builder = new UserOperationBuilder();
const builder = new UserOperationBuilder();
tsx
interface IUserOperationBuilder {
// get methods.
getSender: () => string;
getNonce: () => BigNumberish;
getInitCode: () => BytesLike;
getCallData: () => BytesLike;
getCallGasLimit: () => BigNumberish;
getVerificationGasLimit: () => BigNumberish;
getPreVerificationGas: () => BigNumberish;
getMaxFeePerGas: () => BigNumberish;
getMaxPriorityFeePerGas: () => BigNumberish;
getPaymasterAndData: () => BytesLike;
getSignature: () => BytesLike;
getOp: () => IUserOperation;
// set methods.
setSender: (address: string) => IUserOperationBuilder;
setNonce: (nonce: BigNumberish) => IUserOperationBuilder;
setInitCode: (code: BytesLike) => IUserOperationBuilder;
setCallData: (data: BytesLike) => IUserOperationBuilder;
setCallGasLimit: (gas: BigNumberish) => IUserOperationBuilder;
setVerificationGasLimit: (gas: BigNumberish) => IUserOperationBuilder;
setPreVerificationGas: (gas: BigNumberish) => IUserOperationBuilder;
setMaxFeePerGas: (fee: BigNumberish) => IUserOperationBuilder;
setMaxPriorityFeePerGas: (fee: BigNumberish) => IUserOperationBuilder;
setPaymasterAndData: (data: BytesLike) => IUserOperationBuilder;
setSignature: (bytes: BytesLike) => IUserOperationBuilder;
setPartial: (partialOp: Partial<IUserOperation>) => IUserOperationBuilder;
// Sets the default values that won't be wiped on reset.
useDefaults: (partialOp: Partial<IUserOperation>) => IUserOperationBuilder;
resetDefaults: () => IUserOperationBuilder;
// Some fields may require arbitrary logic to build an op.
// Middleware functions allow you to set custom logic for building op fragments.
useMiddleware: (fn: UserOperationMiddlewareFn) => IUserOperationBuilder;
resetMiddleware: () => IUserOperationBuilder;
// This will construct a UserOperation that can be sent to a client.
// It will run through your entire middleware stack in the process.
buildOp: (
entryPoint: string,
chainId: BigNumberish
) => Promise<IUserOperation>;
// Will reset all fields back to default value.
resetOp: () => IUserOperationBuilder;
}
interface IUserOperationBuilder {
// get methods.
getSender: () => string;
getNonce: () => BigNumberish;
getInitCode: () => BytesLike;
getCallData: () => BytesLike;
getCallGasLimit: () => BigNumberish;
getVerificationGasLimit: () => BigNumberish;
getPreVerificationGas: () => BigNumberish;
getMaxFeePerGas: () => BigNumberish;
getMaxPriorityFeePerGas: () => BigNumberish;
getPaymasterAndData: () => BytesLike;
getSignature: () => BytesLike;
getOp: () => IUserOperation;
// set methods.
setSender: (address: string) => IUserOperationBuilder;
setNonce: (nonce: BigNumberish) => IUserOperationBuilder;
setInitCode: (code: BytesLike) => IUserOperationBuilder;
setCallData: (data: BytesLike) => IUserOperationBuilder;
setCallGasLimit: (gas: BigNumberish) => IUserOperationBuilder;
setVerificationGasLimit: (gas: BigNumberish) => IUserOperationBuilder;
setPreVerificationGas: (gas: BigNumberish) => IUserOperationBuilder;
setMaxFeePerGas: (fee: BigNumberish) => IUserOperationBuilder;
setMaxPriorityFeePerGas: (fee: BigNumberish) => IUserOperationBuilder;
setPaymasterAndData: (data: BytesLike) => IUserOperationBuilder;
setSignature: (bytes: BytesLike) => IUserOperationBuilder;
setPartial: (partialOp: Partial<IUserOperation>) => IUserOperationBuilder;
// Sets the default values that won't be wiped on reset.
useDefaults: (partialOp: Partial<IUserOperation>) => IUserOperationBuilder;
resetDefaults: () => IUserOperationBuilder;
// Some fields may require arbitrary logic to build an op.
// Middleware functions allow you to set custom logic for building op fragments.
useMiddleware: (fn: UserOperationMiddlewareFn) => IUserOperationBuilder;
resetMiddleware: () => IUserOperationBuilder;
// This will construct a UserOperation that can be sent to a client.
// It will run through your entire middleware stack in the process.
buildOp: (
entryPoint: string,
chainId: BigNumberish
) => Promise<IUserOperation>;
// Will reset all fields back to default value.
resetOp: () => IUserOperationBuilder;
}
get and set Functions
These are basic getters and setters for all fields on a UserOperation. Getters return the field type whereas setters will return the instance to enable chaining.
For example:
tsx
const builder = new UserOperationBuilder()
.setCallData(callData)
.setCallGasLimit(callGas);
const builder = new UserOperationBuilder()
.setCallData(callData)
.setCallGasLimit(callGas);