Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance improvements on userop #129

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ src
.prettierrc.json
eslint.config.js
jest.config.js
tsconfig.json
tsconfig.*.*
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
},
"scripts": {
"clean": "rimraf dist",
"build": "yarn clean && tsc",
"build": "yarn clean && tsc -p ./tsconfig.build.json",
"test": "jest",
"lint": "eslint . && tsc --noEmit",
"lint": "eslint . && tsc --noEmit -p ./tsconfig.build.json",
"lint:fix": "eslint . --fix",
"prettier": "prettier --check '**'",
"prettier:fix": "prettier --write '**'"
Expand All @@ -32,6 +32,7 @@
"typescript-eslint": "^7.3.1"
},
"dependencies": {
"@arktype/attest": "^0.7.0",
"abitype": "^1.0.0",
"ethers": "^6.11.1",
"viem": "^2.9.12"
Expand Down
1 change: 1 addition & 0 deletions src/v06/account/common/factoryAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const FACTORY_ADDRESS = "0x9406Cc6185a346906296840746125a0E44976454";
5 changes: 4 additions & 1 deletion src/v06/account/common/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export * as SimpleAccount from "./simpleAccount";
export * as SimpleAccountWithEthers from "./simpleAccountWithEthers";
export * as SimpleAccountWithoutHoistedViemAccount from "./simpleAccountWithoutViemAccount";
export * as SimpleAccountWithHoistedViemAccount from "./simpleAccountWithViemAccount";
export * as SimpleAccountWithSigner from "./simpleAccountWithSigner";
59 changes: 0 additions & 59 deletions src/v06/account/common/simpleAccount.ts

This file was deleted.

35 changes: 35 additions & 0 deletions src/v06/account/common/simpleAccountWithEthers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Address } from "abitype";
import { JsonRpcProvider, Signer } from "ethers";
import { PublicClient, WalletClient, Transport, Chain, Account } from "viem";
import { RequestSignature } from "../hooks";
import { RequiredAccountOpts } from "../types";
import { AccountAbi, FactoryAbi } from "./abi/simpleAccount";
import { FACTORY_ADDRESS } from "./factoryAddress";

export function baseWithEthers(
ethClient: PublicClient | JsonRpcProvider,
eoa: WalletClient<Transport, Chain | undefined, Account> | Signer,
): RequiredAccountOpts<typeof AccountAbi, typeof FactoryAbi> {
return {
accountAbi: AccountAbi,
factoryAbi: FactoryAbi,
factoryAddress: FACTORY_ADDRESS,
ethClient,
async setFactoryData(salt, encoder) {
if ("getAddresses" in eoa) {
return encoder("createAccount", [(await eoa.getAddresses())[0], salt]);
} else {
return encoder("createAccount", [
(await eoa.getAddress()) as Address,
salt,
]);
}
},
requestSignature:
"getAddresses" in eoa
? RequestSignature.withViemWalletClient(
eoa as WalletClient<Transport, Chain | undefined, Account>,
)
: RequestSignature.withEthersSigner(eoa),
};
}
31 changes: 31 additions & 0 deletions src/v06/account/common/simpleAccountWithSigner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Address } from "abitype";
import { JsonRpcProvider, Signer } from "ethers";
import { PublicClient, Account } from "viem";
import { RequestSignature } from "../hooks";
import { RequiredAccountOpts } from "../types";
import { AccountAbi, FactoryAbi } from "./abi/simpleAccount";
import { FACTORY_ADDRESS } from "./factoryAddress";

export function base(
ethClient: PublicClient | JsonRpcProvider,
eoa: Signer,
account?: Account,
): RequiredAccountOpts<typeof AccountAbi, typeof FactoryAbi> {
return {
accountAbi: AccountAbi,
factoryAbi: FactoryAbi,
factoryAddress: FACTORY_ADDRESS,
ethClient,
async setFactoryData(salt, encoder) {
if (account !== undefined) {
return encoder("createAccount", [account.address, salt]);
} else {
return encoder("createAccount", [
(await eoa.getAddress()) as Address,
salt,
]);
}
},
requestSignature: RequestSignature.withEthersSigner(eoa),
};
}
32 changes: 32 additions & 0 deletions src/v06/account/common/simpleAccountWithViemAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { JsonRpcProvider } from "ethers";
import { PublicClient, WalletClient, Transport, Chain, Account } from "viem";
import { RequestSignature } from "../hooks";
import { RequiredAccountOpts } from "../types";
import { AccountAbi, FactoryAbi } from "./abi/simpleAccount";
import { FACTORY_ADDRESS } from "./factoryAddress";

