@zerodev/sdk 4.0.26 → 4.0.27

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 (68) hide show
  1. package/README.md +1 -693
  2. package/dist/cjs/kernel-zerodev/api/index.d.ts +2 -0
  3. package/dist/cjs/kernel-zerodev/api/index.js +18 -1
  4. package/dist/cjs/kernel-zerodev/api/index.js.map +1 -1
  5. package/dist/cjs/kernel-zerodev/owner/passkey/createPasskeyOwner.js.map +1 -1
  6. package/dist/cjs/kernel-zerodev/owner/passkey/exceptions.js +1 -1
  7. package/dist/cjs/kernel-zerodev/owner/passkey/exceptions.js.map +1 -1
  8. package/dist/cjs/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js +3 -3
  9. package/dist/cjs/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js.map +1 -1
  10. package/dist/cjs/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts +1 -1
  11. package/dist/cjs/kernel-zerodev/owner/passkey/getPasskeyOwner.js +4 -2
  12. package/dist/cjs/kernel-zerodev/owner/passkey/getPasskeyOwner.js.map +1 -1
  13. package/dist/cjs/kernel-zerodev/owner/passkey/index.d.ts +1 -1
  14. package/dist/cjs/kernel-zerodev/owner/passkey/index.js.map +1 -1
  15. package/dist/cjs/kernel-zerodev/owner/passkey/utils.js +2 -2
  16. package/dist/cjs/kernel-zerodev/owner/passkey/utils.js.map +1 -1
  17. package/dist/cjs/kernel-zerodev/provider.js +2 -2
  18. package/dist/cjs/kernel-zerodev/provider.js.map +1 -1
  19. package/dist/cjs/kernel-zerodev/validator/recovery-validator.d.ts +8 -5
  20. package/dist/cjs/kernel-zerodev/validator/recovery-validator.js +50 -9
  21. package/dist/cjs/kernel-zerodev/validator/recovery-validator.js.map +1 -1
  22. package/dist/cjs/kernel-zerodev/validator-provider/recovery-provider.js +20 -32
  23. package/dist/cjs/kernel-zerodev/validator-provider/recovery-provider.js.map +1 -1
  24. package/dist/esm/kernel-zerodev/api/index.d.ts +2 -0
  25. package/dist/esm/kernel-zerodev/api/index.js +16 -0
  26. package/dist/esm/kernel-zerodev/api/index.js.map +1 -1
  27. package/dist/esm/kernel-zerodev/owner/passkey/createPasskeyOwner.js.map +1 -1
  28. package/dist/esm/kernel-zerodev/owner/passkey/exceptions.js +1 -1
  29. package/dist/esm/kernel-zerodev/owner/passkey/exceptions.js.map +1 -1
  30. package/dist/esm/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js +3 -3
  31. package/dist/esm/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js.map +1 -1
  32. package/dist/esm/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts +1 -1
  33. package/dist/esm/kernel-zerodev/owner/passkey/getPasskeyOwner.js +4 -2
  34. package/dist/esm/kernel-zerodev/owner/passkey/getPasskeyOwner.js.map +1 -1
  35. package/dist/esm/kernel-zerodev/owner/passkey/index.d.ts +1 -1
  36. package/dist/esm/kernel-zerodev/owner/passkey/index.js +1 -1
  37. package/dist/esm/kernel-zerodev/owner/passkey/index.js.map +1 -1
  38. package/dist/esm/kernel-zerodev/owner/passkey/utils.js +2 -2
  39. package/dist/esm/kernel-zerodev/owner/passkey/utils.js.map +1 -1
  40. package/dist/esm/kernel-zerodev/provider.js +2 -2
  41. package/dist/esm/kernel-zerodev/provider.js.map +1 -1
  42. package/dist/esm/kernel-zerodev/validator/recovery-validator.d.ts +8 -5
  43. package/dist/esm/kernel-zerodev/validator/recovery-validator.js +52 -11
  44. package/dist/esm/kernel-zerodev/validator/recovery-validator.js.map +1 -1
  45. package/dist/esm/kernel-zerodev/validator-provider/recovery-provider.js +23 -32
  46. package/dist/esm/kernel-zerodev/validator-provider/recovery-provider.js.map +1 -1
  47. package/dist/types/kernel-zerodev/api/index.d.ts +2 -0
  48. package/dist/types/kernel-zerodev/api/index.d.ts.map +1 -1
  49. package/dist/types/kernel-zerodev/owner/passkey/exceptions.d.ts.map +1 -1
  50. package/dist/types/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.d.ts.map +1 -1
  51. package/dist/types/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts +1 -1
  52. package/dist/types/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts.map +1 -1
  53. package/dist/types/kernel-zerodev/owner/passkey/index.d.ts +1 -1
  54. package/dist/types/kernel-zerodev/owner/passkey/utils.d.ts.map +1 -1
  55. package/dist/types/kernel-zerodev/validator/recovery-validator.d.ts +8 -5
  56. package/dist/types/kernel-zerodev/validator/recovery-validator.d.ts.map +1 -1
  57. package/dist/types/kernel-zerodev/validator-provider/recovery-provider.d.ts.map +1 -1
  58. package/package.json +1 -1
  59. package/src/kernel-zerodev/api/index.ts +27 -0
  60. package/src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts +4 -4
  61. package/src/kernel-zerodev/owner/passkey/exceptions.ts +2 -2
  62. package/src/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.ts +11 -9
  63. package/src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts +5 -3
  64. package/src/kernel-zerodev/owner/passkey/index.ts +1 -1
  65. package/src/kernel-zerodev/owner/passkey/utils.ts +11 -6
  66. package/src/kernel-zerodev/provider.ts +2 -2
  67. package/src/kernel-zerodev/validator/recovery-validator.ts +59 -12
  68. package/src/kernel-zerodev/validator-provider/recovery-provider.ts +38 -36
