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.
Files changed (64) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/accounts/biconomy/abi/BiconomySmartAccountAbi.js +102 -0
  3. package/_cjs/accounts/biconomy/abi/BiconomySmartAccountAbi.js.map +1 -0
  4. package/_cjs/accounts/biconomy/privateKeyToBiconomySmartAccount.js +15 -0
  5. package/_cjs/accounts/biconomy/privateKeyToBiconomySmartAccount.js.map +1 -0
  6. package/_cjs/accounts/biconomy/signerToBiconomySmartAccount.js +195 -0
  7. package/_cjs/accounts/biconomy/signerToBiconomySmartAccount.js.map +1 -0
  8. package/_cjs/accounts/index.js +3 -1
  9. package/_cjs/accounts/index.js.map +1 -1
  10. package/_cjs/accounts/kernel/signerToEcdsaKernelSmartAccount.js +10 -14
  11. package/_cjs/accounts/kernel/signerToEcdsaKernelSmartAccount.js.map +1 -1
  12. package/_cjs/accounts/signerToSafeSmartAccount.js +23 -20
  13. package/_cjs/accounts/signerToSafeSmartAccount.js.map +1 -1
  14. package/_cjs/accounts/signerToSimpleSmartAccount.js +5 -7
  15. package/_cjs/accounts/signerToSimpleSmartAccount.js.map +1 -1
  16. package/_cjs/accounts/types.js.map +1 -1
  17. package/_cjs/utils/deepHexlify.js +2 -2
  18. package/_cjs/utils/deepHexlify.js.map +1 -1
  19. package/_esm/accounts/biconomy/abi/BiconomySmartAccountAbi.js +105 -0
  20. package/_esm/accounts/biconomy/abi/BiconomySmartAccountAbi.js.map +1 -0
  21. package/_esm/accounts/biconomy/privateKeyToBiconomySmartAccount.js +17 -0
  22. package/_esm/accounts/biconomy/privateKeyToBiconomySmartAccount.js.map +1 -0
  23. package/_esm/accounts/biconomy/signerToBiconomySmartAccount.js +231 -0
  24. package/_esm/accounts/biconomy/signerToBiconomySmartAccount.js.map +1 -0
  25. package/_esm/accounts/index.js +2 -1
  26. package/_esm/accounts/index.js.map +1 -1
  27. package/_esm/accounts/kernel/signerToEcdsaKernelSmartAccount.js +11 -15
  28. package/_esm/accounts/kernel/signerToEcdsaKernelSmartAccount.js.map +1 -1
  29. package/_esm/accounts/signerToSafeSmartAccount.js +24 -27
  30. package/_esm/accounts/signerToSafeSmartAccount.js.map +1 -1
  31. package/_esm/accounts/signerToSimpleSmartAccount.js +5 -7
  32. package/_esm/accounts/signerToSimpleSmartAccount.js.map +1 -1
  33. package/_esm/accounts/types.js.map +1 -1
  34. package/_esm/utils/deepHexlify.js +2 -2
  35. package/_esm/utils/deepHexlify.js.map +1 -1
  36. package/_types/accounts/biconomy/abi/BiconomySmartAccountAbi.d.ts +59 -0
  37. package/_types/accounts/biconomy/abi/BiconomySmartAccountAbi.d.ts.map +1 -0
  38. package/_types/accounts/biconomy/privateKeyToBiconomySmartAccount.d.ts +13 -0
  39. package/_types/accounts/biconomy/privateKeyToBiconomySmartAccount.d.ts.map +1 -0
  40. package/_types/accounts/biconomy/signerToBiconomySmartAccount.d.ts +23 -0
  41. package/_types/accounts/biconomy/signerToBiconomySmartAccount.d.ts.map +1 -0
  42. package/_types/accounts/index.d.ts +2 -1
  43. package/_types/accounts/index.d.ts.map +1 -1
  44. package/_types/accounts/kernel/signerToEcdsaKernelSmartAccount.d.ts +2 -2
  45. package/_types/accounts/kernel/signerToEcdsaKernelSmartAccount.d.ts.map +1 -1
  46. package/_types/accounts/signerToSafeSmartAccount.d.ts +4 -2
  47. package/_types/accounts/signerToSafeSmartAccount.d.ts.map +1 -1
  48. package/_types/accounts/signerToSimpleSmartAccount.d.ts +2 -2
  49. package/_types/accounts/signerToSimpleSmartAccount.d.ts.map +1 -1
  50. package/_types/accounts/types.d.ts +2 -2
  51. package/_types/accounts/types.d.ts.map +1 -1
  52. package/_types/utils/deepHexlify.d.ts.map +1 -1
  53. package/accounts/biconomy/abi/BiconomySmartAccountAbi.ts +105 -0
  54. package/accounts/biconomy/privateKeyToBiconomySmartAccount.ts +40 -0
  55. package/accounts/biconomy/signerToBiconomySmartAccount.ts +364 -0
  56. package/accounts/index.ts +8 -1
  57. package/accounts/kernel/signerToEcdsaKernelSmartAccount.ts +17 -19
  58. package/accounts/signerToSafeSmartAccount.ts +37 -33
  59. package/accounts/signerToSimpleSmartAccount.ts +11 -12
  60. package/accounts/types.ts +4 -5
  61. package/actions/smartAccount/prepareUserOperationRequest.ts +1 -1
  62. package/package.json +1 -1
  63. package/utils/deepHexlify.test.ts +0 -2
  64. 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: Account =
236
- signer.type === "local"
237
- ? ({
238
- ...signer,
239
- signTransaction: (_, __) => {
240
- throw new SignTransactionNotSupportedBySmartAccount()
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: "uint256", name: "preVerificationGas" },
45
- { type: "uint256", name: "verificationGasLimit" },
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: Account =
531
- signer.type === "local"
532
- ? ({
533
- ...signer,
534
- signTransaction: (_, __) => {
535
- throw new SignTransactionNotSupportedBySmartAccount()
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
- maxFeePerGas: userOperation.maxFeePerGas,
658
- maxPriorityFeePerGas:
659
- userOperation.maxPriorityFeePerGas,
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
- let signatureBytes: Address = "0x"
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 signatureBytes
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 "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"
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: Account =
121
- signer.type === "local"
122
- ? ({
123
- ...signer,
124
- signTransaction: (_, __) => {
125
- throw new SignTransactionNotSupportedBySmartAccount()
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<TAddress extends Address = Address> = Omit<
62
- Account<TAddress>,
63
- "signTransaction"
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,