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

Commit 35d66c0

Browse files
authored
Reduce boilerplate for base SimpleAccount config (#124)
1 parent 9c1335e commit 35d66c0

File tree

5 files changed

+69
-44
lines changed

5 files changed

+69
-44
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "userop",
3-
"version": "0.4.0-beta.1",
3+
"version": "0.4.0-beta.2",
44
"description": "A simple JS library for building ERC-4337 UserOperations.",
55
"types": "./dist/index.d.ts",
66
"main": "./dist/index.js",

src/test/v06/account.constants.ts

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { V06 } from "../..";
1616

1717
const EOA_PK = generatePrivateKey();
1818
const VIEM_ACC = privateKeyToAccount(EOA_PK);
19-
const OWNER_ADDR = VIEM_ACC.address;
2019
const VIEM_WALLET_CLIENT = createWalletClient({
2120
account: VIEM_ACC,
2221
chain: localhost,
@@ -33,58 +32,45 @@ export const ACCOUNTS = [
3332
type: "SimpleAccount, withViemWalletClient (account hoisted)",
3433
instance: new V06.Account.Instance({
3534
...V06.Account.CommonConfigs.SimpleAccount.base(
36-
OWNER_ADDR,
37-
V06.Account.Hooks.RequestSignature.withViemWalletClient(
38-
VIEM_WALLET_CLIENT,
39-
),
4035
VIEM_PUBLIC_CLIENT,
36+
VIEM_WALLET_CLIENT,
4137
),
4238
}),
4339
},
4440
{
4541
type: "SimpleAccount, withViemWalletClient (account not hoisted)",
4642
instance: new V06.Account.Instance({
4743
...V06.Account.CommonConfigs.SimpleAccount.base(
48-
OWNER_ADDR,
49-
V06.Account.Hooks.RequestSignature.withViemWalletClient(
50-
VIEM_WALLET_CLIENT_NO_HOIST,
51-
VIEM_ACC,
52-
),
5344
VIEM_PUBLIC_CLIENT,
45+
VIEM_WALLET_CLIENT_NO_HOIST,
46+
VIEM_ACC,
5447
),
5548
}),
5649
},
5750
{
5851
type: "SimpleAccount, with JsonRpcProvider",
5952
instance: new V06.Account.Instance({
6053
...V06.Account.CommonConfigs.SimpleAccount.base(
61-
OWNER_ADDR,
62-
V06.Account.Hooks.RequestSignature.withViemWalletClient(
63-
VIEM_WALLET_CLIENT,
64-
),
6554
ETHERS_JSON_RPC_PROVIDER,
55+
VIEM_WALLET_CLIENT,
6656
),
6757
}),
6858
},
6959
{
7060
type: "SimpleAccount, withEthersSigner",
7161
instance: new V06.Account.Instance({
7262
...V06.Account.CommonConfigs.SimpleAccount.base(
73-
OWNER_ADDR,
74-
V06.Account.Hooks.RequestSignature.withEthersSigner(ETHERS_WALLET),
7563
VIEM_PUBLIC_CLIENT,
64+
ETHERS_WALLET,
7665
),
7766
}),
7867
},
7968
{
8069
type: "SimpleAccount, with separate viem node and bundler PublicClients",
8170
instance: new V06.Account.Instance({
8271
...V06.Account.CommonConfigs.SimpleAccount.base(
83-
OWNER_ADDR,
84-
V06.Account.Hooks.RequestSignature.withViemWalletClient(
85-
VIEM_WALLET_CLIENT,
86-
),
8772
VIEM_NODE_PUBLIC_CLIENT,
73+
VIEM_WALLET_CLIENT,
8874
),
8975

9076
bundlerClient: VIEM_BUNDLER_PUBLIC_CLIENT,
@@ -94,11 +80,8 @@ export const ACCOUNTS = [
9480
type: "SimpleAccount, with separate ethers node and bundler JsonRpcProviders",
9581
instance: new V06.Account.Instance({
9682
...V06.Account.CommonConfigs.SimpleAccount.base(
97-
OWNER_ADDR,
98-
V06.Account.Hooks.RequestSignature.withViemWalletClient(
99-
VIEM_WALLET_CLIENT,
100-
),
10183
ETHERS_NODE_JSON_RPC_PROVIDER,
84+
VIEM_WALLET_CLIENT,
10285
),
10386

10487
bundlerClient: ETHERS_BUNDLER_JSON_RPC_PROVIDER,
@@ -108,11 +91,8 @@ export const ACCOUNTS = [
10891
type: "SimpleAccount, with Stackup V1 PAYG paymaster",
10992
instance: new V06.Account.Instance({
11093
...V06.Account.CommonConfigs.SimpleAccount.base(
111-
OWNER_ADDR,
112-
V06.Account.Hooks.RequestSignature.withViemWalletClient(
113-
VIEM_WALLET_CLIENT,
114-
),
11594
VIEM_PUBLIC_CLIENT,
95+
VIEM_WALLET_CLIENT,
11696
),
11797

11898
requestPaymaster: V06.Account.Hooks.RequestPaymaster.withCommon({
Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,67 @@
1-
import { Address, PublicClient } from "viem";
2-
import { JsonRpcProvider } from "ethers";
1+
import {
2+
Account,
3+
Address,
4+
Chain,
5+
PublicClient,
6+
Transport,
7+
WalletClient,
8+
} from "viem";
9+
import { JsonRpcProvider, Signer } from "ethers";
310
import { AccountAbi, FactoryAbi } from "./abi/simpleAccount";
411
import { RequiredAccountOpts } from "../types";
5-
import { RequestSignatureFunc } from "../hooks";
12+
import { RequestSignature } from "../hooks";
613

7-
export const base = (
8-
owner: Address,
9-
requestSignature: RequestSignatureFunc,
14+
const FACTORY_ADDRESS = "0x9406Cc6185a346906296840746125a0E44976454";
15+
16+
type SimpleAccountArgsWithViemEOA<E extends WalletClient> = [
17+
ethClient: PublicClient | JsonRpcProvider,
18+
eoa: E,
19+
];
20+
type SimpleAccountArgsWithViemEOANoHoist<E extends WalletClient> = [
21+
ethClient: PublicClient | JsonRpcProvider,
22+
eoa: E,
23+
account: Account,
24+
];
25+
type SimpleAccountArgsWithEthersSigner<E extends Signer> = [
1026
ethClient: PublicClient | JsonRpcProvider,
27+
eoa: E,
28+
];
29+
30+
export const base = <E extends WalletClient | Signer>(
31+
...args: E extends WalletClient
32+
? E["account"] extends Account
33+
? SimpleAccountArgsWithViemEOA<E>
34+
: SimpleAccountArgsWithViemEOANoHoist<E>
35+
: E extends Signer
36+
? SimpleAccountArgsWithEthersSigner<E>
37+
: never
1138
): RequiredAccountOpts<typeof AccountAbi, typeof FactoryAbi> => {
39+
const [ethClient, eoa, account] = args;
40+
1241
return {
1342
accountAbi: AccountAbi,
1443
factoryAbi: FactoryAbi,
15-
factoryAddress: "0x9406Cc6185a346906296840746125a0E44976454",
44+
factoryAddress: FACTORY_ADDRESS,
1645
ethClient,
17-
setFactoryData(salt, encoder) {
18-
return encoder("createAccount", [owner, salt]);
46+
async setFactoryData(salt, encoder) {
47+
if (account !== undefined) {
48+
return encoder("createAccount", [account.address, salt]);
49+
} else if ("getAddresses" in eoa) {
50+
return encoder("createAccount", [(await eoa.getAddresses())[0], salt]);
51+
} else {
52+
return encoder("createAccount", [
53+
(await eoa.getAddress()) as Address,
54+
salt,
55+
]);
56+
}
1957
},
20-
requestSignature,
58+
requestSignature:
59+
"getAddresses" in eoa
60+
? account !== undefined
61+
? RequestSignature.withViemWalletClient(eoa, account)
62+
: RequestSignature.withViemWalletClient(
63+
eoa as WalletClient<Transport, Chain | undefined, Account>,
64+
)
65+
: RequestSignature.withEthersSigner(eoa),
2166
};
2267
};

src/v06/account/hooks/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export type SetFactoryDataFunc<F extends Abi> = (
1313
method: M,
1414
inputs: AbiParametersToPrimitiveTypes<ExtractAbiFunction<F, M>["inputs"]>,
1515
) => Hex,
16-
) => Hex;
16+
) => Promise<Hex>;
1717

1818
export type RequestSignatureFunc = (
1919
type: "dummy" | "final",

src/v06/account/instance.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ export class Instance<A extends Abi, F extends Abi> {
7474
this.onBuild = opts.onBuild;
7575
}
7676

77-
private getInitCode(): Hex {
77+
private async getInitCode(): Promise<Hex> {
7878
if (this.initCode === "0x") {
7979
this.initCode = concat([
8080
this.factoryAddress,
81-
this.setFactoryData(this.salt, (method, inputs) => {
81+
await this.setFactoryData(this.salt, (method, inputs) => {
8282
return encodeFunctionData({
8383
abi: this.factoryAbi as Abi,
8484
functionName: method as string,
@@ -117,7 +117,7 @@ export class Instance<A extends Abi, F extends Abi> {
117117

118118
return {
119119
nonce,
120-
initCode: code === undefined ? this.getInitCode() : "0x",
120+
initCode: code === undefined ? await this.getInitCode() : "0x",
121121
};
122122
}
123123

@@ -211,7 +211,7 @@ export class Instance<A extends Abi, F extends Abi> {
211211
address: this.entryPointAddress,
212212
abi: EntryPoint.CONTRACT_ABI,
213213
functionName: "getSenderAddress",
214-
args: [this.getInitCode()],
214+
args: [await this.getInitCode()],
215215
});
216216
} catch (error) {
217217
if (error instanceof BaseError) {

0 commit comments

Comments
 (0)