permissionless 0.2.47 → 0.2.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/_cjs/accounts/index.js +5 -1
- package/_cjs/accounts/index.js.map +1 -1
- package/_cjs/accounts/kernel/to7702KernelSmartAccount.js +11 -0
- package/_cjs/accounts/kernel/to7702KernelSmartAccount.js.map +1 -0
- package/_cjs/accounts/kernel/toKernelSmartAccount.js +60 -17
- package/_cjs/accounts/kernel/toKernelSmartAccount.js.map +1 -1
- package/_cjs/accounts/simple/to7702SimpleSmartAccount.js +11 -0
- package/_cjs/accounts/simple/to7702SimpleSmartAccount.js.map +1 -0
- package/_cjs/accounts/simple/toSimpleSmartAccount.js +50 -18
- package/_cjs/accounts/simple/toSimpleSmartAccount.js.map +1 -1
- package/_cjs/actions/erc7579/installModule.js +2 -1
- package/_cjs/actions/erc7579/installModule.js.map +1 -1
- package/_cjs/actions/erc7579/installModules.js +2 -1
- package/_cjs/actions/erc7579/installModules.js.map +1 -1
- package/_esm/accounts/index.js +3 -1
- package/_esm/accounts/index.js.map +1 -1
- package/_esm/accounts/kernel/to7702KernelSmartAccount.js +8 -0
- package/_esm/accounts/kernel/to7702KernelSmartAccount.js.map +1 -0
- package/_esm/accounts/kernel/toKernelSmartAccount.js +61 -22
- package/_esm/accounts/kernel/toKernelSmartAccount.js.map +1 -1
- package/_esm/accounts/simple/to7702SimpleSmartAccount.js +8 -0
- package/_esm/accounts/simple/to7702SimpleSmartAccount.js.map +1 -0
- package/_esm/accounts/simple/toSimpleSmartAccount.js +51 -20
- package/_esm/accounts/simple/toSimpleSmartAccount.js.map +1 -1
- package/_esm/actions/erc7579/installModule.js +2 -1
- package/_esm/actions/erc7579/installModule.js.map +1 -1
- package/_esm/actions/erc7579/installModules.js +2 -1
- package/_esm/actions/erc7579/installModules.js.map +1 -1
- package/_types/accounts/index.d.ts +3 -1
- package/_types/accounts/index.d.ts.map +1 -1
- package/_types/accounts/kernel/to7702KernelSmartAccount.d.ts +8 -0
- package/_types/accounts/kernel/to7702KernelSmartAccount.d.ts.map +1 -0
- package/_types/accounts/kernel/toKernelSmartAccount.d.ts +29 -9
- package/_types/accounts/kernel/toKernelSmartAccount.d.ts.map +1 -1
- package/_types/accounts/simple/to7702SimpleSmartAccount.d.ts +8 -0
- package/_types/accounts/simple/to7702SimpleSmartAccount.d.ts.map +1 -0
- package/_types/accounts/simple/toSimpleSmartAccount.d.ts +20 -7
- package/_types/accounts/simple/toSimpleSmartAccount.d.ts.map +1 -1
- package/_types/actions/erc7579/installModule.d.ts +2 -1
- package/_types/actions/erc7579/installModule.d.ts.map +1 -1
- package/_types/actions/erc7579/installModules.d.ts +2 -1
- package/_types/actions/erc7579/installModules.d.ts.map +1 -1
- package/accounts/index.ts +23 -1
- package/accounts/kernel/to7702KernelSmartAccount.ts +63 -0
- package/accounts/kernel/toKernelSmartAccount.ts +154 -63
- package/accounts/simple/to7702SimpleSmartAccount.ts +51 -0
- package/accounts/simple/toSimpleSmartAccount.ts +116 -46
- package/actions/erc7579/installModule.test.ts +44 -4
- package/actions/erc7579/installModule.ts +4 -1
- package/actions/erc7579/installModules.test.ts +41 -2
- package/actions/erc7579/installModules.ts +11 -1
- package/actions/erc7579/uninstallModule.test.ts +25 -3
- package/actions/smartAccount/sendTransaction.test.ts +79 -29
- package/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.test.ts +69 -257
- package/package.json +2 -2
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type JsonRpcAccount,
|
|
9
9
|
type LocalAccount,
|
|
10
10
|
type OneOf,
|
|
11
|
+
type PrivateKeyAccount,
|
|
11
12
|
type Transport,
|
|
12
13
|
type WalletClient,
|
|
13
14
|
decodeFunctionData,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
entryPoint07Abi,
|
|
23
24
|
entryPoint07Address,
|
|
24
25
|
entryPoint08Abi,
|
|
26
|
+
entryPoint08Address,
|
|
25
27
|
getUserOperationHash,
|
|
26
28
|
getUserOperationTypedData,
|
|
27
29
|
toSmartAccount
|
|
@@ -71,27 +73,44 @@ const getAccountInitCode = async (
|
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
export type ToSimpleSmartAccountParameters<
|
|
74
|
-
entryPointVersion extends EntryPointVersion
|
|
76
|
+
entryPointVersion extends EntryPointVersion,
|
|
77
|
+
owner extends OneOf<
|
|
78
|
+
| EthereumProvider
|
|
79
|
+
| WalletClient<Transport, Chain | undefined, Account>
|
|
80
|
+
| LocalAccount
|
|
81
|
+
>,
|
|
82
|
+
eip7702 extends boolean = false
|
|
75
83
|
> = {
|
|
76
84
|
client: Client<
|
|
77
85
|
Transport,
|
|
78
86
|
Chain | undefined,
|
|
79
87
|
JsonRpcAccount | LocalAccount | undefined
|
|
80
88
|
>
|
|
81
|
-
owner:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
89
|
+
owner: owner
|
|
90
|
+
eip7702?: eip7702
|
|
91
|
+
} & (eip7702 extends true
|
|
92
|
+
? {
|
|
93
|
+
entryPoint?: {
|
|
94
|
+
address: Address
|
|
95
|
+
version: "0.8"
|
|
96
|
+
}
|
|
97
|
+
factoryAddress?: never
|
|
98
|
+
index?: never
|
|
99
|
+
address?: never
|
|
100
|
+
nonceKey?: never
|
|
101
|
+
accountLogicAddress?: Address
|
|
102
|
+
}
|
|
103
|
+
: {
|
|
104
|
+
entryPoint?: {
|
|
105
|
+
address: Address
|
|
106
|
+
version: entryPointVersion
|
|
107
|
+
}
|
|
108
|
+
factoryAddress?: Address
|
|
109
|
+
index?: bigint
|
|
110
|
+
address?: Address
|
|
111
|
+
nonceKey?: bigint
|
|
112
|
+
accountLogicAddress?: Address
|
|
113
|
+
})
|
|
95
114
|
|
|
96
115
|
const getFactoryAddress = (
|
|
97
116
|
entryPointVersion: EntryPointVersion,
|
|
@@ -121,18 +140,24 @@ const getEntryPointAbi = (entryPointVersion: EntryPointVersion) => {
|
|
|
121
140
|
}
|
|
122
141
|
|
|
123
142
|
export type SimpleSmartAccountImplementation<
|
|
124
|
-
entryPointVersion extends EntryPointVersion = "0.7"
|
|
143
|
+
entryPointVersion extends EntryPointVersion = "0.7",
|
|
144
|
+
eip7702 extends boolean = false
|
|
125
145
|
> = Assign<
|
|
126
146
|
SmartAccountImplementation<
|
|
127
147
|
ReturnType<typeof getEntryPointAbi>,
|
|
128
|
-
entryPointVersion
|
|
148
|
+
entryPointVersion,
|
|
149
|
+
eip7702 extends true ? object : object,
|
|
150
|
+
eip7702
|
|
129
151
|
>,
|
|
130
152
|
{ sign: NonNullable<SmartAccountImplementation["sign"]> }
|
|
131
153
|
>
|
|
132
154
|
|
|
133
155
|
export type ToSimpleSmartAccountReturnType<
|
|
134
|
-
entryPointVersion extends EntryPointVersion = "0.7"
|
|
135
|
-
|
|
156
|
+
entryPointVersion extends EntryPointVersion = "0.7",
|
|
157
|
+
eip7702 extends boolean = false
|
|
158
|
+
> = eip7702 extends true
|
|
159
|
+
? SmartAccount<SimpleSmartAccountImplementation<entryPointVersion, true>>
|
|
160
|
+
: SmartAccount<SimpleSmartAccountImplementation<entryPointVersion, false>>
|
|
136
161
|
|
|
137
162
|
/**
|
|
138
163
|
* @description Creates an Simple Account from a private key.
|
|
@@ -140,17 +165,29 @@ export type ToSimpleSmartAccountReturnType<
|
|
|
140
165
|
* @returns A Private Key Simple Account.
|
|
141
166
|
*/
|
|
142
167
|
export async function toSimpleSmartAccount<
|
|
143
|
-
entryPointVersion extends EntryPointVersion
|
|
168
|
+
entryPointVersion extends EntryPointVersion,
|
|
169
|
+
owner extends OneOf<
|
|
170
|
+
| EthereumProvider
|
|
171
|
+
| WalletClient<Transport, Chain | undefined, Account>
|
|
172
|
+
| LocalAccount
|
|
173
|
+
>,
|
|
174
|
+
eip7702 extends boolean = false
|
|
144
175
|
>(
|
|
145
|
-
parameters: ToSimpleSmartAccountParameters<
|
|
146
|
-
|
|
176
|
+
parameters: ToSimpleSmartAccountParameters<
|
|
177
|
+
entryPointVersion,
|
|
178
|
+
owner,
|
|
179
|
+
eip7702
|
|
180
|
+
>
|
|
181
|
+
): Promise<ToSimpleSmartAccountReturnType<entryPointVersion, eip7702>> {
|
|
147
182
|
const {
|
|
148
183
|
client,
|
|
149
184
|
owner,
|
|
150
185
|
factoryAddress: _factoryAddress,
|
|
151
186
|
index = BigInt(0),
|
|
152
187
|
address,
|
|
153
|
-
nonceKey
|
|
188
|
+
nonceKey,
|
|
189
|
+
eip7702 = false,
|
|
190
|
+
accountLogicAddress = "0xe6Cae83BdE06E4c305530e199D7217f42808555B"
|
|
154
191
|
} = parameters
|
|
155
192
|
|
|
156
193
|
const localOwner = await toOwner({ owner })
|
|
@@ -161,19 +198,23 @@ export async function toSimpleSmartAccount<
|
|
|
161
198
|
abi: getEntryPointAbi(parameters.entryPoint.version),
|
|
162
199
|
version: parameters.entryPoint.version
|
|
163
200
|
}
|
|
164
|
-
:
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
201
|
+
: eip7702
|
|
202
|
+
? ({
|
|
203
|
+
address: entryPoint08Address,
|
|
204
|
+
abi: getEntryPointAbi("0.8"),
|
|
205
|
+
version: "0.8"
|
|
206
|
+
} as const)
|
|
207
|
+
: ({
|
|
208
|
+
address: entryPoint07Address,
|
|
209
|
+
abi: getEntryPointAbi("0.7"),
|
|
210
|
+
version: "0.7"
|
|
211
|
+
} as const)
|
|
169
212
|
|
|
170
213
|
const factoryAddress = getFactoryAddress(
|
|
171
214
|
entryPoint.version,
|
|
172
215
|
_factoryAddress
|
|
173
216
|
)
|
|
174
217
|
|
|
175
|
-
let accountAddress: Address | undefined = address
|
|
176
|
-
|
|
177
218
|
let chainId: number
|
|
178
219
|
|
|
179
220
|
const getMemoizedChainId = async () => {
|
|
@@ -184,29 +225,59 @@ export async function toSimpleSmartAccount<
|
|
|
184
225
|
return chainId
|
|
185
226
|
}
|
|
186
227
|
|
|
187
|
-
const
|
|
228
|
+
const getFactoryArgsFunc = () => async () => {
|
|
188
229
|
return {
|
|
189
230
|
factory: factoryAddress,
|
|
190
231
|
factoryData: await getAccountInitCode(localOwner.address, index)
|
|
191
232
|
}
|
|
192
233
|
}
|
|
193
234
|
|
|
235
|
+
const { accountAddress, getFactoryArgs } = await (async () => {
|
|
236
|
+
if (eip7702) {
|
|
237
|
+
return {
|
|
238
|
+
accountAddress: localOwner.address,
|
|
239
|
+
getFactoryArgs: async () => {
|
|
240
|
+
return {
|
|
241
|
+
factory: undefined,
|
|
242
|
+
factoryData: undefined
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const getFactoryArgs = getFactoryArgsFunc()
|
|
249
|
+
|
|
250
|
+
if (address) {
|
|
251
|
+
return { accountAddress: address, getFactoryArgs }
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const { factory, factoryData } = await getFactoryArgs()
|
|
255
|
+
|
|
256
|
+
const accountAddress = await getSenderAddress(client, {
|
|
257
|
+
factory,
|
|
258
|
+
factoryData,
|
|
259
|
+
entryPointAddress: entryPoint.address
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
return { accountAddress, getFactoryArgs }
|
|
263
|
+
})()
|
|
264
|
+
|
|
194
265
|
return toSmartAccount({
|
|
195
266
|
client,
|
|
196
267
|
entryPoint,
|
|
197
268
|
getFactoryArgs,
|
|
269
|
+
extend: eip7702
|
|
270
|
+
? {
|
|
271
|
+
implementation: accountLogicAddress
|
|
272
|
+
}
|
|
273
|
+
: undefined,
|
|
274
|
+
authorization: eip7702
|
|
275
|
+
? {
|
|
276
|
+
address: accountLogicAddress as Address,
|
|
277
|
+
account: localOwner as PrivateKeyAccount
|
|
278
|
+
}
|
|
279
|
+
: undefined,
|
|
198
280
|
async getAddress() {
|
|
199
|
-
if (accountAddress) return accountAddress
|
|
200
|
-
|
|
201
|
-
const { factory, factoryData } = await getFactoryArgs()
|
|
202
|
-
|
|
203
|
-
// Get the sender address based on the init code
|
|
204
|
-
accountAddress = await getSenderAddress(client, {
|
|
205
|
-
factory,
|
|
206
|
-
factoryData,
|
|
207
|
-
entryPointAddress: entryPoint.address
|
|
208
|
-
})
|
|
209
|
-
|
|
210
281
|
return accountAddress
|
|
211
282
|
},
|
|
212
283
|
async encodeCalls(calls) {
|
|
@@ -372,12 +443,11 @@ export async function toSimpleSmartAccount<
|
|
|
372
443
|
entryPointAddress: entryPoint.address,
|
|
373
444
|
userOperation: {
|
|
374
445
|
...userOperation,
|
|
375
|
-
sender:
|
|
376
|
-
userOperation.sender ?? (await this.getAddress()),
|
|
446
|
+
sender: await this.getAddress(),
|
|
377
447
|
signature: "0x"
|
|
378
448
|
}
|
|
379
449
|
})
|
|
380
|
-
return
|
|
450
|
+
return localOwner.signTypedData(typedData)
|
|
381
451
|
}
|
|
382
452
|
|
|
383
453
|
return signMessage(client, {
|
|
@@ -398,7 +468,7 @@ export async function toSimpleSmartAccount<
|
|
|
398
468
|
}
|
|
399
469
|
})
|
|
400
470
|
}
|
|
401
|
-
}) as Promise<ToSimpleSmartAccountReturnType<entryPointVersion>>
|
|
471
|
+
}) as Promise<ToSimpleSmartAccountReturnType<entryPointVersion, eip7702>>
|
|
402
472
|
}
|
|
403
473
|
|
|
404
474
|
const executeSingleAbi = [
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { encodeAbiParameters, encodePacked, isHash, zeroAddress } from "viem"
|
|
2
|
+
import { privateKeyToAccount } from "viem/accounts"
|
|
2
3
|
import { describe, expect } from "vitest"
|
|
3
4
|
import { testWithRpc } from "../../../permissionless-test/src/testWithRpc"
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getCoreSmartAccounts,
|
|
7
|
+
getPublicClient
|
|
8
|
+
} from "../../../permissionless-test/src/utils"
|
|
5
9
|
import { erc7579Actions } from "../erc7579"
|
|
6
10
|
import { installModule } from "./installModule"
|
|
7
11
|
|
|
8
12
|
describe.each(getCoreSmartAccounts())(
|
|
9
13
|
"installModule $name",
|
|
10
|
-
({ getErc7579SmartAccountClient, name }) => {
|
|
14
|
+
({ getErc7579SmartAccountClient, name, isEip7702Compliant }) => {
|
|
11
15
|
testWithRpc.skipIf(!getErc7579SmartAccountClient)(
|
|
12
16
|
"installModule",
|
|
13
17
|
async ({ rpc }) => {
|
|
@@ -15,14 +19,22 @@ describe.each(getCoreSmartAccounts())(
|
|
|
15
19
|
throw new Error("getErc7579SmartAccountClient not defined")
|
|
16
20
|
}
|
|
17
21
|
|
|
22
|
+
const privateKey =
|
|
23
|
+
"0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356"
|
|
24
|
+
|
|
25
|
+
const privateKeyAccount = privateKeyToAccount(privateKey)
|
|
26
|
+
|
|
18
27
|
const smartClientWithoutExtend =
|
|
19
28
|
await getErc7579SmartAccountClient({
|
|
20
29
|
entryPoint: {
|
|
21
30
|
version: "0.7"
|
|
22
31
|
},
|
|
32
|
+
privateKey,
|
|
23
33
|
...rpc
|
|
24
34
|
})
|
|
25
35
|
|
|
36
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
37
|
+
|
|
26
38
|
const smartClient = smartClientWithoutExtend.extend(
|
|
27
39
|
erc7579Actions()
|
|
28
40
|
)
|
|
@@ -47,7 +59,17 @@ describe.each(getCoreSmartAccounts())(
|
|
|
47
59
|
)
|
|
48
60
|
]
|
|
49
61
|
)
|
|
50
|
-
: moduleData
|
|
62
|
+
: moduleData,
|
|
63
|
+
authorization: isEip7702Compliant
|
|
64
|
+
? await privateKeyAccount.signAuthorization({
|
|
65
|
+
address: (smartClient.account as any)
|
|
66
|
+
.implementation,
|
|
67
|
+
chainId: smartClient.chain.id,
|
|
68
|
+
nonce: await publicClient.getTransactionCount({
|
|
69
|
+
address: smartClient.account.address
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
: undefined
|
|
51
73
|
})
|
|
52
74
|
|
|
53
75
|
expect(isHash(opHash)).toBe(true)
|
|
@@ -88,14 +110,22 @@ describe.each(getCoreSmartAccounts())(
|
|
|
88
110
|
throw new Error("getErc7579SmartAccountClient not defined")
|
|
89
111
|
}
|
|
90
112
|
|
|
113
|
+
const privateKey =
|
|
114
|
+
"0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356"
|
|
115
|
+
|
|
116
|
+
const privateKeyAccount = privateKeyToAccount(privateKey)
|
|
117
|
+
|
|
91
118
|
const smartClientWithoutExtend =
|
|
92
119
|
await getErc7579SmartAccountClient({
|
|
93
120
|
entryPoint: {
|
|
94
121
|
version: "0.7"
|
|
95
122
|
},
|
|
123
|
+
privateKey,
|
|
96
124
|
...rpc
|
|
97
125
|
})
|
|
98
126
|
|
|
127
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
128
|
+
|
|
99
129
|
const smartClient = smartClientWithoutExtend.extend(
|
|
100
130
|
erc7579Actions()
|
|
101
131
|
)
|
|
@@ -112,7 +142,17 @@ describe.each(getCoreSmartAccounts())(
|
|
|
112
142
|
value: 0n,
|
|
113
143
|
data: "0x"
|
|
114
144
|
}
|
|
115
|
-
]
|
|
145
|
+
],
|
|
146
|
+
authorization: isEip7702Compliant
|
|
147
|
+
? await privateKeyAccount.signAuthorization({
|
|
148
|
+
address: (smartClient.account as any)
|
|
149
|
+
.implementation,
|
|
150
|
+
chainId: smartClient.chain.id,
|
|
151
|
+
nonce: await publicClient.getTransactionCount({
|
|
152
|
+
address: smartClient.account.address
|
|
153
|
+
})
|
|
154
|
+
})
|
|
155
|
+
: undefined
|
|
116
156
|
})
|
|
117
157
|
|
|
118
158
|
await smartClient.waitForUserOperationReceipt({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Address, Client, Hex, OneOf } from "viem"
|
|
1
|
+
import type { Address, Client, Hex, OneOf, SignedAuthorization } from "viem"
|
|
2
2
|
import {
|
|
3
3
|
type GetSmartAccountParameter,
|
|
4
4
|
type PaymasterActions,
|
|
@@ -13,6 +13,7 @@ import type { ModuleType } from "./supportsModule.js"
|
|
|
13
13
|
export type InstallModuleParameters<
|
|
14
14
|
TSmartAccount extends SmartAccount | undefined
|
|
15
15
|
> = GetSmartAccountParameter<TSmartAccount> & {
|
|
16
|
+
authorization?: SignedAuthorization<number> | undefined
|
|
16
17
|
type: ModuleType
|
|
17
18
|
address: Address
|
|
18
19
|
maxFeePerGas?: bigint
|
|
@@ -63,6 +64,7 @@ export function installModule<TSmartAccount extends SmartAccount | undefined>(
|
|
|
63
64
|
type,
|
|
64
65
|
calls,
|
|
65
66
|
paymaster,
|
|
67
|
+
authorization,
|
|
66
68
|
paymasterContext
|
|
67
69
|
} = parameters
|
|
68
70
|
|
|
@@ -91,6 +93,7 @@ export function installModule<TSmartAccount extends SmartAccount | undefined>(
|
|
|
91
93
|
maxFeePerGas,
|
|
92
94
|
maxPriorityFeePerGas,
|
|
93
95
|
nonce,
|
|
96
|
+
authorization,
|
|
94
97
|
account
|
|
95
98
|
})
|
|
96
99
|
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { encodeAbiParameters, encodePacked, isHash, zeroAddress } from "viem"
|
|
2
|
+
import { privateKeyToAccount } from "viem/accounts"
|
|
2
3
|
import { describe, expect } from "vitest"
|
|
3
4
|
import { testWithRpc } from "../../../permissionless-test/src/testWithRpc"
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getCoreSmartAccounts,
|
|
7
|
+
getPublicClient
|
|
8
|
+
} from "../../../permissionless-test/src/utils"
|
|
5
9
|
import { erc7579Actions } from "../erc7579"
|
|
6
10
|
import { installModules } from "./installModules"
|
|
7
11
|
|
|
8
12
|
describe.each(getCoreSmartAccounts())(
|
|
9
13
|
"installModules $name",
|
|
10
|
-
({ getErc7579SmartAccountClient, name }) => {
|
|
14
|
+
({ getErc7579SmartAccountClient, name, isEip7702Compliant }) => {
|
|
11
15
|
testWithRpc.skipIf(!getErc7579SmartAccountClient)(
|
|
12
16
|
"installModules",
|
|
13
17
|
async ({ rpc }) => {
|
|
@@ -15,14 +19,22 @@ describe.each(getCoreSmartAccounts())(
|
|
|
15
19
|
throw new Error("getErc7579SmartAccountClient not defined")
|
|
16
20
|
}
|
|
17
21
|
|
|
22
|
+
const privateKey =
|
|
23
|
+
"0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356"
|
|
24
|
+
|
|
25
|
+
const privateKeyAccount = privateKeyToAccount(privateKey)
|
|
26
|
+
|
|
18
27
|
const smartClientWithoutExtend =
|
|
19
28
|
await getErc7579SmartAccountClient({
|
|
20
29
|
entryPoint: {
|
|
21
30
|
version: "0.7"
|
|
22
31
|
},
|
|
32
|
+
privateKey,
|
|
23
33
|
...rpc
|
|
24
34
|
})
|
|
25
35
|
|
|
36
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
37
|
+
|
|
26
38
|
const smartClient = smartClientWithoutExtend.extend(
|
|
27
39
|
erc7579Actions()
|
|
28
40
|
)
|
|
@@ -41,6 +53,16 @@ describe.each(getCoreSmartAccounts())(
|
|
|
41
53
|
data: "0x"
|
|
42
54
|
}
|
|
43
55
|
],
|
|
56
|
+
authorization: isEip7702Compliant
|
|
57
|
+
? await privateKeyAccount.signAuthorization({
|
|
58
|
+
address: (smartClient.account as any)
|
|
59
|
+
.implementation,
|
|
60
|
+
chainId: smartClient.chain.id,
|
|
61
|
+
nonce: await publicClient.getTransactionCount({
|
|
62
|
+
address: smartClient.account.address
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
: undefined,
|
|
44
66
|
modules: [
|
|
45
67
|
{
|
|
46
68
|
type: "executor",
|
|
@@ -102,19 +124,36 @@ describe.each(getCoreSmartAccounts())(
|
|
|
102
124
|
throw new Error("getErc7579SmartAccountClient not defined")
|
|
103
125
|
}
|
|
104
126
|
|
|
127
|
+
const privateKey =
|
|
128
|
+
"0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356"
|
|
129
|
+
|
|
130
|
+
const privateKeyAccount = privateKeyToAccount(privateKey)
|
|
131
|
+
|
|
105
132
|
const smartClientWithoutExtend =
|
|
106
133
|
await getErc7579SmartAccountClient({
|
|
107
134
|
entryPoint: {
|
|
108
135
|
version: "0.7"
|
|
109
136
|
},
|
|
137
|
+
privateKey,
|
|
110
138
|
...rpc
|
|
111
139
|
})
|
|
140
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
112
141
|
|
|
113
142
|
const smartClient = smartClientWithoutExtend.extend(
|
|
114
143
|
erc7579Actions()
|
|
115
144
|
)
|
|
116
145
|
|
|
117
146
|
const userOpHash = await smartClient.sendUserOperation({
|
|
147
|
+
authorization: isEip7702Compliant
|
|
148
|
+
? await privateKeyAccount.signAuthorization({
|
|
149
|
+
address: (smartClient.account as any)
|
|
150
|
+
.implementation,
|
|
151
|
+
chainId: smartClient.chain.id,
|
|
152
|
+
nonce: await publicClient.getTransactionCount({
|
|
153
|
+
address: smartClient.account.address
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
: undefined,
|
|
118
157
|
calls: [
|
|
119
158
|
{
|
|
120
159
|
to: smartClient.account.address,
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Address,
|
|
3
|
+
Chain,
|
|
4
|
+
Client,
|
|
5
|
+
Hex,
|
|
6
|
+
SignedAuthorization,
|
|
7
|
+
Transport
|
|
8
|
+
} from "viem"
|
|
2
9
|
import {
|
|
3
10
|
type PaymasterActions,
|
|
4
11
|
type SmartAccount,
|
|
@@ -14,6 +21,7 @@ import {
|
|
|
14
21
|
export type InstallModulesParameters<
|
|
15
22
|
TSmartAccount extends SmartAccount | undefined
|
|
16
23
|
> = EncodeInstallModuleParameters<TSmartAccount> & {
|
|
24
|
+
authorization?: SignedAuthorization<number> | undefined
|
|
17
25
|
maxFeePerGas?: bigint
|
|
18
26
|
maxPriorityFeePerGas?: bigint
|
|
19
27
|
nonce?: bigint
|
|
@@ -54,6 +62,7 @@ export async function installModules<
|
|
|
54
62
|
modules,
|
|
55
63
|
paymaster,
|
|
56
64
|
paymasterContext,
|
|
65
|
+
authorization,
|
|
57
66
|
calls
|
|
58
67
|
} = parameters
|
|
59
68
|
|
|
@@ -80,6 +89,7 @@ export async function installModules<
|
|
|
80
89
|
paymasterContext,
|
|
81
90
|
maxFeePerGas,
|
|
82
91
|
maxPriorityFeePerGas,
|
|
92
|
+
authorization,
|
|
83
93
|
nonce,
|
|
84
94
|
account: account
|
|
85
95
|
})
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { encodeAbiParameters, encodePacked, isHash, zeroAddress } from "viem"
|
|
2
|
+
import { privateKeyToAccount } from "viem/accounts"
|
|
2
3
|
import { describe, expect } from "vitest"
|
|
3
4
|
import { testWithRpc } from "../../../permissionless-test/src/testWithRpc"
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getCoreSmartAccounts,
|
|
7
|
+
getPublicClient
|
|
8
|
+
} from "../../../permissionless-test/src/utils"
|
|
5
9
|
import { erc7579Actions } from "../erc7579"
|
|
6
10
|
import { uninstallModule } from "./uninstallModule"
|
|
7
11
|
|
|
8
12
|
describe.each(getCoreSmartAccounts())(
|
|
9
13
|
"uninstallModule $name",
|
|
10
|
-
({ getErc7579SmartAccountClient, name }) => {
|
|
14
|
+
({ getErc7579SmartAccountClient, name, isEip7702Compliant }) => {
|
|
11
15
|
testWithRpc.skipIf(!getErc7579SmartAccountClient)(
|
|
12
16
|
"uninstallModule",
|
|
13
17
|
async ({ rpc }) => {
|
|
@@ -15,14 +19,22 @@ describe.each(getCoreSmartAccounts())(
|
|
|
15
19
|
throw new Error("getErc7579SmartAccountClient not defined")
|
|
16
20
|
}
|
|
17
21
|
|
|
22
|
+
const privateKey =
|
|
23
|
+
"0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356"
|
|
24
|
+
|
|
25
|
+
const privateKeyAccount = privateKeyToAccount(privateKey)
|
|
26
|
+
|
|
18
27
|
const smartClientWithoutExtend =
|
|
19
28
|
await getErc7579SmartAccountClient({
|
|
20
29
|
entryPoint: {
|
|
21
30
|
version: "0.7"
|
|
22
31
|
},
|
|
32
|
+
privateKey,
|
|
23
33
|
...rpc
|
|
24
34
|
})
|
|
25
35
|
|
|
36
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
37
|
+
|
|
26
38
|
const smartClient = smartClientWithoutExtend.extend(
|
|
27
39
|
erc7579Actions()
|
|
28
40
|
)
|
|
@@ -46,7 +58,17 @@ describe.each(getCoreSmartAccounts())(
|
|
|
46
58
|
)
|
|
47
59
|
]
|
|
48
60
|
)
|
|
49
|
-
: moduleData
|
|
61
|
+
: moduleData,
|
|
62
|
+
authorization: isEip7702Compliant
|
|
63
|
+
? await privateKeyAccount.signAuthorization({
|
|
64
|
+
address: (smartClient.account as any)
|
|
65
|
+
.implementation,
|
|
66
|
+
chainId: smartClient.chain.id,
|
|
67
|
+
nonce: await publicClient.getTransactionCount({
|
|
68
|
+
address: smartClient.account.address
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
: undefined
|
|
50
72
|
})
|
|
51
73
|
|
|
52
74
|
await smartClient.waitForUserOperationReceipt({
|