permissionless 0.0.15 → 0.0.17
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 +12 -0
- package/_cjs/accounts/biconomy/abi/BiconomySmartAccountAbi.js +102 -0
- package/_cjs/accounts/biconomy/abi/BiconomySmartAccountAbi.js.map +1 -0
- package/_cjs/accounts/biconomy/privateKeyToBiconomySmartAccount.js +15 -0
- package/_cjs/accounts/biconomy/privateKeyToBiconomySmartAccount.js.map +1 -0
- package/_cjs/accounts/biconomy/signerToBiconomySmartAccount.js +195 -0
- package/_cjs/accounts/biconomy/signerToBiconomySmartAccount.js.map +1 -0
- package/_cjs/accounts/index.js +3 -1
- package/_cjs/accounts/index.js.map +1 -1
- package/_cjs/accounts/kernel/signerToEcdsaKernelSmartAccount.js +10 -14
- package/_cjs/accounts/kernel/signerToEcdsaKernelSmartAccount.js.map +1 -1
- package/_cjs/accounts/signerToSafeSmartAccount.js +23 -20
- package/_cjs/accounts/signerToSafeSmartAccount.js.map +1 -1
- package/_cjs/accounts/signerToSimpleSmartAccount.js +5 -7
- package/_cjs/accounts/signerToSimpleSmartAccount.js.map +1 -1
- package/_cjs/accounts/types.js.map +1 -1
- package/_cjs/utils/deepHexlify.js +2 -2
- package/_cjs/utils/deepHexlify.js.map +1 -1
- package/_esm/accounts/biconomy/abi/BiconomySmartAccountAbi.js +105 -0
- package/_esm/accounts/biconomy/abi/BiconomySmartAccountAbi.js.map +1 -0
- package/_esm/accounts/biconomy/privateKeyToBiconomySmartAccount.js +17 -0
- package/_esm/accounts/biconomy/privateKeyToBiconomySmartAccount.js.map +1 -0
- package/_esm/accounts/biconomy/signerToBiconomySmartAccount.js +231 -0
- package/_esm/accounts/biconomy/signerToBiconomySmartAccount.js.map +1 -0
- package/_esm/accounts/index.js +2 -1
- package/_esm/accounts/index.js.map +1 -1
- package/_esm/accounts/kernel/signerToEcdsaKernelSmartAccount.js +11 -15
- package/_esm/accounts/kernel/signerToEcdsaKernelSmartAccount.js.map +1 -1
- package/_esm/accounts/signerToSafeSmartAccount.js +24 -27
- package/_esm/accounts/signerToSafeSmartAccount.js.map +1 -1
- package/_esm/accounts/signerToSimpleSmartAccount.js +5 -7
- package/_esm/accounts/signerToSimpleSmartAccount.js.map +1 -1
- package/_esm/accounts/types.js.map +1 -1
- package/_esm/utils/deepHexlify.js +2 -2
- package/_esm/utils/deepHexlify.js.map +1 -1
- package/_types/accounts/biconomy/abi/BiconomySmartAccountAbi.d.ts +59 -0
- package/_types/accounts/biconomy/abi/BiconomySmartAccountAbi.d.ts.map +1 -0
- package/_types/accounts/biconomy/privateKeyToBiconomySmartAccount.d.ts +13 -0
- package/_types/accounts/biconomy/privateKeyToBiconomySmartAccount.d.ts.map +1 -0
- package/_types/accounts/biconomy/signerToBiconomySmartAccount.d.ts +23 -0
- package/_types/accounts/biconomy/signerToBiconomySmartAccount.d.ts.map +1 -0
- package/_types/accounts/index.d.ts +2 -1
- package/_types/accounts/index.d.ts.map +1 -1
- package/_types/accounts/kernel/signerToEcdsaKernelSmartAccount.d.ts +2 -2
- package/_types/accounts/kernel/signerToEcdsaKernelSmartAccount.d.ts.map +1 -1
- package/_types/accounts/signerToSafeSmartAccount.d.ts +4 -2
- package/_types/accounts/signerToSafeSmartAccount.d.ts.map +1 -1
- package/_types/accounts/signerToSimpleSmartAccount.d.ts +2 -2
- package/_types/accounts/signerToSimpleSmartAccount.d.ts.map +1 -1
- package/_types/accounts/types.d.ts +2 -2
- package/_types/accounts/types.d.ts.map +1 -1
- package/_types/utils/deepHexlify.d.ts.map +1 -1
- package/accounts/biconomy/abi/BiconomySmartAccountAbi.ts +105 -0
- package/accounts/biconomy/privateKeyToBiconomySmartAccount.ts +40 -0
- package/accounts/biconomy/signerToBiconomySmartAccount.ts +364 -0
- package/accounts/index.ts +8 -1
- package/accounts/kernel/signerToEcdsaKernelSmartAccount.ts +17 -19
- package/accounts/signerToSafeSmartAccount.ts +37 -33
- package/accounts/signerToSimpleSmartAccount.ts +11 -12
- package/accounts/types.ts +4 -5
- package/actions/smartAccount/prepareUserOperationRequest.ts +1 -1
- package/package.json +1 -1
- package/utils/deepHexlify.test.ts +0 -2
- package/utils/deepHexlify.ts +6 -2
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Address,
|
|
3
|
+
type Chain,
|
|
4
|
+
type Client,
|
|
5
|
+
type Hex,
|
|
6
|
+
type LocalAccount,
|
|
7
|
+
type Transport,
|
|
8
|
+
concatHex,
|
|
9
|
+
encodeAbiParameters,
|
|
10
|
+
encodeFunctionData,
|
|
11
|
+
encodePacked,
|
|
12
|
+
getContractAddress,
|
|
13
|
+
hexToBigInt,
|
|
14
|
+
keccak256,
|
|
15
|
+
parseAbiParameters
|
|
16
|
+
} from "viem"
|
|
17
|
+
import { toAccount } from "viem/accounts"
|
|
18
|
+
import {
|
|
19
|
+
getBytecode,
|
|
20
|
+
getChainId,
|
|
21
|
+
signMessage,
|
|
22
|
+
signTypedData
|
|
23
|
+
} from "viem/actions"
|
|
24
|
+
import { getAccountNonce } from "../../actions/public/getAccountNonce.js"
|
|
25
|
+
import { getUserOperationHash } from "../../utils/getUserOperationHash.js"
|
|
26
|
+
import {
|
|
27
|
+
SignTransactionNotSupportedBySmartAccount,
|
|
28
|
+
type SmartAccount,
|
|
29
|
+
type SmartAccountSigner
|
|
30
|
+
} from "../types.js"
|
|
31
|
+
import {
|
|
32
|
+
BiconomyExecuteAbi,
|
|
33
|
+
BiconomyInitAbi
|
|
34
|
+
} from "./abi/BiconomySmartAccountAbi.js"
|
|
35
|
+
// import Abis
|
|
36
|
+
|
|
37
|
+
export type BiconomySmartAccount<
|
|
38
|
+
transport extends Transport = Transport,
|
|
39
|
+
chain extends Chain | undefined = Chain | undefined
|
|
40
|
+
> = SmartAccount<"biconomySmartAccount", transport, chain>
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The account creation ABI for Biconomy Smart Account (from the biconomy SmartAccountFactory)
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
const createAccountAbi = [
|
|
47
|
+
{
|
|
48
|
+
inputs: [
|
|
49
|
+
{
|
|
50
|
+
internalType: "address",
|
|
51
|
+
name: "moduleSetupContract",
|
|
52
|
+
type: "address"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
internalType: "bytes",
|
|
56
|
+
name: "moduleSetupData",
|
|
57
|
+
type: "bytes"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
internalType: "uint256",
|
|
61
|
+
name: "index",
|
|
62
|
+
type: "uint256"
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
name: "deployCounterFactualAccount",
|
|
66
|
+
outputs: [
|
|
67
|
+
{
|
|
68
|
+
internalType: "address",
|
|
69
|
+
name: "proxy",
|
|
70
|
+
type: "address"
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
stateMutability: "nonpayable",
|
|
74
|
+
type: "function"
|
|
75
|
+
}
|
|
76
|
+
] as const
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Default addresses for Biconomy Smart Account
|
|
80
|
+
*/
|
|
81
|
+
const BICONOMY_ADDRESSES: {
|
|
82
|
+
ECDSA_OWNERSHIP_REGISTRY_MODULE: Address
|
|
83
|
+
ACCOUNT_V2_0_LOGIC: Address
|
|
84
|
+
FACTORY_ADDRESS: Address
|
|
85
|
+
DEFAULT_FALLBACK_HANDLER_ADDRESS: Address
|
|
86
|
+
} = {
|
|
87
|
+
ECDSA_OWNERSHIP_REGISTRY_MODULE:
|
|
88
|
+
"0x0000001c5b32F37F5beA87BDD5374eB2aC54eA8e",
|
|
89
|
+
ACCOUNT_V2_0_LOGIC: "0x0000002512019Dafb59528B82CB92D3c5D2423aC",
|
|
90
|
+
FACTORY_ADDRESS: "0x000000a56Aaca3e9a4C479ea6b6CD0DbcB6634F5",
|
|
91
|
+
DEFAULT_FALLBACK_HANDLER_ADDRESS:
|
|
92
|
+
"0x0bBa6d96BD616BedC6BFaa341742FD43c60b83C1"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const BICONOMY_PROXY_CREATION_CODE =
|
|
96
|
+
"0x6080346100aa57601f61012038819003918201601f19168301916001600160401b038311848410176100af578084926020946040528339810103126100aa57516001600160a01b0381168082036100aa5715610065573055604051605a90816100c68239f35b60405162461bcd60e51b815260206004820152601e60248201527f496e76616c696420696d706c656d656e746174696f6e206164647265737300006044820152606490fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe608060405230546000808092368280378136915af43d82803e156020573d90f35b3d90fdfea2646970667358221220a03b18dce0be0b4c9afe58a9eb85c35205e2cf087da098bbf1d23945bf89496064736f6c63430008110033"
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get the account initialization code for Biconomy smart account with ECDSA as default authorization module
|
|
100
|
+
* @param owner
|
|
101
|
+
* @param index
|
|
102
|
+
* @param factoryAddress
|
|
103
|
+
* @param ecdsaValidatorAddress
|
|
104
|
+
*/
|
|
105
|
+
const getAccountInitCode = async ({
|
|
106
|
+
owner,
|
|
107
|
+
index,
|
|
108
|
+
factoryAddress,
|
|
109
|
+
ecdsaModuleAddress
|
|
110
|
+
}: {
|
|
111
|
+
owner: Address
|
|
112
|
+
index: bigint
|
|
113
|
+
factoryAddress: Address
|
|
114
|
+
ecdsaModuleAddress: Address
|
|
115
|
+
}): Promise<Hex> => {
|
|
116
|
+
if (!owner) throw new Error("Owner account not found")
|
|
117
|
+
|
|
118
|
+
// Build the module setup data
|
|
119
|
+
const ecdsaOwnershipInitData = encodeFunctionData({
|
|
120
|
+
abi: BiconomyInitAbi,
|
|
121
|
+
functionName: "initForSmartAccount",
|
|
122
|
+
args: [owner]
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// Build the account init code
|
|
126
|
+
return concatHex([
|
|
127
|
+
factoryAddress,
|
|
128
|
+
encodeFunctionData({
|
|
129
|
+
abi: createAccountAbi,
|
|
130
|
+
functionName: "deployCounterFactualAccount",
|
|
131
|
+
args: [ecdsaModuleAddress, ecdsaOwnershipInitData, index]
|
|
132
|
+
}) as Hex
|
|
133
|
+
])
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const getAccountAddress = async ({
|
|
137
|
+
factoryAddress,
|
|
138
|
+
accountLogicAddress,
|
|
139
|
+
fallbackHandlerAddress,
|
|
140
|
+
ecdsaModuleAddress,
|
|
141
|
+
owner,
|
|
142
|
+
index = 0n
|
|
143
|
+
}: {
|
|
144
|
+
factoryAddress: Address
|
|
145
|
+
accountLogicAddress: Address
|
|
146
|
+
fallbackHandlerAddress: Address
|
|
147
|
+
ecdsaModuleAddress: Address
|
|
148
|
+
owner: Address
|
|
149
|
+
index?: bigint
|
|
150
|
+
}): Promise<Address> => {
|
|
151
|
+
// Build the module setup data
|
|
152
|
+
const ecdsaOwnershipInitData = encodeFunctionData({
|
|
153
|
+
abi: BiconomyInitAbi,
|
|
154
|
+
functionName: "initForSmartAccount",
|
|
155
|
+
args: [owner]
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// Build account init code
|
|
159
|
+
const initialisationData = encodeFunctionData({
|
|
160
|
+
abi: BiconomyInitAbi,
|
|
161
|
+
functionName: "init",
|
|
162
|
+
args: [
|
|
163
|
+
fallbackHandlerAddress,
|
|
164
|
+
ecdsaModuleAddress,
|
|
165
|
+
ecdsaOwnershipInitData
|
|
166
|
+
]
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
const deploymentCode = encodePacked(
|
|
170
|
+
["bytes", "uint256"],
|
|
171
|
+
[BICONOMY_PROXY_CREATION_CODE, hexToBigInt(accountLogicAddress)]
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
const salt = keccak256(
|
|
175
|
+
encodePacked(
|
|
176
|
+
["bytes32", "uint256"],
|
|
177
|
+
[keccak256(encodePacked(["bytes"], [initialisationData])), index]
|
|
178
|
+
)
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
return getContractAddress({
|
|
182
|
+
from: factoryAddress,
|
|
183
|
+
salt,
|
|
184
|
+
bytecode: deploymentCode,
|
|
185
|
+
opcode: "CREATE2"
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Build a Biconomy modular smart account from a private key, that use the ECDSA signer behind the scene
|
|
191
|
+
* @param client
|
|
192
|
+
* @param privateKey
|
|
193
|
+
* @param entryPoint
|
|
194
|
+
* @param index
|
|
195
|
+
* @param factoryAddress
|
|
196
|
+
* @param accountLogicAddress
|
|
197
|
+
* @param ecdsaModuleAddress
|
|
198
|
+
*/
|
|
199
|
+
export async function signerToBiconomySmartAccount<
|
|
200
|
+
TTransport extends Transport = Transport,
|
|
201
|
+
TChain extends Chain | undefined = Chain | undefined,
|
|
202
|
+
TSource extends string = "custom",
|
|
203
|
+
TAddress extends Address = Address
|
|
204
|
+
>(
|
|
205
|
+
client: Client<TTransport, TChain>,
|
|
206
|
+
{
|
|
207
|
+
signer,
|
|
208
|
+
entryPoint,
|
|
209
|
+
index = 0n,
|
|
210
|
+
factoryAddress = BICONOMY_ADDRESSES.FACTORY_ADDRESS,
|
|
211
|
+
accountLogicAddress = BICONOMY_ADDRESSES.ACCOUNT_V2_0_LOGIC,
|
|
212
|
+
fallbackHandlerAddress = BICONOMY_ADDRESSES.DEFAULT_FALLBACK_HANDLER_ADDRESS,
|
|
213
|
+
ecdsaModuleAddress = BICONOMY_ADDRESSES.ECDSA_OWNERSHIP_REGISTRY_MODULE
|
|
214
|
+
}: {
|
|
215
|
+
signer: SmartAccountSigner<TSource, TAddress>
|
|
216
|
+
entryPoint: Address
|
|
217
|
+
index?: bigint
|
|
218
|
+
factoryAddress?: Address
|
|
219
|
+
accountLogicAddress?: Address
|
|
220
|
+
fallbackHandlerAddress?: Address
|
|
221
|
+
ecdsaModuleAddress?: Address
|
|
222
|
+
}
|
|
223
|
+
): Promise<BiconomySmartAccount<TTransport, TChain>> {
|
|
224
|
+
// Get the private key related account
|
|
225
|
+
const viemSigner: LocalAccount = {
|
|
226
|
+
...signer,
|
|
227
|
+
signTransaction: (_, __) => {
|
|
228
|
+
throw new SignTransactionNotSupportedBySmartAccount()
|
|
229
|
+
}
|
|
230
|
+
} as LocalAccount
|
|
231
|
+
|
|
232
|
+
// Helper to generate the init code for the smart account
|
|
233
|
+
const generateInitCode = () =>
|
|
234
|
+
getAccountInitCode({
|
|
235
|
+
owner: viemSigner.address,
|
|
236
|
+
index,
|
|
237
|
+
factoryAddress,
|
|
238
|
+
ecdsaModuleAddress
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
// Fetch account address and chain id
|
|
242
|
+
const [accountAddress, chainId] = await Promise.all([
|
|
243
|
+
getAccountAddress({
|
|
244
|
+
owner: viemSigner.address,
|
|
245
|
+
ecdsaModuleAddress,
|
|
246
|
+
factoryAddress,
|
|
247
|
+
accountLogicAddress,
|
|
248
|
+
fallbackHandlerAddress,
|
|
249
|
+
index
|
|
250
|
+
}),
|
|
251
|
+
getChainId(client)
|
|
252
|
+
])
|
|
253
|
+
|
|
254
|
+
if (!accountAddress) throw new Error("Account address not found")
|
|
255
|
+
|
|
256
|
+
// Build the EOA Signer
|
|
257
|
+
const account = toAccount({
|
|
258
|
+
address: accountAddress,
|
|
259
|
+
async signMessage({ message }) {
|
|
260
|
+
return signMessage(client, { account: viemSigner, message })
|
|
261
|
+
},
|
|
262
|
+
async signTransaction(_, __) {
|
|
263
|
+
throw new SignTransactionNotSupportedBySmartAccount()
|
|
264
|
+
},
|
|
265
|
+
async signTypedData(typedData) {
|
|
266
|
+
return signTypedData(client, { account: viemSigner, ...typedData })
|
|
267
|
+
}
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
...account,
|
|
272
|
+
client: client,
|
|
273
|
+
publicKey: accountAddress,
|
|
274
|
+
entryPoint: entryPoint,
|
|
275
|
+
source: "biconomySmartAccount",
|
|
276
|
+
|
|
277
|
+
// Get the nonce of the smart account
|
|
278
|
+
async getNonce() {
|
|
279
|
+
return getAccountNonce(client, {
|
|
280
|
+
sender: accountAddress,
|
|
281
|
+
entryPoint: entryPoint
|
|
282
|
+
})
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
// Sign a user operation
|
|
286
|
+
async signUserOperation(userOperation) {
|
|
287
|
+
const hash = getUserOperationHash({
|
|
288
|
+
userOperation: {
|
|
289
|
+
...userOperation,
|
|
290
|
+
signature: "0x"
|
|
291
|
+
},
|
|
292
|
+
entryPoint: entryPoint,
|
|
293
|
+
chainId: chainId
|
|
294
|
+
})
|
|
295
|
+
const signature = await signMessage(client, {
|
|
296
|
+
account: viemSigner,
|
|
297
|
+
message: { raw: hash }
|
|
298
|
+
})
|
|
299
|
+
// userOp signature is encoded module signature + module address
|
|
300
|
+
const signatureWithModuleAddress = encodeAbiParameters(
|
|
301
|
+
parseAbiParameters("bytes, address"),
|
|
302
|
+
[signature, ecdsaModuleAddress]
|
|
303
|
+
)
|
|
304
|
+
return signatureWithModuleAddress
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
// Encode the init code
|
|
308
|
+
async getInitCode() {
|
|
309
|
+
const contractCode = await getBytecode(client, {
|
|
310
|
+
address: accountAddress
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
if ((contractCode?.length ?? 0) > 2) return "0x"
|
|
314
|
+
|
|
315
|
+
return generateInitCode()
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
// Encode the deploy call data
|
|
319
|
+
async encodeDeployCallData(_) {
|
|
320
|
+
throw new Error("Doesn't support account deployment")
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
// Encode a call
|
|
324
|
+
async encodeCallData(args) {
|
|
325
|
+
if (Array.isArray(args)) {
|
|
326
|
+
// Encode a batched call
|
|
327
|
+
const argsArray = args as {
|
|
328
|
+
to: Address
|
|
329
|
+
value: bigint
|
|
330
|
+
data: Hex
|
|
331
|
+
}[]
|
|
332
|
+
|
|
333
|
+
return encodeFunctionData({
|
|
334
|
+
abi: BiconomyExecuteAbi,
|
|
335
|
+
functionName: "executeBatch_y6U",
|
|
336
|
+
args: [
|
|
337
|
+
argsArray.map((a) => a.to),
|
|
338
|
+
argsArray.map((a) => a.value),
|
|
339
|
+
argsArray.map((a) => a.data)
|
|
340
|
+
]
|
|
341
|
+
})
|
|
342
|
+
}
|
|
343
|
+
const { to, value, data } = args as {
|
|
344
|
+
to: Address
|
|
345
|
+
value: bigint
|
|
346
|
+
data: Hex
|
|
347
|
+
}
|
|
348
|
+
// Encode a simple call
|
|
349
|
+
return encodeFunctionData({
|
|
350
|
+
abi: BiconomyExecuteAbi,
|
|
351
|
+
functionName: "execute_ncC",
|
|
352
|
+
args: [to, value, data]
|
|
353
|
+
})
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
// Get simple dummy signature for ECDSA module authorization
|
|
357
|
+
async getDummySignature() {
|
|
358
|
+
const moduleAddress =
|
|
359
|
+
BICONOMY_ADDRESSES.ECDSA_OWNERSHIP_REGISTRY_MODULE
|
|
360
|
+
const dynamicPart = moduleAddress.substring(2).padEnd(40, "0")
|
|
361
|
+
return `0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000${dynamicPart}000000000000000000000000000000000000000000000000000000000000004181d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b00000000000000000000000000000000000000000000000000000000000000`
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
package/accounts/index.ts
CHANGED
|
@@ -18,6 +18,11 @@ import {
|
|
|
18
18
|
signerToEcdsaKernelSmartAccount
|
|
19
19
|
} from "./kernel/signerToEcdsaKernelSmartAccount.js"
|
|
20
20
|
|
|
21
|
+
import {
|
|
22
|
+
type BiconomySmartAccount,
|
|
23
|
+
signerToBiconomySmartAccount
|
|
24
|
+
} from "./biconomy/signerToBiconomySmartAccount.js"
|
|
25
|
+
|
|
21
26
|
import {
|
|
22
27
|
SignTransactionNotSupportedBySmartAccount,
|
|
23
28
|
type SmartAccount,
|
|
@@ -36,5 +41,7 @@ export {
|
|
|
36
41
|
type SmartAccount,
|
|
37
42
|
privateKeyToSafeSmartAccount,
|
|
38
43
|
type KernelEcdsaSmartAccount,
|
|
39
|
-
signerToEcdsaKernelSmartAccount
|
|
44
|
+
signerToEcdsaKernelSmartAccount,
|
|
45
|
+
type BiconomySmartAccount,
|
|
46
|
+
signerToBiconomySmartAccount
|
|
40
47
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type Account,
|
|
3
2
|
type Address,
|
|
4
3
|
type Chain,
|
|
5
4
|
type Client,
|
|
6
5
|
type Hex,
|
|
6
|
+
type LocalAccount,
|
|
7
7
|
type Transport,
|
|
8
8
|
concatHex,
|
|
9
9
|
encodeFunctionData,
|
|
@@ -210,7 +210,9 @@ const getAccountAddress = async <
|
|
|
210
210
|
*/
|
|
211
211
|
export async function signerToEcdsaKernelSmartAccount<
|
|
212
212
|
TTransport extends Transport = Transport,
|
|
213
|
-
TChain extends Chain | undefined = Chain | undefined
|
|
213
|
+
TChain extends Chain | undefined = Chain | undefined,
|
|
214
|
+
TSource extends string = "custom",
|
|
215
|
+
TAddress extends Address = Address
|
|
214
216
|
>(
|
|
215
217
|
client: Client<TTransport, TChain>,
|
|
216
218
|
{
|
|
@@ -222,7 +224,7 @@ export async function signerToEcdsaKernelSmartAccount<
|
|
|
222
224
|
ecdsaValidatorAddress = KERNEL_ADDRESSES.ECDSA_VALIDATOR,
|
|
223
225
|
deployedAccountAddress
|
|
224
226
|
}: {
|
|
225
|
-
signer: SmartAccountSigner
|
|
227
|
+
signer: SmartAccountSigner<TSource, TAddress>
|
|
226
228
|
entryPoint: Address
|
|
227
229
|
index?: bigint
|
|
228
230
|
factoryAddress?: Address
|
|
@@ -232,15 +234,12 @@ export async function signerToEcdsaKernelSmartAccount<
|
|
|
232
234
|
}
|
|
233
235
|
): Promise<KernelEcdsaSmartAccount<TTransport, TChain>> {
|
|
234
236
|
// Get the private key related account
|
|
235
|
-
const viemSigner:
|
|
236
|
-
signer
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
} as Account)
|
|
243
|
-
: (signer as Account)
|
|
237
|
+
const viemSigner: LocalAccount = {
|
|
238
|
+
...signer,
|
|
239
|
+
signTransaction: (_, __) => {
|
|
240
|
+
throw new SignTransactionNotSupportedBySmartAccount()
|
|
241
|
+
}
|
|
242
|
+
} as LocalAccount
|
|
244
243
|
|
|
245
244
|
// Helper to generate the init code for the smart account
|
|
246
245
|
const generateInitCode = () =>
|
|
@@ -345,14 +344,13 @@ export async function signerToEcdsaKernelSmartAccount<
|
|
|
345
344
|
}))
|
|
346
345
|
]
|
|
347
346
|
})
|
|
348
|
-
} else {
|
|
349
|
-
// Encode a simple call
|
|
350
|
-
return encodeFunctionData({
|
|
351
|
-
abi: KernelExecuteAbi,
|
|
352
|
-
functionName: "execute",
|
|
353
|
-
args: [_tx.to, _tx.value, _tx.data, 0]
|
|
354
|
-
})
|
|
355
347
|
}
|
|
348
|
+
// Encode a simple call
|
|
349
|
+
return encodeFunctionData({
|
|
350
|
+
abi: KernelExecuteAbi,
|
|
351
|
+
functionName: "execute",
|
|
352
|
+
args: [_tx.to, _tx.value, _tx.data, 0]
|
|
353
|
+
})
|
|
356
354
|
},
|
|
357
355
|
|
|
358
356
|
// Get simple dummy signature
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type Account,
|
|
3
2
|
type Address,
|
|
4
3
|
type Chain,
|
|
5
4
|
type Client,
|
|
6
5
|
type Hex,
|
|
6
|
+
type LocalAccount,
|
|
7
7
|
type SignableMessage,
|
|
8
8
|
type Transport,
|
|
9
9
|
type TypedData,
|
|
10
10
|
type TypedDataDefinition,
|
|
11
|
+
concat,
|
|
11
12
|
concatHex,
|
|
12
13
|
encodeFunctionData,
|
|
13
14
|
encodePacked,
|
|
@@ -39,13 +40,17 @@ export type SafeVersion = "1.4.1"
|
|
|
39
40
|
const EIP712_SAFE_OPERATION_TYPE = {
|
|
40
41
|
SafeOp: [
|
|
41
42
|
{ type: "address", name: "safe" },
|
|
42
|
-
{ type: "bytes", name: "callData" },
|
|
43
43
|
{ type: "uint256", name: "nonce" },
|
|
44
|
-
{ type: "
|
|
45
|
-
{ type: "
|
|
44
|
+
{ type: "bytes", name: "initCode" },
|
|
45
|
+
{ type: "bytes", name: "callData" },
|
|
46
46
|
{ type: "uint256", name: "callGasLimit" },
|
|
47
|
+
{ type: "uint256", name: "verificationGasLimit" },
|
|
48
|
+
{ type: "uint256", name: "preVerificationGas" },
|
|
47
49
|
{ type: "uint256", name: "maxFeePerGas" },
|
|
48
50
|
{ type: "uint256", name: "maxPriorityFeePerGas" },
|
|
51
|
+
{ type: "bytes", name: "paymasterAndData" },
|
|
52
|
+
{ type: "uint48", name: "validAfter" },
|
|
53
|
+
{ type: "uint48", name: "validUntil" },
|
|
49
54
|
{ type: "address", name: "entryPoint" }
|
|
50
55
|
]
|
|
51
56
|
}
|
|
@@ -490,7 +495,9 @@ const getDefaultAddresses = (
|
|
|
490
495
|
*/
|
|
491
496
|
export async function signerToSafeSmartAccount<
|
|
492
497
|
TTransport extends Transport = Transport,
|
|
493
|
-
TChain extends Chain | undefined = Chain | undefined
|
|
498
|
+
TChain extends Chain | undefined = Chain | undefined,
|
|
499
|
+
TSource extends string = "custom",
|
|
500
|
+
TAddress extends Address = Address
|
|
494
501
|
>(
|
|
495
502
|
client: Client<TTransport, TChain>,
|
|
496
503
|
{
|
|
@@ -504,11 +511,13 @@ export async function signerToSafeSmartAccount<
|
|
|
504
511
|
multiSendAddress: _multiSendAddress,
|
|
505
512
|
multiSendCallOnlyAddress: _multiSendCallOnlyAddress,
|
|
506
513
|
saltNonce = 0n,
|
|
514
|
+
validUntil = 0,
|
|
515
|
+
validAfter = 0,
|
|
507
516
|
safeModules = [],
|
|
508
517
|
setupTransactions = []
|
|
509
518
|
}: {
|
|
510
519
|
safeVersion: SafeVersion
|
|
511
|
-
signer: SmartAccountSigner
|
|
520
|
+
signer: SmartAccountSigner<TSource, TAddress>
|
|
512
521
|
entryPoint: Address
|
|
513
522
|
addModuleLibAddress?: Address
|
|
514
523
|
safe4337ModuleAddress?: Address
|
|
@@ -517,6 +526,8 @@ export async function signerToSafeSmartAccount<
|
|
|
517
526
|
multiSendAddress?: Address
|
|
518
527
|
multiSendCallOnlyAddress?: Address
|
|
519
528
|
saltNonce?: bigint
|
|
529
|
+
validUntil?: number
|
|
530
|
+
validAfter?: number
|
|
520
531
|
setupTransactions?: {
|
|
521
532
|
to: Address
|
|
522
533
|
data: Address
|
|
@@ -527,15 +538,12 @@ export async function signerToSafeSmartAccount<
|
|
|
527
538
|
): Promise<SafeSmartAccount<TTransport, TChain>> {
|
|
528
539
|
const chainId = await getChainId(client)
|
|
529
540
|
|
|
530
|
-
const viemSigner:
|
|
531
|
-
signer
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
}
|
|
537
|
-
} as Account)
|
|
538
|
-
: (signer as Account)
|
|
541
|
+
const viemSigner: LocalAccount = {
|
|
542
|
+
...signer,
|
|
543
|
+
signTransaction: (_, __) => {
|
|
544
|
+
throw new SignTransactionNotSupportedBySmartAccount()
|
|
545
|
+
}
|
|
546
|
+
} as LocalAccount
|
|
539
547
|
|
|
540
548
|
const {
|
|
541
549
|
addModuleLibAddress,
|
|
@@ -632,8 +640,6 @@ export async function signerToSafeSmartAccount<
|
|
|
632
640
|
})
|
|
633
641
|
},
|
|
634
642
|
async signUserOperation(userOperation) {
|
|
635
|
-
// const timestamps = 0n
|
|
636
|
-
|
|
637
643
|
const signatures = [
|
|
638
644
|
{
|
|
639
645
|
signer: viemSigner.address,
|
|
@@ -648,17 +654,20 @@ export async function signerToSafeSmartAccount<
|
|
|
648
654
|
message: {
|
|
649
655
|
safe: accountAddress,
|
|
650
656
|
callData: userOperation.callData,
|
|
657
|
+
entryPoint: entryPoint,
|
|
651
658
|
nonce: userOperation.nonce,
|
|
659
|
+
initCode: userOperation.initCode,
|
|
660
|
+
maxFeePerGas: userOperation.maxFeePerGas,
|
|
661
|
+
maxPriorityFeePerGas:
|
|
662
|
+
userOperation.maxPriorityFeePerGas,
|
|
652
663
|
preVerificationGas:
|
|
653
664
|
userOperation.preVerificationGas,
|
|
654
665
|
verificationGasLimit:
|
|
655
666
|
userOperation.verificationGasLimit,
|
|
656
667
|
callGasLimit: userOperation.callGasLimit,
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
// signatureTimestamps: timestamps,
|
|
661
|
-
entryPoint: entryPoint
|
|
668
|
+
paymasterAndData: userOperation.paymasterAndData,
|
|
669
|
+
validAfter: validAfter,
|
|
670
|
+
validUntil: validUntil
|
|
662
671
|
}
|
|
663
672
|
})
|
|
664
673
|
}
|
|
@@ -670,17 +679,12 @@ export async function signerToSafeSmartAccount<
|
|
|
670
679
|
.localeCompare(right.signer.toLowerCase())
|
|
671
680
|
)
|
|
672
681
|
|
|
673
|
-
|
|
674
|
-
for (const sig of signatures) {
|
|
675
|
-
signatureBytes += sig.data.slice(2)
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
// const signatureWithTimestamps = encodePacked(
|
|
679
|
-
// ["uint96", "bytes"],
|
|
680
|
-
// [timestamps, signatureBytes]
|
|
681
|
-
// )
|
|
682
|
+
const signatureBytes = concat(signatures.map((sig) => sig.data))
|
|
682
683
|
|
|
683
|
-
return
|
|
684
|
+
return encodePacked(
|
|
685
|
+
["uint48", "uint48", "bytes"],
|
|
686
|
+
[validAfter, validUntil, signatureBytes]
|
|
687
|
+
)
|
|
684
688
|
},
|
|
685
689
|
async getInitCode() {
|
|
686
690
|
const contractCode = await getBytecode(client, {
|
|
@@ -769,7 +773,7 @@ export async function signerToSafeSmartAccount<
|
|
|
769
773
|
})
|
|
770
774
|
},
|
|
771
775
|
async getDummySignature() {
|
|
772
|
-
return "
|
|
776
|
+
return "0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
|
773
777
|
}
|
|
774
778
|
}
|
|
775
779
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type Account,
|
|
3
2
|
type Address,
|
|
4
3
|
type Chain,
|
|
5
4
|
type Client,
|
|
6
5
|
type Hex,
|
|
6
|
+
type LocalAccount,
|
|
7
7
|
type Transport,
|
|
8
8
|
concatHex,
|
|
9
9
|
encodeFunctionData
|
|
@@ -102,7 +102,9 @@ const getAccountAddress = async <
|
|
|
102
102
|
*/
|
|
103
103
|
export async function signerToSimpleSmartAccount<
|
|
104
104
|
TTransport extends Transport = Transport,
|
|
105
|
-
TChain extends Chain | undefined = Chain | undefined
|
|
105
|
+
TChain extends Chain | undefined = Chain | undefined,
|
|
106
|
+
TSource extends string = "custom",
|
|
107
|
+
TAddress extends Address = Address
|
|
106
108
|
>(
|
|
107
109
|
client: Client<TTransport, TChain>,
|
|
108
110
|
{
|
|
@@ -111,21 +113,18 @@ export async function signerToSimpleSmartAccount<
|
|
|
111
113
|
entryPoint,
|
|
112
114
|
index = 0n
|
|
113
115
|
}: {
|
|
114
|
-
signer: SmartAccountSigner
|
|
116
|
+
signer: SmartAccountSigner<TSource, TAddress>
|
|
115
117
|
factoryAddress: Address
|
|
116
118
|
entryPoint: Address
|
|
117
119
|
index?: bigint
|
|
118
120
|
}
|
|
119
121
|
): Promise<SimpleSmartAccount<TTransport, TChain>> {
|
|
120
|
-
const viemSigner:
|
|
121
|
-
signer
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
} as Account)
|
|
128
|
-
: (signer as Account)
|
|
122
|
+
const viemSigner: LocalAccount = {
|
|
123
|
+
...signer,
|
|
124
|
+
signTransaction: (_, __) => {
|
|
125
|
+
throw new SignTransactionNotSupportedBySmartAccount()
|
|
126
|
+
}
|
|
127
|
+
} as LocalAccount
|
|
129
128
|
|
|
130
129
|
const [accountAddress, chainId] = await Promise.all([
|
|
131
130
|
getAccountAddress<TTransport, TChain>({
|
package/accounts/types.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Abi,
|
|
3
|
-
type Account,
|
|
4
3
|
type Address,
|
|
5
4
|
BaseError,
|
|
6
5
|
type Client,
|
|
@@ -58,7 +57,7 @@ export type SmartAccount<
|
|
|
58
57
|
signUserOperation: (UserOperation: UserOperation) => Promise<Hex>
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
export type SmartAccountSigner<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
>
|
|
60
|
+
export type SmartAccountSigner<
|
|
61
|
+
TSource extends string,
|
|
62
|
+
TAddress extends Address = Address
|
|
63
|
+
> = Omit<LocalAccount<TSource, TAddress>, "signTransaction">
|
|
@@ -26,7 +26,7 @@ export type SponsorUserOperationMiddleware = {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export type PrepareUserOperationRequestParameters<
|
|
29
|
-
TAccount extends SmartAccount | undefined = SmartAccount | undefined
|
|
29
|
+
TAccount extends SmartAccount | undefined = SmartAccount | undefined
|
|
30
30
|
> = {
|
|
31
31
|
userOperation: PartialBy<
|
|
32
32
|
UserOperation,
|