11import {
22 Address ,
3+ bytesToHex ,
34 concat ,
45 concatHex ,
56 createPublicClient ,
7+ getAddress ,
68 getTypesForEIP712Domain ,
79 hashTypedData ,
810 Hex ,
11+ hexToBytes ,
912 http ,
1013 keccak256 ,
1114 PrivateKeyAccount ,
@@ -14,9 +17,11 @@ import {
1417 Transport ,
1518 TypedDataDefinition ,
1619 validateTypedData ,
20+ WalletGrantPermissionsParameters ,
21+ WalletGrantPermissionsReturnType ,
1722 zeroAddress
1823} from 'viem'
19- import { privateKeyToAccount , signMessage } from 'viem/accounts'
24+ import { privateKeyToAccount , publicKeyToAddress , signMessage } from 'viem/accounts'
2025import { EIP155Wallet } from '../EIP155Lib'
2126import { JsonRpcProvider } from '@ethersproject/providers'
2227import { KernelValidator , signerToEcdsaValidator } from '@zerodev/ecdsa-validator'
@@ -44,14 +49,22 @@ import {
4449 SECP256K1_SIGNATURE_VALIDATOR_ADDRESS
4550} from '@/utils/permissionValidatorUtils/constants'
4651import { executeAbi } from '@/utils/safe7579AccountUtils/abis/Account'
47- import { ENTRYPOINT_ADDRESS_V07_TYPE } from 'permissionless/_types/types'
4852import {
4953 getPermissionScopeData ,
5054 PermissionContext ,
5155 SingleSignerPermission
5256} from '@/utils/permissionValidatorUtils'
5357import { KERNEL_V2_4 , KERNEL_V3_1 } from '@zerodev/sdk/constants'
5458import { KERNEL_V2_VERSION_TYPE , KERNEL_V3_VERSION_TYPE } from '@zerodev/sdk/types'
59+ import { decodeDIDToSecp256k1PublicKey } from '@/utils/HelperUtil'
60+ import { KeySigner } from 'viem/_types/experimental/erc7715/types/signer'
61+
62+ type DonutPurchasePermissionData = {
63+ target : string
64+ abi : any
65+ valueLimit : bigint
66+ functionName : string
67+ }
5568
5669type SmartAccountLibOptions = {
5770 privateKey : string
@@ -279,6 +292,66 @@ export class KernelSmartAccountLib implements EIP155Wallet {
279292 return serializedSessionKey
280293 }
281294
295+ async grantPermissions (
296+ grantPermissionsRequestParams : WalletGrantPermissionsParameters
297+ ) : Promise < WalletGrantPermissionsReturnType > {
298+ if ( ! this . publicClient ) {
299+ throw new Error ( 'Client not initialized' )
300+ }
301+ console . log ( 'grantPermissions' , { grantPermissionsRequestParams } )
302+
303+ const signer = grantPermissionsRequestParams . signer
304+ // check if signer type is AccountSigner then it will have data.id
305+ if ( signer && ! ( signer . type === 'key' ) ) {
306+ throw Error ( 'Currently only supporting KeySigner Type for permissions' )
307+ }
308+
309+ const typedSigner = signer as KeySigner
310+ const pubkey = decodeDIDToSecp256k1PublicKey ( typedSigner . data . id )
311+
312+ const emptySessionKeySigner = addressToEmptyAccount ( publicKeyToAddress ( pubkey as `0x${string } `) )
313+
314+ const permissions = grantPermissionsRequestParams . permissions
315+ const zeroDevPermissions = [ ]
316+
317+ for ( const permission of permissions ) {
318+ if ( permission . type === 'donut-purchase' ) {
319+ const data = permission . data as DonutPurchasePermissionData
320+ zeroDevPermissions . push ( {
321+ target : data . target ,
322+ abi : data . abi ,
323+ valueLimit : data . valueLimit ,
324+ functionName : data . functionName
325+ } )
326+ }
327+ }
328+ const sessionKeyValidator = await signerToSessionKeyValidator ( this . publicClient , {
329+ signer : emptySessionKeySigner ,
330+ validatorData : {
331+ // @ts -ignore
332+ permissions : zeroDevPermissions
333+ } ,
334+ kernelVersion : this . kernelVersion ,
335+ entryPoint : this . entryPoint
336+ } )
337+ const sessionKeyAccount = await createKernelAccount ( this . publicClient , {
338+ plugins : {
339+ sudo : this . validator ,
340+ regular : sessionKeyValidator
341+ } ,
342+ entryPoint : this . entryPoint ,
343+ kernelVersion : this . kernelVersion
344+ } )
345+
346+ const serializedSessionKey = await serializeSessionKeyAccount ( sessionKeyAccount )
347+
348+ return {
349+ permissionsContext : serializedSessionKey ,
350+ grantedPermissions : grantPermissionsRequestParams . permissions ,
351+ expiry : grantPermissionsRequestParams . expiry
352+ } as WalletGrantPermissionsReturnType
353+ }
354+
282355 async updateCoSigners ( signers : `0x${string } `[ ] ) {
283356 if ( ! this . client || ! this . publicClient || ! this . client . account ) {
284357 throw new Error ( 'Client not initialized' )
0 commit comments