Skip to content

Commit

Permalink
refactor ContextBuilderUtil
Browse files Browse the repository at this point in the history
  • Loading branch information
KannuSingh committed Sep 24, 2024
1 parent 9e94417 commit c14e598
Show file tree
Hide file tree
Showing 6 changed files with 502 additions and 352 deletions.
180 changes: 136 additions & 44 deletions advanced/wallets/react-wallet-v2/src/data/EIP7715Data.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,174 @@
import { Address } from 'viem'

/**
* EIP7715Method
*/
export const EIP7715_METHOD = {
WALLET_GRANT_PERMISSIONS: 'wallet_grantPermissions'
}

// `data` is not necessary for this signer type as the wallet is both the signer and grantor of these permissions
export type Signer = WalletSigner | KeySigner | MultiKeySigner | AccountSigner
export type KeyType = 'secp256k1' | 'secp256r1' | 'ed25519' | 'schonorr'
// The types of keys that are supported for the following `key` and `keys` signer types.
export enum SignerKeyType {
SECP256K1 = 0, // EOA - k1
SECP256R1 = 1, // Passkey - r1
ED25519 = 3,
SCHNORR = 4
}
/*
* A wallet is the signer for these permissions
* `data` is not necessary for this signer type as the wallet is both the signer and grantor of these permissions
*/
export type WalletSigner = {
type: 'wallet'
data: {}
data: Record<string, unknown>
}

// A signer representing a single key.
// `id` is a did:key identifier and can therefore represent both Secp256k1 or Secp256r1 keys, among other key types.
/*
* A signer representing a single key.
* "Key" types are explicitly secp256r1 (p256) or secp256k1, and the public keys are hex-encoded.
*/
export type KeySigner = {
type: 'key'
data: {
id: string
type: KeyType
publicKey: `0x${string}`
}
}

// A signer representing a multisig signer.
// Each element of `ids` is a did:key identifier just like the `key` signer.
/*
* A signer representing a multisig signer.
* Each element of `publicKeys` are all explicitly the same `KeyType`, and the public keys are hex-encoded.
*/
export type MultiKeySigner = {
type: 'keys'
data: {
ids: string[]
address?: Address
keys: {
type: KeyType
publicKey: `0x${string}`
}[]
}
}

// An account that can be granted with permissions as in ERC-7710.
export type AccountSigner = {
type: 'account'
data: {
id: `0x${string}`
address: `0x${string}`
}
}

