Skip to content
This repository was archived by the owner on Oct 20, 2024. It is now read-only.

Commit 928ad8e

Browse files
authored
Add state override set to context (#116)
1 parent 7f55733 commit 928ad8e

File tree

5 files changed

+56
-81
lines changed

5 files changed

+56
-81
lines changed

src/builder.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { OpToJSON } from "./utils";
33
import { UserOperationMiddlewareCtx } from "./context";
44
import {
55
IUserOperation,
6-
IUserOperationBuilder,
6+
StateOverrideSet,
77
UserOperationMiddlewareFn,
88
} from "./types";
99

@@ -25,7 +25,7 @@ export const DEFAULT_USER_OP: IUserOperation = {
2525
signature: ethers.utils.hexlify("0x"),
2626
};
2727

28-
export class UserOperationBuilder implements IUserOperationBuilder {
28+
export class UserOperationBuilder {
2929
private defaultOp: IUserOperation;
3030
private currOp: IUserOperation;
3131
private middlewareStack: Array<UserOperationMiddlewareFn>;
@@ -197,11 +197,16 @@ export class UserOperationBuilder implements IUserOperationBuilder {
197197
return this;
198198
}
199199

200-
async buildOp(entryPoint: string, chainId: BigNumberish) {
200+
async buildOp(
201+
entryPoint: string,
202+
chainId: BigNumberish,
203+
stateOverrides?: StateOverrideSet
204+
) {
201205
const ctx = new UserOperationMiddlewareCtx(
202206
this.currOp,
203207
entryPoint,
204-
chainId
208+
chainId,
209+
stateOverrides
205210
);
206211

207212
for (const fn of this.middlewareStack) {

src/client.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
import { BigNumberish, ethers } from "ethers";
2-
import {
3-
IClient,
4-
IUserOperationBuilder,
5-
ISendUserOperationOpts,
6-
IClientOpts,
7-
} from "./types";
2+
import { UserOperationBuilder } from "./builder";
3+
import { ISendUserOperationOpts, IClientOpts, StateOverrideSet } from "./types";
84
import { EntryPoint, EntryPoint__factory } from "./typechain";
95
import { OpToJSON } from "./utils";
106
import { UserOperationMiddlewareCtx } from "./context";
117
import { ERC4337 } from "./constants";
128
import { BundlerJsonRpcProvider } from "./provider";
139

14-
export class Client implements IClient {
10+
export class Client {
1511
private provider: ethers.providers.JsonRpcProvider;
1612

1713
public entryPoint: EntryPoint;
@@ -41,16 +37,23 @@ export class Client implements IClient {
4137
return instance;
4238
}
4339

44-
async buildUserOperation(builder: IUserOperationBuilder) {
45-
return builder.buildOp(this.entryPoint.address, this.chainId);
40+
async buildUserOperation(
41+
builder: UserOperationBuilder,
42+
stateOverrides?: StateOverrideSet
43+
) {
44+
return builder.buildOp(
45+
this.entryPoint.address,
46+
this.chainId,
47+
stateOverrides
48+
);
4649
}
4750

4851
async sendUserOperation(
49-
builder: IUserOperationBuilder,
52+
builder: UserOperationBuilder,
5053
opts?: ISendUserOperationOpts
5154
) {
5255
const dryRun = Boolean(opts?.dryRun);
53-
const op = await this.buildUserOperation(builder);
56+
const op = await this.buildUserOperation(builder, opts?.stateOverrides);
5457
opts?.onBuild?.(op);
5558

5659
const userOpHash = dryRun

src/context.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
import { BigNumberish, ethers } from "ethers";
2-
import { IUserOperationMiddlewareCtx, IUserOperation } from "./types";
2+
import {
3+
IUserOperationMiddlewareCtx,
4+
IUserOperation,
5+
StateOverrideSet,
6+
} from "./types";
37

48
export class UserOperationMiddlewareCtx implements IUserOperationMiddlewareCtx {
59
public op: IUserOperation;
610
readonly entryPoint: string;
711
readonly chainId: BigNumberish;
12+
readonly stateOverrides?: StateOverrideSet | undefined;
813

9-
constructor(op: IUserOperation, entryPoint: string, chainId: BigNumberish) {
14+
constructor(
15+
op: IUserOperation,
16+
entryPoint: string,
17+
chainId: BigNumberish,
18+
stateOverrides?: StateOverrideSet
19+
) {
1020
this.op = { ...op };
1121
this.entryPoint = ethers.utils.getAddress(entryPoint);
1222
this.chainId = ethers.BigNumber.from(chainId);
23+
this.stateOverrides = stateOverrides;
1324
}
1425

1526
getUserOpHash() {

src/preset/middleware/gasLimit.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ interface GasEstimate {
1414
export const estimateUserOperationGas =
1515
(provider: ethers.providers.JsonRpcProvider): UserOperationMiddlewareFn =>
1616
async (ctx) => {
17-
const est = (await provider.send("eth_estimateUserOperationGas", [
18-
OpToJSON(ctx.op),
19-
ctx.entryPoint,
20-
])) as GasEstimate;
17+
const params =
18+
ctx.stateOverrides !== undefined
19+
? [OpToJSON(ctx.op), ctx.entryPoint, ctx.stateOverrides]
20+
: [OpToJSON(ctx.op), ctx.entryPoint];
21+
const est = (await provider.send(
22+
"eth_estimateUserOperationGas",
23+
params
24+
)) as GasEstimate;
2125

2226
ctx.op.preVerificationGas = est.preVerificationGas;
2327
ctx.op.verificationGasLimit =

src/types.ts

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import { BigNumberish, BytesLike, ethers } from "ethers";
22
import { UserOperationEventEvent } from "./typechain/EntryPoint";
33

4+
export interface ISateOverrideAccount {
5+
nonce: BigNumberish;
6+
code: BytesLike;
7+
balance: BigNumberish;
8+
state: Record<string, BytesLike>;
9+
stateDiff: Record<string, BytesLike>;
10+
}
11+
12+
export type StateOverrideSet = Record<string, Partial<ISateOverrideAccount>>;
13+
414
export interface IUserOperation {
515
sender: string;
616
nonce: BigNumberish;
@@ -15,55 +25,6 @@ export interface IUserOperation {
1525
signature: BytesLike;
1626
}
1727

18-
export interface IUserOperationBuilder {
19-
// get methods.
20-
getSender: () => string;
21-
getNonce: () => BigNumberish;
22-
getInitCode: () => BytesLike;
23-
getCallData: () => BytesLike;
24-
getCallGasLimit: () => BigNumberish;
25-
getVerificationGasLimit: () => BigNumberish;
26-
getPreVerificationGas: () => BigNumberish;
27-
getMaxFeePerGas: () => BigNumberish;
28-
getMaxPriorityFeePerGas: () => BigNumberish;
29-
getPaymasterAndData: () => BytesLike;
30-
getSignature: () => BytesLike;
31-
getOp: () => IUserOperation;
32-
33-
// set methods.
34-
setSender: (address: string) => IUserOperationBuilder;
35-
setNonce: (nonce: BigNumberish) => IUserOperationBuilder;
36-
setInitCode: (code: BytesLike) => IUserOperationBuilder;
37-
setCallData: (data: BytesLike) => IUserOperationBuilder;
38-
setCallGasLimit: (gas: BigNumberish) => IUserOperationBuilder;
39-
setVerificationGasLimit: (gas: BigNumberish) => IUserOperationBuilder;
40-
setPreVerificationGas: (gas: BigNumberish) => IUserOperationBuilder;
41-
setMaxFeePerGas: (fee: BigNumberish) => IUserOperationBuilder;
42-
setMaxPriorityFeePerGas: (fee: BigNumberish) => IUserOperationBuilder;
43-
setPaymasterAndData: (data: BytesLike) => IUserOperationBuilder;
44-
setSignature: (bytes: BytesLike) => IUserOperationBuilder;
45-
setPartial: (partialOp: Partial<IUserOperation>) => IUserOperationBuilder;
46-
47-
// Sets the default values that won't be wiped on reset.
48-
useDefaults: (partialOp: Partial<IUserOperation>) => IUserOperationBuilder;
49-
resetDefaults: () => IUserOperationBuilder;
50-
51-
// Some fields may require arbitrary logic to build an op.
52-
// Middleware functions allow you to set custom logic for building op fragments.
53-
useMiddleware: (fn: UserOperationMiddlewareFn) => IUserOperationBuilder;
54-
resetMiddleware: () => IUserOperationBuilder;
55-
56-
// This will construct a UserOperation that can be sent to a client.
57-
// It will run through your entire middleware stack in the process.
58-
buildOp: (
59-
entryPoint: string,
60-
chainId: BigNumberish
61-
) => Promise<IUserOperation>;
62-
63-
// Will reset all fields back to default value.
64-
resetOp: () => IUserOperationBuilder;
65-
}
66-
6728
export type UserOperationMiddlewareFn = (
6829
context: IUserOperationMiddlewareCtx
6930
) => Promise<void>;
@@ -72,22 +33,12 @@ export interface IUserOperationMiddlewareCtx {
7233
op: IUserOperation;
7334
entryPoint: string;
7435
chainId: BigNumberish;
36+
stateOverrides?: StateOverrideSet;
7537

7638
// A userOpHash is a unique hash of op + entryPoint + chainId.
7739
getUserOpHash: () => string;
7840
}
7941

80-
export interface IClient {
81-
sendUserOperation: (
82-
builder: IUserOperationBuilder,
83-
opts?: ISendUserOperationOpts
84-
) => Promise<ISendUserOperationResponse>;
85-
86-
buildUserOperation: (
87-
builder: IUserOperationBuilder
88-
) => Promise<IUserOperation>;
89-
}
90-
9142
export interface IClientOpts {
9243
entryPoint?: string;
9344
overrideBundlerRpc?: string;
@@ -96,6 +47,7 @@ export interface IClientOpts {
9647
export interface ISendUserOperationOpts {
9748
dryRun?: boolean;
9849
onBuild?: (op: IUserOperation) => Promise<any> | any;
50+
stateOverrides?: StateOverrideSet;
9951
}
10052

10153
export interface ISendUserOperationResponse {

0 commit comments

Comments
 (0)