package/README.md CHANGED
@@ -2,696 +2,4 @@
2
2
 
3
3
  SDK for [ZeroDev](https://docs.zerodev.app/), based on [Kernel](https://github.com/zerodevapp/kernel).
4
4
 
5
- ## Getting started
6
-
7
- Follow the instructions below to install the packages.
8
-
9
- via `yarn`
10
-
11
- ```bash
12
- yarn add @zerodev/sdk
13
- ```
14
-
15
- via `npm`
16
-
17
- ```bash
18
- npm i -s @zerodev/sdk
19
- ```
20
-
21
- ## Example Usage to Interact with [Kernel Accounts](https://github.com/zerodevapp/kernel/blob/main/src/Kernel.sol)
22
-
23
- ### Basic Usage
24
-
25
- ```ts
26
- import { ECDSAValidator } from "@zerodev/sdk";
27
- import { LocalAccountSigner } from "@alchemy/aa-core";
28
-
29
- // 1. define the EOA owner of the Smart Account
30
- // This is just one exapmle of how to interact with EOAs, feel free to use any other interface
31
- const owner = LocalAccountSigner.privateKeyToAccountSigner(PRIVATE_KEY);
32
-
33
- // 2. Create a ZeroDev Provider
34
- let ecdsaProvider = await ECDSAProvider.init({
35
- projectId, // zeroDev projectId
36
- owner,
37
- // Optional: pass the paymasterConfig to use the verifying paymaster
38
- // opts: {
39
- // paymasterConfig: {
40
- // policy: "VERIFYING_PAYMASTER"
41
- // }
42
- // }
43
- });
44
-
45
- // 3. send a UserOperation
46
- const { hash } = await ecdsaProvider.sendUserOperation({
47
- target: "0xTargetAddress",
48
- data: "0xcallData",
49
- value: 0n, // value: bigint or undefined
50
- });
51
-
52
- // 4. Wait for UserOp
53
- const tx = await ecdsaProvider.waitForUserOperationTransaction(
54
- result.hash as Hex
55
- );
56
- ```
57
-
58
- ### Batch Transactions
59
-
60
- ```ts
61
- const { hash } = await ecdsaProvider.sendUserOperation([
62
- {
63
- target: "0xTargetAddress1",
64
- data: "0xcallData1",
65
- value: 0n, // value: bigint or undefined
66
- },
67
- {
68
- target: "0xTargetAddress2",
69
- data: "0xcallData2",
70
- value: 0n, // value: bigint or undefined
71
- },
72
- ]);
73
- ```
74
-
75
- ### Optional params for ValidatorProvider:
76
-
77
- | Option | Usage | Type | Default |
78
- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- | -------------------------------------------------------------------------------- |
79
- | bundlerProvider | Bundler Provider | "ALCHEMY", "STACKUP", "PIMLICO" | "STACKUP" |
80
- | usePaymaster | Use paymaster to send userOps | boolean | true |
81
- | opts:paymasterConfig:paymasterProvider | Paymaster Provider | "ALCHEMY", "STACKUP", "PIMLICO" | "STACKUP" |
82
- | opts:paymasterConfig:onlySendSponsoredTransaction | Only send sponsored transaction and revert if somehow paymaster fails | boolean | false |
83
- | opts:paymasterConfig:policy | Paymaster policy | "TOKEN_PAYMASTER", "VERIFYING_PAYMASTER" | "VERIFYING_PAYMASTER" |
84
- | opts:paymasterConfig:gasToken | ERC20 token to use for gas fees in case of "TOKEN_PAYMASTER" | "USDC", "PEPE", "TEST_ERC20" | (Required) |
85
- | opts:providerConfig:rpcUrl | Custom RPC URL for the bundler provider | string | "https://v0-6-meta-bundler.onrender.com" |
86
- | opts:providerConfig:opts:txMaxRetries | The maximum number of times to try fetching a transaction receipt before giving up | number | 5 |
87
- | opts:providerConfig:opts:txRetryIntervalMs | The interval in milliseconds to wait between retries while waiting for tx receipts | number | 2000 |
88
- | opts:providerConfig:opts:minPriorityFeePerBid | used when computing the fees for a user operation | bigint | 100_000_000n, [Chain-wise defaults](/packages/core/src/provider/base.ts#L61-L64) |
89
- | opts:providerConfig:opts:sendTxMaxRetries | The maximum number of times to try sending a transaction before giving up | number | 3 |
90
- | opts:providerConfig:opts:sendTxRetryIntervalMs | The interval in milliseconds to wait between retries while sending a transaction | number | 180000 |
91
- | opts:accountConfig:index | Index variable to be used alongwith with owner address and validator data while calculating counterfactual address | number | 1000 |
92
- | [TODO] include other options | | | |
93
-
94
- ### Pay gas in ERC20
95
-
96
- ZeroDev currently supports:
97
-
98
- - `USDC`
99
- - `PEPE` (mainnet only)
100
- - `DAI` (upcoming)
101
-
102
- Just pass the `paymasterConfig` to `createZeroDevProvider` function while creating the provider.
103
-
104
- ```ts
105
- let ecdsaProvider = await ECDSAProvider.init({
106
- projectId, // zeroDev projectId
107
- owner,
108
- opts: {
109
- paymasterConfig: {
110
- policy: "TOKEN_PAYMASTER",
111
- gasToken: "TEST_ERC20",
112
- },
113
- },
114
- });
115
- ```
116
-
117
- ### Change Kernel Account Owner in ECDSAValidator
118
-
119
- ```ts
120
- // 1. Create a ECDSAValidatorProvider
121
- const ecdsaProvider = await ECDSAProvider.init({
122
- projectId: "c73037ef-8c0b-48be-a581-1f3d161151d3",
123
- owner,
124
- });
125
-
126
- // 2. Change the owner of the Kernel Account
127
- const { hash } = await ecdsaProvider.changeOwner(<NEW_OWNER_ADDRESS>);
128
- ```
129
-
130
- ### Via `ethers` Signer
131
-
132
- ```ts
133
- import { Wallet } from "@ethersproject/wallet";
134
- import {
135
- ZeroDevEthersProvider,
136
- convertEthersSignerToAccountSigner,
137
- } from "@zerodev/sdk";
138
-
139
- // 1. Create an ethers Wallet
140
- const owner = Wallet.fromMnemonic(OWNER_MNEMONIC);
141
-
142
- // 2. Create a ZeroDev ZeroDevEthersProvider passing the ethers Wallet as the signer
143
- const provider = await ZeroDevEthersProvider.init("ECDSA", {
144
- projectId, // zeroDev projectId
145
- owner: convertEthersSignerToAccountSigner(owner),
146
- opts: {
147
- paymasterConfig: {
148
- policy: "VERIFYING_PAYMASTER",
149
- },
150
- },
151
- });
152
-
153
- // 3. Get the AccountSigner adapter of ethers signer
154
- const signer = provider.getAccountSigner();
155
-
156
- // 4. send a UserOperation
157
- const { hash } = await signer.sendUserOperation({
158
- target: "0xTargetAddress",
159
- data: "0xcallData",
160
- value: 0n, // value: bigint or undefined
161
- });
162
- ```
163
-
164
- ### Via `viem` using `custom` transport which supports EIP-1193 providers
165
-
166
- ```ts
167
- import { createWalletClient, custom } from "viem";
168
- import { polygonMumbai } from "viem/chains";
169
- import {
170
- ECDSAProvider,
171
- convertWalletClientToAccountSigner,
172
- } from "@zerodev/sdk";
173
-
174
- // 1. Create a Viem Wallet Client using the custom transport
175
- const client = createWalletClient({
176
- chain: polygonMumbai,
177
- transport: custom(window.ethereum),
178
- });
179
-
180
- // 2. Create a ZeroDev ECDSAProvider passing the Viem Wallet Client as the signer
181
- let ecdsaProvider = await ECDSAProvider.init({
182
- projectId, // zeroDev projectId
183
- owner: convertWalletClientToAccountSigner(client),
184
- });
185
-
186
- // 3. send a UserOperation
187
- const { hash } = await ecdsaProvider.sendUserOperation({
188
- target: "0xTargetAddress",
189
- data: "0xcallData",
190
- value: 0n, // value: bigint or undefined
191
- });
192
- ```
193
-
194
- ### Using [Magic](https://magic.link/)
195
-
196
- ```ts
197
- import { ECDSAProvider, getRPCProviderOwner } from "@zerodev/sdk";
198
- import { Magic } from "magic-sdk";
199
-
200
- const magic = new Magic("MAGIC_API_KEY", {
201
- // magic config...
202
- });
203
-
204
- let ecdsaProvider = await ECDSAProvider.init({
205
- projectId, // zeroDev projectId
206
- owner: getRPCProviderOwner(magic.rpcProvider),
207
- });
208
- ```
209
-
210
- ### Using [Web3Auth](https://web3auth.io/)
211
-
212
- ```ts
213
- import { ECDSAProvider, getRPCProviderOwner } from "@zerodev/sdk";
214
- import { Web3Auth } from "@web3auth/modal";
215
-
216
- const web3auth = new Web3Auth({
217
- // web3auth config...
218
- });
219
-
220
- await web3auth.initModal();
221
-
222
- web3auth.connect();
223
-
224
- let ecdsaProvider = await ECDSAProvider.init({
225
- projectId, // zeroDev projectId
226
- owner: getRPCProviderOwner(web3auth.provider),
227
- });
228
- ```
229
-
230
- ## Using validator plugins
231
-
232
- ### Kill Switch Validator
233
-
234
- A designated guardian can "turn off" the account and set a new owner.
235
-
236
- ```ts
237
- import { constants } from "@zerodev/sdk";
238
- // 1. Get the default ecdsa validator provider
239
- const ecdsaProvider = await ECDSAProvider.init({
240
- projectId, // zeroDev projectId
241
- owner,
242
- });
243
-
244
- // 2. Deploy the Kernel account if not already by sending an empty transaction
245
- let result = await ecdsaProvider.sendUserOperation({
246
- target: "0xADDRESS",
247
- data: "0x",
248
- });
249
- await ecdsaProvider.waitForUserOperationTransaction(result.hash as Hex);
250
-
251
- // 3. Initialize required variables
252
- const accountAddress = await ecdsaProvider.getAccount().getAddress();
253
- const selector = getFunctionSelector("toggleKillSwitch()");
254
-
255
- // 4. Initialize KillSwitch Validator Provider
256
- const blockerKillSwitchProvider = await KillSwitchProvider.init({
257
- projectId, // zeroDev projectId
258
- guardian, // Guardian signer
259
- delaySeconds: 1000, // Delay in seconds
260
- opts: {
261
- accountConfig: {
262
- accountAddress,
263
- },
264
- validatorConfig: {
265
- mode: ValidatorMode.plugin,
266
- executor: constants.KILL_SWITCH_ACTION, // Address of the executor contract
267
- selector, // Function selector in the executor contract to toggleKillSwitch()
268
- },
269
- },
270
- });
271
-
272
- // 5. Get enable signature from default ECDSA validator provider and set it in KillSwitch Validator Provider
273
- const enableSig = await ecdsaProvider
274
- .getValidator()
275
- .approveExecutor(
276
- accountAddress,
277
- selector,
278
- constants.KILL_SWITCH_ACTION,
279
- 0,
280
- 0,
281
- blockerKillSwitchProvider.getValidator()
282
- );
283
-
284
- blockerKillSwitchProvider.getValidator().setEnableSignature(enableSig);
285
-
286
- // 6. Send the transaction to turn on the KillSwitch
287
- result = await blockerKillSwitchProvider.sendUserOperation({
288
- target: accountAddress,
289
- data: selector,
290
- });
291
-
292
- await blockerKillSwitchProvider.waitForUserOperationTransaction(
293
- result.hash as Hex
294
- );
295
-
296
- // 7. Get KillSwitch validator provider instance with SUDO mode
297
- const sudoModeKillSwitchProvider = await KillSwitchProvider.init({
298
- projectId, // zeroDev projectId
299
- guardian,
300
- delaySeconds: 0,
301
- opts: {
302
- accountConfig: {
303
- accountAddress,
304
- },
305
- validatorConfig: {
306
- mode: ValidatorMode.sudo,
307
- executor: KILL_SWITCH_ACTION,
308
- selector,
309
- },
310
- },
311
- });
312
-
313
- // 8. Send transaction to change the owner address
314
- const changeOwnerdata = await ecdsaProvider.getEncodedEnableData(
315
- "0xNEW_OWNER_ADDRESS"
316
- );
317
- let result = await sudoModeKillSwitchProvider.sendUserOperation({
318
- target: accountAddress,
319
- data: changeOwnerdata,
320
- });
321
-
322
- await sudoModeKillSwitchProvider.waitForUserOperationTransaction(
323
- result.hash as Hex
324
- );
325
- ```
326
-
327
- #### Force Unblock
328
-
329
- ```ts
330
- let result = await sudoModeKillSwitchProvider.sendUserOperation({
331
- target: accountAddress,
332
- data: selector,
333
- });
334
-
335
- await sudoModeKillSwitchProvider.waitForUserOperationTransaction(
336
- result.hash as Hash
337
- );
338
- ```
339
-
340
- <!--
341
- ### ERC165 Session Key Validator
342
-
343
- ```ts
344
- // 1. Get the default ecdsa validator provider
345
- const ecdsaProvider = await ECDSAProvider.init({
346
- projectId, // zeroDev projectId
347
- owner,
348
- });
349
-
350
- // 2. Deploy the Kernel account if not already by sending an empty transaction
351
- let result = await ecdsaProvider.sendUserOperation({
352
- target: "0xADDRESS",
353
- data: "0x",
354
- });
355
- await ecdsaProvider.waitForUserOperationTransaction(result.hash as Hex);
356
-
357
- // 3. Initialize required variables
358
- const accountAddress = await ecdsaProvider.getAccount().getAddress();
359
- const selector = getFunctionSelector(
360
- "transferERC721Action(address, uint256, address)"
361
- );
362
-
363
- // 4. Initialize ERC165SessionKey Validator Provider
364
- const erc165SessionKeyProvider = await ERC165SessionKeyProvider.init({
365
- projectId, // ZeroDev projectId
366
- sessionKey, // Session Key signer
367
- sessionKeyData: {
368
- selector, // Function selector in the executor contract to execute
369
- erc165InterfaceId: "0x80ac58cd", // Supported interfaceId of the contract the executor calls
370
- validAfter: 0,
371
- validUntil: 0,
372
- addressOffset: 16, // Address offest of the contract called by the executor in the calldata
373
- },
374
- opts: {
375
- accountConfig: {
376
- accountAddress,
377
- },
378
- validatorConfig: {
379
- mode: ValidatorMode.plugin,
380
- executor: constants.TOKEN_ACTION, // Address of the executor contract
381
- selector, // Function selector in the executor contract to execute
382
- },
383
- },
384
- });
385
-
386
- // 5. Get enable signature from default ECDSA validator provider and set it in ERC165SessionKey Validator Provider
387
- const enableSig = await ecdsaProvider
388
- .getValidator()
389
- .approveExecutor(
390
- accountAddress,
391
- selector,
392
- constants.TOKEN_ACTION,
393
- 0,
394
- 0,
395
- erc165SessionKeyProvider.getValidator()
396
- );
397
-
398
- erc165SessionKeyProvider.getValidator().setEnableSignature(enableSig);
399
-
400
- // 6. Send the transaction
401
- const { hash } = await erc165SessionKeyProvider.sendUserOperation({
402
- target: accountAddress,
403
- data: encodeFunctionData({
404
- abi: TokenActionsAbi,
405
- functionName: "transferERC721Action",
406
- args: ["TOKEN_ADDRESS", "TOKEN_ID", "RECIPIENT_ADDRESS"],
407
- }),
408
- });
409
- ```
410
-
411
- -->
412
-
413
- ### Session Key Validator
414
-
415
- ```ts
416
- // 1. Get the default ecdsa validator provider
417
- const ecdsaProvider = await ECDSAProvider.init({
418
- projectId, // zeroDev projectId
419
- owner,
420
- });
421
-
422
- // 2. Initialize SessionKey Validator Provider
423
- const sessionKey = LocalAccountSigner.privateKeyToAccountSigner(<SESSION_PRIVATE_KEY>);
424
- const accountAddress = await ecdsaProvider.getAccount().getAddress();
425
- const sig = getFunctionSelector(
426
- "transfer(address, uint256)"
427
- )
428
- const permissions = [
429
- {
430
- target: <ERC20Address>, // address of the target contract
431
- valueLimit: 0, // max value the session key can use in tx
432
- sig, // The function selector of the function that can be called on the target contract
433
- operation: Operation.Call, // The kind of call session key can make CALL/DELEGATECALL
434
- rules: [ // Parameter rules
435
- {
436
- condition: ParamCondition.LESS_THAN_OR_EQUAL, // The condition to check
437
- offset: 32, // The offset where the param is in the calldata
438
- param: pad(toHex(10000), { size: 32 }), // The value to check in condition
439
- },
440
- {
441
- condition: ParamCondition.EQUAL,
442
- offset: 0,
443
- param: pad(<SPECIFIC_ADDRESS>, { size: 32 }),
444
- },
445
- ],
446
- }
447
- ]
448
-
449
- const sessionKeyProvider = await SessionKeyProvider.init({
450
- projectId, //ZeroDevProject
451
- defaultProvider: ecdsaProvider, // Pass the ECDSAProvider as default provider
452
- sessionKey, // Session Key Signer
453
- sessionKeyData: {
454
- validAfter: 0,
455
- validUntil: 0,
456
- permissions,
457
- paymaster, // Paymaster Address : zeroAddress means accept userOp without paymaster, oneAddress means reject userOp without paymaster, other address means accept userOp with paymaster with the address
458
- }
459
- });
460
-
461
- // 3. Send the transaction
462
- const { hash } = await sessionKeyProvider.sendUserOperation({
463
- target: ERC20Address,
464
- data: encodeFunctionData({
465
- abi: TEST_ERC20Abi,
466
- functionName: "transfer",
467
- args: ["RECIPIENT_ADDRESS", "AMOUNT_TO_TRANSFER"],
468
- }),
469
- });
470
- ```
471
-
472
- #### Creating Session Key on the server and using it on the client side
473
-
474
- ```ts
475
- // 1. Initilize the session key provider
476
- const sessionKeyProvider = await SessionKeyProvider.init({
477
- projectId, //ZeroDevProject
478
- defaultProvider: ecdsaProvider,
479
- sessionKey, // Session Key Signer
480
- sessionKeyData: {
481
- validAfter: 0,
482
- validUntil: 0,
483
- permissions,
484
- paymaster, // Paymaster Address : zeroAddress means accept userOp without paymaster, oneAddress means reject userOp without paymaster, other address means accept userOp with paymaster with the address
485
- }
486
- });
487
-
488
- // 2. Serialize the session key params with the private key and send it to the client
489
- const serializedSessionKeyParams = await sessionKeyProvider.serializeSessionKeyParams(<SESSION_PRIVATE_KEY>);
490
-
491
- // On client side
492
- // 3. Deserialize the session key params
493
- const sessionKeyParams = SessionKeyProvider.deserializeSessionKeyParams(serializedSessionKeyParams);
494
-
495
- // 4 Initialize the SessionKey Provider from the session key params
496
- const sessionKeyProvider = await SessionKeyProvider.fromSessionKeyParams({
497
- projectId, //ZeroDevProject
498
- sessionKeyParams
499
- });
500
- ```
501
-
502
- #### Creating Session Key on the client and approving on the server
503
-
504
- ```ts
505
- // On the server
506
- // 1. Create an EmptyAccountSigner from the session key address sent from the client and pass to the provider
507
- const sessionKey = new EmptyAccountSigner(<SESSION_KEY_ADDRESS>);
508
-
509
- const sessionKeyProvider = await SessionKeyProvider.init({
510
- projectId, //ZeroDevProject
511
- defaultProvider: ecdsaProvider,
512
- sessionKey,
513
- sessionKeyData: {
514
- validAfter: 0,
515
- validUntil: 0,
516
- permissions,
517
- paymaster, // Paymaster Address : zeroAddress means accept userOp without paymaster, oneAddress means reject userOp without paymaster, other address means accept userOp with paymaster with the address
518
- }
519
- });
520
-
521
- // 2. Serialize the session key params and send it to the client
522
- const serializedSessionKeyParams = await sessionKeyProvider.serializeSessionKeyParams();
523
-
524
- // On client side
525
- // 3. Deserialize the session key params and pass the session private key to the object
526
- const sessionKeyParams = {
527
- ...SessionKeyProvider.deserializeSessionKeyParams(serializedSessionKeyParams)
528
- sessionPrivateKey
529
- }
530
-
531
- // 4. Initialize the SessionKey Provider from the session key params
532
- const sessionKeyProvider = await SessionKeyProvider.fromSessionKeyParams({
533
- projectId, //ZeroDevProject
534
- sessionKeyParams
535
- });
536
- ```
537
-
538
- ### Recovery Key Validator
539
-
540
- #### Initiate the recovery and retrieve the recoveryId
541
-
542
- ```ts
543
- // 1. Get the default ecdsa validator provider
544
- const ecdsaProvider = await ECDSAProvider.init({
545
- projectId, // zeroDev projectId
546
- owner,
547
- });
548
-
549
- // 2. Initialize the Recovery Provider
550
- const recoveryData = {
551
- guardians: { // Guardian addresses with their weights
552
- [guardianAddress]: 1,
553
- [guardian2Address]: 1,
554
- [guardian3Address]: 1,
555
- },
556
- threshold: 3,
557
- delaySeconds: 0,
558
- };
559
-
560
- const recoveryProvider = await RecoveryProvider.init({
561
- projectId,
562
- defaultProvider: ecdsaProvider,
563
- opts: {
564
- validatorConfig: {
565
- ...recoveryData,
566
- },
567
- },
568
- });
569
-
570
- // 3. Enable the recovery plugin
571
- const result = await recoveryProvider.enableRecovery();
572
- await recoveryProvider.waitForUserOperationTransaction(
573
- result.hash as Hex
574
- );
575
-
576
- // 3. Initiate the recovery
577
- const recoveryId = await recoveryProvider.initiateRecovery(<NewOwnerAddress>);
578
- ```
579
-
580
- #### Share recoveryId with the guardians to sign recoveryHash
581
-
582
- ```ts
583
- // 1. Intialize the Recovery Provider for guardian
584
- const guardian =
585
- LocalAccountSigner.privateKeyToAccountSigner(<PrivateKey>);
586
- const recoveryProvider = await RecoveryProvider.init({
587
- projectId,
588
- recoveryId,
589
- opts: {
590
- validatorConfig: {
591
- accountSigner: guardian,
592
- },
593
- },
594
- });
595
-
596
- // 2. Sign the recovery hash
597
- await recoveryProvider.signRecovery();
598
- ```
599
-
600
- #### Submit the recovery request
601
-
602
- | Anybody can submit the recovery request if they have the recoveryId
603
-
604
- ```ts
605
- // 1. Initialize the recovery provider
606
- const account = privateKeyToAccount(<PrivateKey>);
607
- const recoveryProvider = await RecoveryProvider.init({
608
- projectId,
609
- recoveryId,
610
- opts: {
611
- validatorConfig: {
612
- guardianAccountOrProvider: account,
613
- },
614
- },
615
- });
616
-
617
- // 2. Submit the recovery request
618
- const result = await recoveryProvider.submitRecovery();
619
- await recoveryProvider.waitForUserOperationTransaction(
620
- result.hash as Hex
621
- );
622
- ```
623
-
624
- #### Cancel the recovery request
625
-
626
- | Owner of the account can canel the recovery request
627
-
628
- ```ts
629
- // 1. Get the default ecdsa validator provider
630
- const ecdsaProvider = await ECDSAProvider.init({
631
- projectId, // zeroDev projectId
632
- owner,
633
- });
634
-
635
- // 2. Initialize the Recovery Provider
636
- const recoveryProvider = await RecoveryProvider.init({
637
- projectId,
638
- defaultProvider: ecdsaProvider,
639
- recoveryId,
640
- });
641
-
642
- // 3. Cancel the recovery
643
- const result = await recoveryProvider.cancelRecovery();
644
- await recoveryProvider.waitForUserOperationTransaction(result.hash as Hex);
645
- ```
646
-
647
- ## Components
648
-
649
- ### Core Components
650
-
651
- The primary interfaces are the `ZeroDevProvider`, `KernelSmartContractAccount` and `KernelBaseValidator`
652
-
653
- The `ZeroDevProvider` is an ERC-1193 compliant Provider built on top of Alchemy's `SmartAccountProvider`
654
-
655
- 1. `sendUserOperation` -- this takes in `target`, `callData`, and an optional `value` which then constructs a UserOperation (UO), sends it, and returns the `hash` of the UO. It handles estimating gas, fetching fee data, (optionally) requesting paymasterAndData, and lastly signing. This is done via a middleware stack that runs in a specific order. The middleware order is `getDummyPaymasterData` => `estimateGas` => `getFeeData` => `getPaymasterAndData`. The paymaster fields are set to `0x` by default. They can be changed using `provider.withPaymasterMiddleware`.
656
- 2. `sendTransaction` -- this takes in a traditional Transaction Request object which then gets converted into a UO. Currently, the only data being used from the Transaction Request object is `from`, `to`, `data` and `value`. Support for other fields is coming soon.
657
-
658
- `KernelSmartContractAccount` is Kernel's implementation of `BaseSmartContractAccount`. 6 main methods are implemented
659
-
660
- 1. `getDummySignature` -- this method should return a signature that will not `revert` during validation. It does not have to pass validation, just not cause the contract to revert. This is required for gas estimation so that the gas estimate are accurate.
661
- 2. `encodeExecute` -- this method should return the abi encoded function data for a call to your contract's `execute` method
662
- 3. `encodeExecuteDelegate` -- this method should return the abi encoded function data for a `delegate` call to your contract's `execute` method
663
- 4. `signMessage` -- this is used to sign UO Hashes
664
- 5. `signWithEip6492` -- this should return an ERC-191 and EIP-6492 compliant message used to personal_sign
665
- 6. `getAccountInitCode` -- this should return the init code that will be used to create an account if one does not exist. Usually this is the concatenation of the account's factory address and the abi encoded function data of the account factory's `createAccount` method.
666
-
667
- The `KernelBaseValidator` is a plugin that modify how transactions are validated. It allows for extension and implementation of arbitrary validation logic. It implements 3 main methods:
668
-
669
- 1. `getAddress` -- this returns the address of the validator
670
- 2. `getOwner` -- this returns the eligible signer's address for the active smart wallet
671
- 3. `getSignature` -- this method signs the userop hash using signer object and then concats additional params based on validator mode.
672
-
673
- ## Contributing
674
-
675
- 1. clone the repo
676
- 2. run `yarn`
677
- 3. Make changes to packages
678
-
679
- ### Adding new custom validator plugin
680
-
681
- 1. Create a new validator class that extends `KernelBaseValidator` similar to [`ECDSAValidator`](`packages/accounts/src/kernel-zerodev/validator/ecdsa-validator.ts`).
682
-
683
- 2. Make sure to pass the `validatorAddress` of your validator to the `KernelBaseValidator` base class.
684
-
685
- 3. Create a new validator provider that extends `ValidatorProvider` similar to [`ECDSAValidatorProvider`](`packages/accounts/src/kernel-zerodev/validator-provider/ecdsa-provider.ts`).
686
-
687
- 4. Use the newly created validator provider as per above examples.
688
-
689
- #### `KernelBaseValidator` methods to be implemented in your validator class
690
-
691
- - `signer()` -- this method should return the signer as per your validator's implementation. For example, for Multi-Signature validator, this method should return one of the owner signer which is connected to the multisig wallet contract and currently using the DAPP.
692
- - `getOwner()` -- this method should return the address of the signer. For example, for Multi-Signature validator, this method should return the address of the signer which is connected to the multisig wallet contract and currently using the DAPP.
693
- - `getEnableData()` -- this method should return the bytes data for the `enable` method of your validator contract. For example, in ECDSA validator, this method returns `owner` address as bytes data. This method is used to enable the validator for the first time while creating the account wallet.
694
- - `encodeEnable(enableData: Hex)` -- this method should return the abi encoded function data for the `enable` method of your validator contract. For example, in ECDSA validator, this method returns the abi encoded function data for the `enable` method with owner address as bytes param.
695
- - `encodeDisable(disableData: Hex)` -- this method should return the abi encoded function data for the `disable` method of your validator contract. For example, in ECDSA validator, this method returns the abi encoded function data for the `disable` method with empty bytes param since ECDSA Validator doesn't require any param.
696
- - `signMessage(message: Uint8Array | string | Hex)` -- this method should return the signature of the message using the connected signer.
697
- - `signUserOp(userOp: UserOperationRequest)` -- this method should return the signature of the userOp hash using the connected signer.
5
+ Documentation available [here](https://github.com/zerodevapp/sdk#zerodev-sdk).
@@ -1,3 +1,5 @@
1
+ import type { Hex } from "viem";
1
2
  export declare const getChainId: (projectId: string, backendUrl?: string) => Promise<number | undefined>;
2
3
  export declare const getRecoveryData: (recoveryId: string) => Promise<any>;
4
+ export declare const postRecoveryData: (enableData: Hex, scwAddress: Hex, recoveryConfig: string) => Promise<string | undefined>;
3
5
  export declare const setSignatures: (recoveryId: string, signatures: string) => Promise<any>;