export enum SignerType {
EOA,
PASSKEY
export type Policy = {
type: string
data: Record<string, unknown>
}

export type Signer = {
type: SignerType
data: string
export type ContractCallPermission = {
type: 'contract-call'
data: {
address: `0x${string}`
functionSelector: `0x${string}`
abi?: Record<string, unknown>
}
}
// Native token transfer, e.g. ETH on Ethereum
export type NativeTokenTransferPermission = {
type: 'native-token-transfer'
data: {
allowance: `0x${string}` // hex value
}
}

export type Permission = {
type: PermissionType
policies: Policy[]
required: boolean
data: any
// ERC20 token transfer
export type ERC20TokenTransferPermission = {
type: 'erc20-token-transfer'
data: {
address: `0x${string}` // erc20 contract
allowance: `0x${string}` // hex value
}
}
export type Policy = {
type: PolicyType
data: any
}
export type PermissionType =
| 'native-token-transfer'
| 'erc20-token-transfer'
| 'erc721-token-transfer'
| 'erc1155-token-transfer'
| {
custom: any

// ERC721 token transfer
export type ERC721TokenTransferPermission = {
type: 'erc721-token-transfer'
data: {
address: `0x${string}` // erc721 contract
tokenIds: `0x${string}`[] // hex value array
}
}

// ERC1155 token transfer
export type ERC1155TokenTransferPermission = {
type: 'erc1155-token-transfer'
data: {
address: `0x${string}` // erc1155 contract
allowances: {
[tokenId: string]: `0x${string}` // hex value
}
export type PolicyType =
| 'gas-limit'
| 'call-limit'
| 'rate-limit'
| 'spent-limit'
| 'value-limit'
| 'time-frame'
| 'uni-action'
| 'simpler-signer'
}
}

// The maximum gas limit spent in the session in total
export type GasLimitPermission = {
type: 'gas-limit'
data: {
limit: `0x${string}` // hex value
}
}

// The number of calls the session can make in total
export type CallLimitPermission = {
type: 'call-limit'
data: {
count: `0x${string}` // hex value
}
}

// The number of calls the session can make during each interval
export type RateLimitPermission = {
type: 'rate-limit'
data: {
count: `0x${string}` //hex value: the number of times during each interval
interval: `0x${string}` //hex value in seconds
}
}

// Union type for all possible permissions
export type Permission =
| ContractCallPermission
| NativeTokenTransferPermission
| ERC20TokenTransferPermission
| ERC721TokenTransferPermission
| ERC1155TokenTransferPermission
| GasLimitPermission
| CallLimitPermission
| RateLimitPermission
| {
custom: any
type: string
data: Record<string, unknown>
}

export type WalletGrantPermissionsRequest = {
chainId: `0x${string}`
address?: `0x${string}`
expiry: number
signer: Signer
permissions: Permission[]
policies: {
type: string
data: Record<string, unknown>
}[]
}

export type WalletGrantPermissionsResponse = WalletGrantPermissionsRequest & {
context: `0x${string}`
accountMeta?: {
factory: `0x${string}`
factoryData: `0x${string}`
}
signerMeta?: {
// 7679 userOp building
userOpBuilder?: `0x${string}`
// 7710 delegation
delegationManager?: `0x${string}`
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,25 @@ import { EntryPoint } from 'permissionless/types/entrypoint'
import {
Address,
Hex,
WalletGrantPermissionsParameters,
createWalletClient,
encodeFunctionData,
getAddress,
http,
parseAbi,
type WalletGrantPermissionsReturnType
toHex
} from 'viem'
import { MultiKeySigner } from 'viem/_types/experimental/erc7715/types/signer'
import { ModuleType } from 'permissionless/actions/erc7579'
import {
MOCK_VALIDATOR_ADDRESSES,
TRUSTED_SMART_SESSIONS_ATTERSTER_ADDRESS
} from './builders/SmartSessionUtil'
import { Permission } from '@/data/EIP7715Data'
import { getSmartSessionContext } from './builders/ContextBuilderUtil'
import {
Permission,
WalletGrantPermissionsRequest,
WalletGrantPermissionsResponse
} from '@/data/EIP7715Data'
import { getContext } from './builders/ContextBuilderUtil'
import { readContract } from 'viem/actions'
import { Execution, Module } from '@rhinestone/module-sdk'

Expand Down Expand Up @@ -71,8 +74,8 @@ export class SafeSmartAccountLib extends SmartAccountLib {

/* 7715 method */
async grantPermissions(
grantPermissionsRequestParameters: WalletGrantPermissionsParameters
): Promise<WalletGrantPermissionsReturnType> {
grantPermissionsRequestParameters: WalletGrantPermissionsRequest
): Promise<WalletGrantPermissionsResponse> {
if (!this.client?.account) {
throw new Error('Client not initialized')
}
Expand All @@ -86,15 +89,12 @@ export class SafeSmartAccountLib extends SmartAccountLib {
console.log('walletClient chainId:', walletClient.chain.id)
let permissionContext = '0x'
try {
permissionContext = await getSmartSessionContext({
walletClient,
permissionContext = await getContext(walletClient, {
account: getAccount({
address: this.client.account.address,
type: 'safe'
}),
permissions: [...grantPermissionsRequestParameters.permissions] as unknown as Permission[],
expiry: grantPermissionsRequestParameters.expiry,
signer: grantPermissionsRequestParameters.signer as MultiKeySigner
grantPermissionsRequest: grantPermissionsRequestParameters
})
} catch (error) {
console.error(`Error getting permission context: ${error}`)
Expand All @@ -103,13 +103,15 @@ export class SafeSmartAccountLib extends SmartAccountLib {

console.log(`Returning the permissions request`)
return {
permissionsContext: permissionContext,
grantedPermissions: grantPermissionsRequestParameters.permissions,
expiry: grantPermissionsRequestParameters.expiry,
signerData: {
submitToAddress: this.client.account.address
}
} as WalletGrantPermissionsReturnType
...grantPermissionsRequestParameters,
context: permissionContext as Hex,
chainId: toHex(this.chain.id),
accountMeta: {
factory: (await this.client.account.getFactory()) || '0x',
factoryData: (await this.client.account.getFactoryData()) || '0x'
},
expiry: grantPermissionsRequestParameters.expiry
}
}

/**
Expand Down
Loading

0 comments on commit c14e598

Please sign in to comment.