permissionless 0.2.20 → 0.2.22
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 +13 -0
- package/_cjs/accounts/index.js +3 -1
- package/_cjs/accounts/index.js.map +1 -1
- package/_cjs/accounts/kernel/toEcdsaKernelSmartAccount.js +4 -287
- package/_cjs/accounts/kernel/toEcdsaKernelSmartAccount.js.map +1 -1
- package/_cjs/accounts/kernel/toKernelSmartAccount.js +363 -0
- package/_cjs/accounts/kernel/toKernelSmartAccount.js.map +1 -0
- package/_cjs/accounts/kernel/utils/isWebAuthnAccount.js +8 -0
- package/_cjs/accounts/kernel/utils/isWebAuthnAccount.js.map +1 -0
- package/_cjs/accounts/kernel/utils/signMessage.js +41 -0
- package/_cjs/accounts/kernel/utils/signMessage.js.map +1 -1
- package/_cjs/accounts/kernel/utils/signTypedData.js +13 -1
- package/_cjs/accounts/kernel/utils/signTypedData.js.map +1 -1
- package/_cjs/actions/erc7579/installModule.js.map +1 -1
- package/_cjs/actions/erc7579/installModules.js.map +1 -1
- package/_cjs/actions/erc7579/uninstallModule.js.map +1 -1
- package/_cjs/actions/erc7579/uninstallModules.js.map +1 -1
- package/_cjs/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.js +12 -0
- package/_cjs/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.js.map +1 -1
- package/_cjs/utils/encodeInstallModule.js.map +1 -1
- package/_cjs/vitest.config.js +3 -1
- package/_cjs/vitest.config.js.map +1 -1
- package/_esm/accounts/index.js +2 -1
- package/_esm/accounts/index.js.map +1 -1
- package/_esm/accounts/kernel/toEcdsaKernelSmartAccount.js +6 -333
- package/_esm/accounts/kernel/toEcdsaKernelSmartAccount.js.map +1 -1
- package/_esm/accounts/kernel/toKernelSmartAccount.js +408 -0
- package/_esm/accounts/kernel/toKernelSmartAccount.js.map +1 -0
- package/_esm/accounts/kernel/utils/isWebAuthnAccount.js +4 -0
- package/_esm/accounts/kernel/utils/isWebAuthnAccount.js.map +1 -0
- package/_esm/accounts/kernel/utils/signMessage.js +49 -1
- package/_esm/accounts/kernel/utils/signMessage.js.map +1 -1
- package/_esm/accounts/kernel/utils/signTypedData.js +13 -1
- package/_esm/accounts/kernel/utils/signTypedData.js.map +1 -1
- package/_esm/actions/erc7579/installModule.js.map +1 -1
- package/_esm/actions/erc7579/installModules.js.map +1 -1
- package/_esm/actions/erc7579/uninstallModule.js.map +1 -1
- package/_esm/actions/erc7579/uninstallModules.js.map +1 -1
- package/_esm/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.js +12 -0
- package/_esm/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.js.map +1 -1
- package/_esm/utils/encodeInstallModule.js.map +1 -1
- package/_esm/vitest.config.js +3 -1
- package/_esm/vitest.config.js.map +1 -1
- package/_types/accounts/index.d.ts +3 -2
- package/_types/accounts/index.d.ts.map +1 -1
- package/_types/accounts/kernel/toEcdsaKernelSmartAccount.d.ts +9 -46
- package/_types/accounts/kernel/toEcdsaKernelSmartAccount.d.ts.map +1 -1
- package/_types/accounts/kernel/toKernelSmartAccount.d.ts +50 -0
- package/_types/accounts/kernel/toKernelSmartAccount.d.ts.map +1 -0
- package/_types/accounts/kernel/utils/encodeCallData.d.ts +1 -1
- package/_types/accounts/kernel/utils/encodeCallData.d.ts.map +1 -1
- package/_types/accounts/kernel/utils/getNonceKey.d.ts +1 -1
- package/_types/accounts/kernel/utils/getNonceKey.d.ts.map +1 -1
- package/_types/accounts/kernel/utils/isKernelV2.d.ts +1 -1
- package/_types/accounts/kernel/utils/isKernelV2.d.ts.map +1 -1
- package/_types/accounts/kernel/utils/isWebAuthnAccount.d.ts +4 -0
- package/_types/accounts/kernel/utils/isWebAuthnAccount.d.ts.map +1 -0
- package/_types/accounts/kernel/utils/signMessage.d.ts +2 -1
- package/_types/accounts/kernel/utils/signMessage.d.ts.map +1 -1
- package/_types/accounts/kernel/utils/signTypedData.d.ts +2 -1
- package/_types/accounts/kernel/utils/signTypedData.d.ts.map +1 -1
- package/_types/accounts/kernel/utils/wrapMessageHash.d.ts +1 -1
- package/_types/accounts/kernel/utils/wrapMessageHash.d.ts.map +1 -1
- package/_types/actions/erc7579/installModule.d.ts +2 -2
- package/_types/actions/erc7579/installModule.d.ts.map +1 -1
- package/_types/actions/erc7579/installModules.d.ts +2 -2
- package/_types/actions/erc7579/installModules.d.ts.map +1 -1
- package/_types/actions/erc7579/uninstallModule.d.ts +2 -2
- package/_types/actions/erc7579/uninstallModule.d.ts.map +1 -1
- package/_types/actions/erc7579/uninstallModules.d.ts +2 -2
- package/_types/actions/erc7579/uninstallModules.d.ts.map +1 -1
- package/_types/actions/erc7579.d.ts +4 -4
- package/_types/actions/erc7579.d.ts.map +1 -1
- package/_types/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.d.ts.map +1 -1
- package/_types/utils/encodeInstallModule.d.ts +3 -3
- package/_types/utils/encodeInstallModule.d.ts.map +1 -1
- package/_types/vitest.config.d.ts.map +1 -1
- package/accounts/index.ts +14 -3
- package/accounts/kernel/toEcdsaKernelSmartAccount.ts +32 -513
- package/accounts/kernel/toKernelSmartAccount.ts +645 -0
- package/accounts/kernel/utils/encodeCallData.ts +1 -1
- package/accounts/kernel/utils/getNonceKey.ts +1 -1
- package/accounts/kernel/utils/isKernelV2.ts +1 -1
- package/accounts/kernel/utils/isWebAuthnAccount.ts +8 -0
- package/accounts/kernel/utils/signMessage.ts +55 -1
- package/accounts/kernel/utils/signTypedData.ts +19 -2
- package/accounts/kernel/utils/wrapMessageHash.ts +1 -1
- package/actions/erc7579/installModule.ts +9 -4
- package/actions/erc7579/installModules.ts +9 -4
- package/actions/erc7579/uninstallModule.ts +9 -4
- package/actions/erc7579/uninstallModules.ts +9 -4
- package/actions/erc7579.ts +8 -8
- package/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.ts +24 -0
- package/package.json +3 -2
- package/utils/encodeInstallModule.ts +37 -34
- package/vitest.config.ts +3 -1
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Account,
|
|
3
|
+
Assign,
|
|
4
|
+
Chain,
|
|
5
|
+
OneOf,
|
|
6
|
+
Transport,
|
|
7
|
+
WalletClient
|
|
8
|
+
} from "viem"
|
|
9
|
+
import {
|
|
10
|
+
type Address,
|
|
11
|
+
type Client,
|
|
12
|
+
type Hex,
|
|
13
|
+
type LocalAccount,
|
|
14
|
+
type TypedDataDefinition,
|
|
15
|
+
concatHex,
|
|
16
|
+
encodeAbiParameters,
|
|
17
|
+
encodeFunctionData,
|
|
18
|
+
keccak256,
|
|
19
|
+
toHex,
|
|
20
|
+
zeroAddress
|
|
21
|
+
} from "viem"
|
|
22
|
+
import {
|
|
23
|
+
type SmartAccount,
|
|
24
|
+
type SmartAccountImplementation,
|
|
25
|
+
type UserOperation,
|
|
26
|
+
type WebAuthnAccount,
|
|
27
|
+
entryPoint06Abi,
|
|
28
|
+
entryPoint07Abi,
|
|
29
|
+
entryPoint07Address,
|
|
30
|
+
getUserOperationHash,
|
|
31
|
+
toSmartAccount
|
|
32
|
+
} from "viem/account-abstraction"
|
|
33
|
+
import { signMessage as _signMessage, getChainId } from "viem/actions"
|
|
34
|
+
import { getAction } from "viem/utils"
|
|
35
|
+
import { base64UrlToBytes, bytesToHex, parsePublicKey } from "webauthn-p256"
|
|
36
|
+
import { getAccountNonce } from "../../actions/public/getAccountNonce.js"
|
|
37
|
+
import { getSenderAddress } from "../../actions/public/getSenderAddress.js"
|
|
38
|
+
import { type EthereumProvider, toOwner } from "../../utils/toOwner.js"
|
|
39
|
+
import { KernelInitAbi } from "./abi/KernelAccountAbi.js"
|
|
40
|
+
import {
|
|
41
|
+
KernelV3InitAbi,
|
|
42
|
+
KernelV3_1AccountAbi
|
|
43
|
+
} from "./abi/KernelV3AccountAbi.js"
|
|
44
|
+
import { KernelV3MetaFactoryDeployWithFactoryAbi } from "./abi/KernelV3MetaFactoryAbi.js"
|
|
45
|
+
import {
|
|
46
|
+
DUMMY_ECDSA_SIGNATURE,
|
|
47
|
+
ROOT_MODE_KERNEL_V2,
|
|
48
|
+
VALIDATOR_TYPE
|
|
49
|
+
} from "./constants.js"
|
|
50
|
+
import { encodeCallData } from "./utils/encodeCallData.js"
|
|
51
|
+
import { getNonceKeyWithEncoding } from "./utils/getNonceKey.js"
|
|
52
|
+
import { isKernelV2 } from "./utils/isKernelV2.js"
|
|
53
|
+
import { isWebAuthnAccount } from "./utils/isWebAuthnAccount.js"
|
|
54
|
+
import { signMessage } from "./utils/signMessage.js"
|
|
55
|
+
import { signTypedData } from "./utils/signTypedData.js"
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The account creation ABI for a kernel smart account (from the KernelFactory)
|
|
59
|
+
*/
|
|
60
|
+
const createAccountAbi = [
|
|
61
|
+
{
|
|
62
|
+
inputs: [
|
|
63
|
+
{
|
|
64
|
+
internalType: "address",
|
|
65
|
+
name: "_implementation",
|
|
66
|
+
type: "address"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
internalType: "bytes",
|
|
70
|
+
name: "_data",
|
|
71
|
+
type: "bytes"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
internalType: "uint256",
|
|
75
|
+
name: "_index",
|
|
76
|
+
type: "uint256"
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
name: "createAccount",
|
|
80
|
+
outputs: [
|
|
81
|
+
{
|
|
82
|
+
internalType: "address",
|
|
83
|
+
name: "proxy",
|
|
84
|
+
type: "address"
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
stateMutability: "payable",
|
|
88
|
+
type: "function"
|
|
89
|
+
}
|
|
90
|
+
] as const
|
|
91
|
+
|
|
92
|
+
export type KernelVersion<entryPointVersion extends "0.6" | "0.7"> =
|
|
93
|
+
entryPointVersion extends "0.6"
|
|
94
|
+
? "0.2.1" | "0.2.2" | "0.2.3" | "0.2.4"
|
|
95
|
+
: "0.3.0-beta" | "0.3.1"
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Default addresses map for different kernel smart account versions
|
|
99
|
+
*/
|
|
100
|
+
export const KERNEL_VERSION_TO_ADDRESSES_MAP: {
|
|
101
|
+
[key in KernelVersion<"0.6" | "0.7">]: {
|
|
102
|
+
ECDSA_VALIDATOR: Address
|
|
103
|
+
WEB_AUTHN_VALIDATOR?: Address
|
|
104
|
+
ACCOUNT_LOGIC: Address
|
|
105
|
+
FACTORY_ADDRESS: Address
|
|
106
|
+
META_FACTORY_ADDRESS?: Address
|
|
107
|
+
}
|
|
108
|
+
} = {
|
|
109
|
+
"0.2.1": {
|
|
110
|
+
ECDSA_VALIDATOR: "0xd9AB5096a832b9ce79914329DAEE236f8Eea0390",
|
|
111
|
+
ACCOUNT_LOGIC: "0xf048AD83CB2dfd6037A43902a2A5Be04e53cd2Eb",
|
|
112
|
+
FACTORY_ADDRESS: "0x5de4839a76cf55d0c90e2061ef4386d962E15ae3"
|
|
113
|
+
},
|
|
114
|
+
"0.2.2": {
|
|
115
|
+
ECDSA_VALIDATOR: "0xd9AB5096a832b9ce79914329DAEE236f8Eea0390",
|
|
116
|
+
ACCOUNT_LOGIC: "0x0DA6a956B9488eD4dd761E59f52FDc6c8068E6B5",
|
|
117
|
+
FACTORY_ADDRESS: "0x5de4839a76cf55d0c90e2061ef4386d962E15ae3"
|
|
118
|
+
},
|
|
119
|
+
"0.2.3": {
|
|
120
|
+
ECDSA_VALIDATOR: "0xd9AB5096a832b9ce79914329DAEE236f8Eea0390",
|
|
121
|
+
ACCOUNT_LOGIC: "0xD3F582F6B4814E989Ee8E96bc3175320B5A540ab",
|
|
122
|
+
FACTORY_ADDRESS: "0x5de4839a76cf55d0c90e2061ef4386d962E15ae3"
|
|
123
|
+
},
|
|
124
|
+
"0.2.4": {
|
|
125
|
+
ECDSA_VALIDATOR: "0xd9AB5096a832b9ce79914329DAEE236f8Eea0390",
|
|
126
|
+
ACCOUNT_LOGIC: "0xd3082872F8B06073A021b4602e022d5A070d7cfC",
|
|
127
|
+
FACTORY_ADDRESS: "0x5de4839a76cf55d0c90e2061ef4386d962E15ae3"
|
|
128
|
+
},
|
|
129
|
+
"0.3.0-beta": {
|
|
130
|
+
ECDSA_VALIDATOR: "0x8104e3Ad430EA6d354d013A6789fDFc71E671c43",
|
|
131
|
+
ACCOUNT_LOGIC: "0x94F097E1ebEB4ecA3AAE54cabb08905B239A7D27",
|
|
132
|
+
FACTORY_ADDRESS: "0x6723b44Abeec4E71eBE3232BD5B455805baDD22f",
|
|
133
|
+
META_FACTORY_ADDRESS: "0xd703aaE79538628d27099B8c4f621bE4CCd142d5",
|
|
134
|
+
WEB_AUTHN_VALIDATOR: "0xbA45a2BFb8De3D24cA9D7F1B551E14dFF5d690Fd"
|
|
135
|
+
},
|
|
136
|
+
"0.3.1": {
|
|
137
|
+
ECDSA_VALIDATOR: "0x845ADb2C711129d4f3966735eD98a9F09fC4cE57",
|
|
138
|
+
ACCOUNT_LOGIC: "0xBAC849bB641841b44E965fB01A4Bf5F074f84b4D",
|
|
139
|
+
FACTORY_ADDRESS: "0xaac5D4240AF87249B3f71BC8E4A2cae074A3E419",
|
|
140
|
+
META_FACTORY_ADDRESS: "0xd703aaE79538628d27099B8c4f621bE4CCd142d5",
|
|
141
|
+
WEB_AUTHN_VALIDATOR: "0xbA45a2BFb8De3D24cA9D7F1B551E14dFF5d690Fd"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Get supported Kernel Smart Account version based on entryPoint
|
|
147
|
+
* @param entryPoint
|
|
148
|
+
*/
|
|
149
|
+
const getDefaultKernelVersion = <TEntryPointVersion extends "0.6" | "0.7">(
|
|
150
|
+
entryPointVersion: TEntryPointVersion,
|
|
151
|
+
version?: KernelVersion<TEntryPointVersion>
|
|
152
|
+
): KernelVersion<TEntryPointVersion> => {
|
|
153
|
+
if (version) {
|
|
154
|
+
return version
|
|
155
|
+
}
|
|
156
|
+
return (
|
|
157
|
+
entryPointVersion === "0.6" ? "0.2.2" : "0.3.0-beta"
|
|
158
|
+
) as KernelVersion<TEntryPointVersion>
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
type KERNEL_ADDRESSES = {
|
|
162
|
+
validatorAddress?: Address
|
|
163
|
+
accountLogicAddress: Address
|
|
164
|
+
factoryAddress: Address
|
|
165
|
+
metaFactoryAddress: Address
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get default addresses for Kernel Smart Account based on entryPoint or user input
|
|
170
|
+
* @param entryPointAddress
|
|
171
|
+
* @param ecdsaValidatorAddress
|
|
172
|
+
* @param accountLogicAddress
|
|
173
|
+
* @param factoryAddress
|
|
174
|
+
* @param metaFactoryAddress
|
|
175
|
+
*/
|
|
176
|
+
const getDefaultAddresses = ({
|
|
177
|
+
validatorAddress: _validatorAddress,
|
|
178
|
+
accountLogicAddress: _accountLogicAddress,
|
|
179
|
+
factoryAddress: _factoryAddress,
|
|
180
|
+
metaFactoryAddress: _metaFactoryAddress,
|
|
181
|
+
kernelVersion,
|
|
182
|
+
isWebAuthn
|
|
183
|
+
}: Partial<KERNEL_ADDRESSES> & {
|
|
184
|
+
kernelVersion: KernelVersion<"0.6" | "0.7">
|
|
185
|
+
isWebAuthn: boolean
|
|
186
|
+
}): KERNEL_ADDRESSES => {
|
|
187
|
+
const addresses = KERNEL_VERSION_TO_ADDRESSES_MAP[kernelVersion]
|
|
188
|
+
const validatorAddress =
|
|
189
|
+
_validatorAddress ??
|
|
190
|
+
(isWebAuthn ? addresses.WEB_AUTHN_VALIDATOR : addresses.ECDSA_VALIDATOR)
|
|
191
|
+
const accountLogicAddress = _accountLogicAddress ?? addresses.ACCOUNT_LOGIC
|
|
192
|
+
const factoryAddress = _factoryAddress ?? addresses.FACTORY_ADDRESS
|
|
193
|
+
const metaFactoryAddress =
|
|
194
|
+
_metaFactoryAddress ?? addresses?.META_FACTORY_ADDRESS ?? zeroAddress // Meta Factory doesn't exists for Kernel v2.2
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
validatorAddress,
|
|
198
|
+
accountLogicAddress,
|
|
199
|
+
factoryAddress,
|
|
200
|
+
metaFactoryAddress
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export const getEcdsaRootIdentifierForKernelV3 = (
|
|
205
|
+
validatorAddress: Address
|
|
206
|
+
) => {
|
|
207
|
+
return concatHex([VALIDATOR_TYPE.VALIDATOR, validatorAddress])
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get the initialization data for a kernel smart account
|
|
212
|
+
* @param entryPoint
|
|
213
|
+
* @param owner
|
|
214
|
+
* @param ecdsaValidatorAddress
|
|
215
|
+
*/
|
|
216
|
+
const getInitializationData = <entryPointVersion extends "0.6" | "0.7">({
|
|
217
|
+
entryPoint: { version: entryPointVersion },
|
|
218
|
+
kernelVersion,
|
|
219
|
+
validatorData,
|
|
220
|
+
validatorAddress
|
|
221
|
+
}: {
|
|
222
|
+
kernelVersion: KernelVersion<entryPointVersion>
|
|
223
|
+
entryPoint: {
|
|
224
|
+
version: entryPointVersion
|
|
225
|
+
}
|
|
226
|
+
validatorData: Hex
|
|
227
|
+
validatorAddress: Address
|
|
228
|
+
}) => {
|
|
229
|
+
if (entryPointVersion === "0.6") {
|
|
230
|
+
return encodeFunctionData({
|
|
231
|
+
abi: KernelInitAbi,
|
|
232
|
+
functionName: "initialize",
|
|
233
|
+
args: [validatorAddress, validatorData]
|
|
234
|
+
})
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (kernelVersion === "0.3.0-beta") {
|
|
238
|
+
return encodeFunctionData({
|
|
239
|
+
abi: KernelV3InitAbi,
|
|
240
|
+
functionName: "initialize",
|
|
241
|
+
args: [
|
|
242
|
+
getEcdsaRootIdentifierForKernelV3(validatorAddress),
|
|
243
|
+
zeroAddress,
|
|
244
|
+
validatorData,
|
|
245
|
+
"0x"
|
|
246
|
+
]
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return encodeFunctionData({
|
|
251
|
+
abi: KernelV3_1AccountAbi,
|
|
252
|
+
functionName: "initialize",
|
|
253
|
+
args: [
|
|
254
|
+
getEcdsaRootIdentifierForKernelV3(validatorAddress),
|
|
255
|
+
zeroAddress,
|
|
256
|
+
validatorData,
|
|
257
|
+
"0x",
|
|
258
|
+
[]
|
|
259
|
+
]
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const getValidatorData = async (owner: WebAuthnAccount | LocalAccount) => {
|
|
264
|
+
if (owner.type === "local") {
|
|
265
|
+
return owner.address
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (isWebAuthnAccount(owner)) {
|
|
269
|
+
const parsedPublicKey = parsePublicKey(owner.publicKey)
|
|
270
|
+
const authenticatorIdHash = keccak256(
|
|
271
|
+
bytesToHex(base64UrlToBytes(owner.id))
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
return encodeAbiParameters(
|
|
275
|
+
[
|
|
276
|
+
{
|
|
277
|
+
components: [
|
|
278
|
+
{ name: "x", type: "uint256" },
|
|
279
|
+
{ name: "y", type: "uint256" }
|
|
280
|
+
],
|
|
281
|
+
name: "webAuthnData",
|
|
282
|
+
type: "tuple"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: "authenticatorIdHash",
|
|
286
|
+
type: "bytes32"
|
|
287
|
+
}
|
|
288
|
+
],
|
|
289
|
+
[
|
|
290
|
+
{
|
|
291
|
+
x: parsedPublicKey.x,
|
|
292
|
+
y: parsedPublicKey.y
|
|
293
|
+
},
|
|
294
|
+
authenticatorIdHash
|
|
295
|
+
]
|
|
296
|
+
)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
throw new Error("Invalid owner type")
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Get the account initialization code for a kernel smart account
|
|
304
|
+
* @param entryPoint
|
|
305
|
+
* @param owner
|
|
306
|
+
* @param index
|
|
307
|
+
* @param factoryAddress
|
|
308
|
+
* @param accountLogicAddress
|
|
309
|
+
* @param ecdsaValidatorAddress
|
|
310
|
+
*/
|
|
311
|
+
const getAccountInitCode = async <entryPointVersion extends "0.6" | "0.7">({
|
|
312
|
+
entryPointVersion,
|
|
313
|
+
kernelVersion,
|
|
314
|
+
validatorData,
|
|
315
|
+
index,
|
|
316
|
+
factoryAddress,
|
|
317
|
+
accountLogicAddress,
|
|
318
|
+
validatorAddress
|
|
319
|
+
}: {
|
|
320
|
+
kernelVersion: KernelVersion<entryPointVersion>
|
|
321
|
+
entryPointVersion: entryPointVersion
|
|
322
|
+
validatorData: Hex
|
|
323
|
+
index: bigint
|
|
324
|
+
factoryAddress: Address
|
|
325
|
+
accountLogicAddress: Address
|
|
326
|
+
validatorAddress: Address
|
|
327
|
+
}): Promise<Hex> => {
|
|
328
|
+
// Build the account initialization data
|
|
329
|
+
const initializationData = getInitializationData({
|
|
330
|
+
entryPoint: { version: entryPointVersion },
|
|
331
|
+
kernelVersion,
|
|
332
|
+
validatorAddress,
|
|
333
|
+
validatorData
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
// Build the account init code
|
|
337
|
+
|
|
338
|
+
if (entryPointVersion === "0.6") {
|
|
339
|
+
return encodeFunctionData({
|
|
340
|
+
abi: createAccountAbi,
|
|
341
|
+
functionName: "createAccount",
|
|
342
|
+
args: [accountLogicAddress, initializationData, index]
|
|
343
|
+
})
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return encodeFunctionData({
|
|
347
|
+
abi: KernelV3MetaFactoryDeployWithFactoryAbi,
|
|
348
|
+
functionName: "deployWithFactory",
|
|
349
|
+
args: [factoryAddress, initializationData, toHex(index, { size: 32 })]
|
|
350
|
+
})
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export type ToKernelSmartAccountParameters<
|
|
354
|
+
entryPointVersion extends "0.6" | "0.7",
|
|
355
|
+
kernelVersion extends KernelVersion<entryPointVersion>,
|
|
356
|
+
owner extends OneOf<
|
|
357
|
+
| EthereumProvider
|
|
358
|
+
| WalletClient<Transport, Chain | undefined, Account>
|
|
359
|
+
| LocalAccount
|
|
360
|
+
| WebAuthnAccount
|
|
361
|
+
>
|
|
362
|
+
> = {
|
|
363
|
+
client: Client
|
|
364
|
+
owners: [owner]
|
|
365
|
+
entryPoint?: {
|
|
366
|
+
address: Address
|
|
367
|
+
version: entryPointVersion
|
|
368
|
+
}
|
|
369
|
+
address?: Address
|
|
370
|
+
version?: kernelVersion
|
|
371
|
+
index?: bigint
|
|
372
|
+
factoryAddress?: Address
|
|
373
|
+
metaFactoryAddress?: Address
|
|
374
|
+
accountLogicAddress?: Address
|
|
375
|
+
validatorAddress?: Address
|
|
376
|
+
nonceKey?: bigint
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export type KernelSmartAccountImplementation<
|
|
380
|
+
entryPointVersion extends "0.6" | "0.7" = "0.7"
|
|
381
|
+
> = Assign<
|
|
382
|
+
SmartAccountImplementation<
|
|
383
|
+
entryPointVersion extends "0.6"
|
|
384
|
+
? typeof entryPoint06Abi
|
|
385
|
+
: typeof entryPoint07Abi,
|
|
386
|
+
entryPointVersion
|
|
387
|
+
// {
|
|
388
|
+
// // entryPoint === ENTRYPOINT_ADDRESS_V06 ? "0.2.2" : "0.3.0-beta"
|
|
389
|
+
// abi: entryPointVersion extends "0.6" ? typeof BiconomyAbi
|
|
390
|
+
// factory: { abi: typeof FactoryAbi; address: Address }
|
|
391
|
+
// }
|
|
392
|
+
>,
|
|
393
|
+
{ sign: NonNullable<SmartAccountImplementation["sign"]> }
|
|
394
|
+
>
|
|
395
|
+
|
|
396
|
+
export type ToKernelSmartAccountReturnType<
|
|
397
|
+
entryPointVersion extends "0.6" | "0.7" = "0.7"
|
|
398
|
+
> = SmartAccount<KernelSmartAccountImplementation<entryPointVersion>>
|
|
399
|
+
/**
|
|
400
|
+
* Build a kernel smart account from a private key, that use the ECDSA or passkeys signer behind the scene
|
|
401
|
+
* @param client
|
|
402
|
+
* @param privateKey
|
|
403
|
+
* @param entryPoint
|
|
404
|
+
* @param index
|
|
405
|
+
* @param factoryAddress
|
|
406
|
+
* @param accountLogicAddress
|
|
407
|
+
* @param validatorAddress
|
|
408
|
+
*/
|
|
409
|
+
export async function toKernelSmartAccount<
|
|
410
|
+
entryPointVersion extends "0.6" | "0.7",
|
|
411
|
+
kernelVersion extends KernelVersion<entryPointVersion>,
|
|
412
|
+
owner extends OneOf<
|
|
413
|
+
| EthereumProvider
|
|
414
|
+
| WalletClient<Transport, Chain | undefined, Account>
|
|
415
|
+
| LocalAccount
|
|
416
|
+
| WebAuthnAccount
|
|
417
|
+
>
|
|
418
|
+
>(
|
|
419
|
+
parameters: ToKernelSmartAccountParameters<
|
|
420
|
+
entryPointVersion,
|
|
421
|
+
kernelVersion,
|
|
422
|
+
owner
|
|
423
|
+
>
|
|
424
|
+
): Promise<ToKernelSmartAccountReturnType<entryPointVersion>> {
|
|
425
|
+
const {
|
|
426
|
+
client,
|
|
427
|
+
address,
|
|
428
|
+
index = 0n,
|
|
429
|
+
owners,
|
|
430
|
+
version,
|
|
431
|
+
validatorAddress: _validatorAddress,
|
|
432
|
+
factoryAddress: _factoryAddress,
|
|
433
|
+
metaFactoryAddress: _metaFactoryAddress,
|
|
434
|
+
accountLogicAddress: _accountLogicAddress
|
|
435
|
+
} = parameters
|
|
436
|
+
|
|
437
|
+
const isWebAuthn = owners[0].type === "webAuthn"
|
|
438
|
+
|
|
439
|
+
const owner = isWebAuthn
|
|
440
|
+
? (owners[0] as WebAuthnAccount)
|
|
441
|
+
: await toOwner({
|
|
442
|
+
owner: owners[0] as OneOf<
|
|
443
|
+
| EthereumProvider
|
|
444
|
+
| WalletClient<Transport, Chain | undefined, Account>
|
|
445
|
+
| LocalAccount
|
|
446
|
+
>
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
const entryPoint = {
|
|
450
|
+
address: parameters.entryPoint?.address ?? entryPoint07Address,
|
|
451
|
+
abi:
|
|
452
|
+
(parameters.entryPoint?.version ?? "0.7") === "0.6"
|
|
453
|
+
? entryPoint06Abi
|
|
454
|
+
: entryPoint07Abi,
|
|
455
|
+
version: parameters.entryPoint?.version ?? "0.7"
|
|
456
|
+
} as const
|
|
457
|
+
|
|
458
|
+
const kernelVersion = getDefaultKernelVersion(entryPoint.version, version)
|
|
459
|
+
|
|
460
|
+
const {
|
|
461
|
+
accountLogicAddress,
|
|
462
|
+
validatorAddress,
|
|
463
|
+
factoryAddress,
|
|
464
|
+
metaFactoryAddress
|
|
465
|
+
} = getDefaultAddresses({
|
|
466
|
+
validatorAddress: _validatorAddress,
|
|
467
|
+
accountLogicAddress: _accountLogicAddress,
|
|
468
|
+
factoryAddress: _factoryAddress,
|
|
469
|
+
metaFactoryAddress: _metaFactoryAddress,
|
|
470
|
+
kernelVersion,
|
|
471
|
+
isWebAuthn
|
|
472
|
+
})
|
|
473
|
+
|
|
474
|
+
if (!validatorAddress) {
|
|
475
|
+
throw new Error("Validator address is required")
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Helper to generate the init code for the smart account
|
|
479
|
+
const generateInitCode = async () =>
|
|
480
|
+
getAccountInitCode({
|
|
481
|
+
entryPointVersion: entryPoint.version,
|
|
482
|
+
kernelVersion,
|
|
483
|
+
validatorData: await getValidatorData(owner),
|
|
484
|
+
index,
|
|
485
|
+
factoryAddress,
|
|
486
|
+
accountLogicAddress,
|
|
487
|
+
validatorAddress
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
let accountAddress: Address | undefined = address
|
|
491
|
+
|
|
492
|
+
let chainId: number
|
|
493
|
+
|
|
494
|
+
const getMemoizedChainId = async () => {
|
|
495
|
+
if (chainId) return chainId
|
|
496
|
+
chainId = client.chain
|
|
497
|
+
? client.chain.id
|
|
498
|
+
: await getAction(client, getChainId, "getChainId")({})
|
|
499
|
+
return chainId
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const getFactoryArgs = async () => {
|
|
503
|
+
return {
|
|
504
|
+
factory:
|
|
505
|
+
entryPoint.version === "0.6"
|
|
506
|
+
? factoryAddress
|
|
507
|
+
: metaFactoryAddress,
|
|
508
|
+
factoryData: await generateInitCode()
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
return toSmartAccount({
|
|
513
|
+
client,
|
|
514
|
+
entryPoint,
|
|
515
|
+
getFactoryArgs,
|
|
516
|
+
async getAddress() {
|
|
517
|
+
if (accountAddress) return accountAddress
|
|
518
|
+
|
|
519
|
+
const { factory, factoryData } = await getFactoryArgs()
|
|
520
|
+
|
|
521
|
+
// Get the sender address based on the init code
|
|
522
|
+
accountAddress = await getSenderAddress(client, {
|
|
523
|
+
factory,
|
|
524
|
+
factoryData,
|
|
525
|
+
entryPointAddress: entryPoint.address
|
|
526
|
+
})
|
|
527
|
+
|
|
528
|
+
return accountAddress
|
|
529
|
+
},
|
|
530
|
+
async encodeCalls(calls) {
|
|
531
|
+
return encodeCallData({ calls, kernelVersion })
|
|
532
|
+
},
|
|
533
|
+
async getNonce(_args) {
|
|
534
|
+
return getAccountNonce(client, {
|
|
535
|
+
address: await this.getAddress(),
|
|
536
|
+
entryPointAddress: entryPoint.address,
|
|
537
|
+
key: getNonceKeyWithEncoding(
|
|
538
|
+
kernelVersion,
|
|
539
|
+
validatorAddress,
|
|
540
|
+
/*args?.key ?? */ parameters.nonceKey ?? 0n
|
|
541
|
+
)
|
|
542
|
+
})
|
|
543
|
+
},
|
|
544
|
+
async getStubSignature() {
|
|
545
|
+
if (isKernelV2(kernelVersion)) {
|
|
546
|
+
return concatHex([ROOT_MODE_KERNEL_V2, DUMMY_ECDSA_SIGNATURE])
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (isWebAuthnAccount(owner)) {
|
|
550
|
+
return encodeAbiParameters(
|
|
551
|
+
[
|
|
552
|
+
{ name: "authenticatorData", type: "bytes" },
|
|
553
|
+
{ name: "clientDataJSON", type: "string" },
|
|
554
|
+
{ name: "responseTypeLocation", type: "uint256" },
|
|
555
|
+
{ name: "r", type: "uint256" },
|
|
556
|
+
{ name: "s", type: "uint256" },
|
|
557
|
+
{ name: "usePrecompiled", type: "bool" }
|
|
558
|
+
],
|
|
559
|
+
[
|
|
560
|
+
"0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97631d00000000",
|
|
561
|
+
'{"type":"webauthn.get","challenge":"tbxXNFS9X_4Byr1cMwqKrIGB-_30a0QhZ6y7ucM0BOE","origin":"http://localhost:3000","crossOrigin":false, "other_keys_can_be_added_here":"do not compare clientDataJSON against a template. See https://goo.gl/yabPex"}',
|
|
562
|
+
1n,
|
|
563
|
+
44941127272049826721201904734628716258498742255959991581049806490182030242267n,
|
|
564
|
+
9910254599581058084911561569808925251374718953855182016200087235935345969636n,
|
|
565
|
+
false
|
|
566
|
+
]
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
return DUMMY_ECDSA_SIGNATURE
|
|
571
|
+
},
|
|
572
|
+
async sign({ hash }) {
|
|
573
|
+
return this.signMessage({ message: hash })
|
|
574
|
+
},
|
|
575
|
+
async signMessage({ message }) {
|
|
576
|
+
const signature = await signMessage({
|
|
577
|
+
owner,
|
|
578
|
+
message,
|
|
579
|
+
accountAddress: await this.getAddress(),
|
|
580
|
+
kernelVersion,
|
|
581
|
+
chainId: await getMemoizedChainId()
|
|
582
|
+
})
|
|
583
|
+
|
|
584
|
+
if (isKernelV2(kernelVersion)) {
|
|
585
|
+
return signature
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
return concatHex([
|
|
589
|
+
getEcdsaRootIdentifierForKernelV3(validatorAddress),
|
|
590
|
+
signature
|
|
591
|
+
])
|
|
592
|
+
},
|
|
593
|
+
async signTypedData(typedData) {
|
|
594
|
+
const signature = await signTypedData({
|
|
595
|
+
owner: owner,
|
|
596
|
+
chainId: await getMemoizedChainId(),
|
|
597
|
+
...(typedData as TypedDataDefinition),
|
|
598
|
+
accountAddress: await this.getAddress(),
|
|
599
|
+
kernelVersion
|
|
600
|
+
})
|
|
601
|
+
|
|
602
|
+
if (isKernelV2(kernelVersion)) {
|
|
603
|
+
return signature
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
return concatHex([
|
|
607
|
+
getEcdsaRootIdentifierForKernelV3(validatorAddress),
|
|
608
|
+
signature
|
|
609
|
+
])
|
|
610
|
+
},
|
|
611
|
+
// Sign a user operation
|
|
612
|
+
async signUserOperation(parameters) {
|
|
613
|
+
const { chainId = await getMemoizedChainId(), ...userOperation } =
|
|
614
|
+
parameters
|
|
615
|
+
|
|
616
|
+
const hash = getUserOperationHash({
|
|
617
|
+
userOperation: {
|
|
618
|
+
...userOperation,
|
|
619
|
+
sender: userOperation.sender ?? (await this.getAddress()),
|
|
620
|
+
signature: "0x"
|
|
621
|
+
} as UserOperation<entryPointVersion>,
|
|
622
|
+
entryPointAddress: entryPoint.address,
|
|
623
|
+
entryPointVersion: entryPoint.version,
|
|
624
|
+
chainId: chainId
|
|
625
|
+
})
|
|
626
|
+
const signature = isWebAuthnAccount(owner)
|
|
627
|
+
? await signMessage({
|
|
628
|
+
owner,
|
|
629
|
+
message: { raw: hash },
|
|
630
|
+
chainId,
|
|
631
|
+
accountAddress: await this.getAddress(),
|
|
632
|
+
kernelVersion
|
|
633
|
+
})
|
|
634
|
+
: await owner.signMessage({
|
|
635
|
+
message: { raw: hash }
|
|
636
|
+
})
|
|
637
|
+
|
|
638
|
+
// Always use the sudo mode, since we will use external paymaster
|
|
639
|
+
if (isKernelV2(kernelVersion)) {
|
|
640
|
+
return concatHex(["0x00000000", signature])
|
|
641
|
+
}
|
|
642
|
+
return signature
|
|
643
|
+
}
|
|
644
|
+
}) as Promise<ToKernelSmartAccountReturnType<entryPointVersion>>
|
|
645
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Address, type Hex, encodeFunctionData } from "viem"
|
|
2
2
|
import { encode7579Calls } from "../../../utils/encode7579Calls.js"
|
|
3
3
|
import { KernelExecuteAbi } from "../abi/KernelAccountAbi.js"
|
|
4
|
-
import type { KernelVersion } from "../
|
|
4
|
+
import type { KernelVersion } from "../toKernelSmartAccount.js"
|
|
5
5
|
import { isKernelV2 } from "./isKernelV2.js"
|
|
6
6
|
|
|
7
7
|
export const encodeCallData = ({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Address, concatHex, maxUint16, pad, toHex } from "viem"
|
|
2
2
|
import { VALIDATOR_MODE, VALIDATOR_TYPE } from "../constants.js"
|
|
3
|
-
import type { KernelVersion } from "../
|
|
3
|
+
import type { KernelVersion } from "../toKernelSmartAccount.js"
|
|
4
4
|
import { isKernelV2 } from "./isKernelV2.js"
|
|
5
5
|
|
|
6
6
|
export const getNonceKeyWithEncoding = (
|