export function baseWithViemHoistedAccount(
ethClient: PublicClient | JsonRpcProvider,
eoa: WalletClient<Transport, Chain | undefined, Account>,
account: Account,
): RequiredAccountOpts<typeof AccountAbi, typeof FactoryAbi> {
return {
accountAbi: AccountAbi,
factoryAbi: FactoryAbi,
factoryAddress: FACTORY_ADDRESS,
ethClient,
async setFactoryData(salt, encoder) {
if (account !== undefined) {
return encoder("createAccount", [account.address, salt]);
} else {
return encoder("createAccount", [(await eoa.getAddresses())[0], salt]);
}
},
requestSignature:
"getAddresses" in eoa
? RequestSignature.withViemWalletClient(
eoa as WalletClient<Transport, Chain | undefined, Account>,
)
: RequestSignature.withEthersSigner(eoa),
};
}
33 changes: 33 additions & 0 deletions src/v06/account/common/simpleAccountWithoutViemAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { JsonRpcProvider } from "ethers";
import { PublicClient, WalletClient, Transport, Chain, Account } from "viem";
import { RequestSignature } from "../hooks";
import { RequiredAccountOpts } from "../types";
import { AccountAbi, FactoryAbi } from "./abi/simpleAccount";
import { FACTORY_ADDRESS } from "./factoryAddress";

export function baseWithoutHoistedViemAccount(
ethClient: PublicClient | JsonRpcProvider,
eoa: WalletClient<Transport, Chain | undefined, undefined>,
account: Account,
): RequiredAccountOpts<typeof AccountAbi, typeof FactoryAbi> {
return {
accountAbi: AccountAbi,
factoryAbi: FactoryAbi,
factoryAddress: FACTORY_ADDRESS,
ethClient,
async setFactoryData(salt, encoder) {
if (account !== undefined) {
return encoder("createAccount", [account.address, salt]);
} else {
return encoder("createAccount", [(await eoa.getAddresses())[0], salt]);
}
},
requestSignature:
"getAddresses" in eoa
? RequestSignature.withoutViemWalletClient(
eoa as WalletClient<Transport, Chain | undefined, undefined>,
account,
)
: RequestSignature.withEthersSigner(eoa),
};
}
42 changes: 0 additions & 42 deletions src/v06/account/hooks/requestGasPrice/common.ts

This file was deleted.

3 changes: 2 additions & 1 deletion src/v06/account/hooks/requestGasPrice/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./common";
export * from "./jsonProvider";
export * from "./publicClient";
21 changes: 21 additions & 0 deletions src/v06/account/hooks/requestGasPrice/jsonProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { JsonRpcProvider } from "ethers";
import { RequestGasPriceFunc } from "../types";

export const withEthJsonRpcProvider = (
ethClient: JsonRpcProvider,
): RequestGasPriceFunc => {
return async () => {
const feeData = await ethClient.getFeeData();
if (!feeData.maxFeePerGas || !feeData.maxPriorityFeePerGas) {
return {
maxFeePerGas: feeData.gasPrice || 0n,
maxPriorityFeePerGas: feeData.gasPrice || 0n,
};
}

return {
maxFeePerGas: feeData.maxFeePerGas,
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
};
};
};
17 changes: 17 additions & 0 deletions src/v06/account/hooks/requestGasPrice/publicClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PublicClient } from "viem";
import { RequestGasPriceFunc } from "../types";

export const withEthPublicClient = (
ethClient: PublicClient,
): RequestGasPriceFunc => {
return async () => {
const gp = await ethClient.getGasPrice();
const maxPriorityFeePerGas = await ethClient.estimateMaxPriorityFeePerGas();
const maxFeePerGas = gp * 2n + maxPriorityFeePerGas;

return {
maxFeePerGas,
maxPriorityFeePerGas,
};
};
};
3 changes: 2 additions & 1 deletion src/v06/account/hooks/requestSignature/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./ethers";
export * from "./viem";
export * from "./withViemHoistedClient";
export * from "./withouthViemHoistedClient";
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,8 @@ import { WalletClient, Account, Transport, Chain } from "viem";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { RequestSignatureFunc } from "../types";

export function withViemWalletClient(
client: WalletClient<Transport, Chain | undefined, undefined>,
account: Account,
): RequestSignatureFunc;
export function withViemWalletClient(
client: WalletClient<Transport, Chain | undefined, Account>,
): RequestSignatureFunc;
export function withViemWalletClient(
client: WalletClient,
account?: Account,
): RequestSignatureFunc {
const dummy = privateKeyToAccount(generatePrivateKey());
return async (type, message) => {
Expand All @@ -21,9 +13,6 @@ export function withViemWalletClient(
}

case "final": {
if (account) {
return client.signMessage({ account, message: { raw: message } });
}
return (
client as WalletClient<Transport, Chain | undefined, Account>
).signMessage({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { WalletClient, Transport, Chain, Account } from "viem";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { RequestSignatureFunc } from "../types";

export function withoutViemWalletClient(
client: WalletClient<Transport, Chain | undefined, undefined>,
account: Account,
): RequestSignatureFunc {
const dummy = privateKeyToAccount(generatePrivateKey());
return async (type, message) => {
switch (type) {
case "dummy": {
return dummy.signMessage({ message: { raw: message } });
}

case "final": {
return client.signMessage({ account, message: { raw: message } });
}
}
};
}