Skip to content

Commit c14e598

Browse files
committed
refactor ContextBuilderUtil
1 parent 9e94417 commit c14e598

File tree

6 files changed

+502
-352
lines changed

6 files changed

+502
-352
lines changed
Lines changed: 136 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,174 @@
1-
import { Address } from 'viem'
2-
31
/**
42
* EIP7715Method
53
*/
64
export const EIP7715_METHOD = {
75
WALLET_GRANT_PERMISSIONS: 'wallet_grantPermissions'
86
}
97

10-
// `data` is not necessary for this signer type as the wallet is both the signer and grantor of these permissions
8+
export type Signer = WalletSigner | KeySigner | MultiKeySigner | AccountSigner
9+
export type KeyType = 'secp256k1' | 'secp256r1' | 'ed25519' | 'schonorr'
10+
// The types of keys that are supported for the following `key` and `keys` signer types.
11+
export enum SignerKeyType {
12+
SECP256K1 = 0, // EOA - k1
13+
SECP256R1 = 1, // Passkey - r1
14+
ED25519 = 3,
15+
SCHNORR = 4
16+
}
17+
/*
18+
* A wallet is the signer for these permissions
19+
* `data` is not necessary for this signer type as the wallet is both the signer and grantor of these permissions
20+
*/
1121
export type WalletSigner = {
1222
type: 'wallet'
13-
data: {}
23+
data: Record<string, unknown>
1424
}
1525

16-
// A signer representing a single key.
17-
// `id` is a did:key identifier and can therefore represent both Secp256k1 or Secp256r1 keys, among other key types.
26+
/*
27+
* A signer representing a single key.
28+
* "Key" types are explicitly secp256r1 (p256) or secp256k1, and the public keys are hex-encoded.
29+
*/
1830
export type KeySigner = {
1931
type: 'key'
2032
data: {
21-
id: string
33+
type: KeyType
34+
publicKey: `0x${string}`
2235
}
2336
}
2437

25-
// A signer representing a multisig signer.
26-
// Each element of `ids` is a did:key identifier just like the `key` signer.
38+
/*
39+
* A signer representing a multisig signer.
40+
* Each element of `publicKeys` are all explicitly the same `KeyType`, and the public keys are hex-encoded.
41+
*/
2742
export type MultiKeySigner = {
2843
type: 'keys'
2944
data: {
30-
ids: string[]
31-
address?: Address
45+
keys: {
46+
type: KeyType
47+
publicKey: `0x${string}`
48+
}[]
3249
}
3350
}
3451

3552
// An account that can be granted with permissions as in ERC-7710.
3653
export type AccountSigner = {
3754
type: 'account'
3855
data: {
39-
id: `0x${string}`
56+
address: `0x${string}`
4057
}
4158
}
4259

43-
export enum SignerType {
44-
EOA,
45-
PASSKEY
60+
export type Policy = {
61+
type: string
62+
data: Record<string, unknown>
4663
}
4764

48-
export type Signer = {
49-
type: SignerType
50-
data: string
65+
export type ContractCallPermission = {
66+
type: 'contract-call'
67+
data: {
68+
address: `0x${string}`
69+
functionSelector: `0x${string}`
70+
abi?: Record<string, unknown>
71+
}
72+
}
73+
// Native token transfer, e.g. ETH on Ethereum
74+
export type NativeTokenTransferPermission = {
75+
type: 'native-token-transfer'
76+
data: {
77+
allowance: `0x${string}` // hex value
78+
}
5179
}
5280

53-
export type Permission = {
54-
type: PermissionType
55-
policies: Policy[]
56-
required: boolean
57-
data: any
81+
// ERC20 token transfer
82+
export type ERC20TokenTransferPermission = {
83+
type: 'erc20-token-transfer'
84+
data: {
85+
address: `0x${string}` // erc20 contract
86+
allowance: `0x${string}` // hex value
87+
}
5888
}
59-
export type Policy = {
60-
type: PolicyType
61-
data: any
62-
}
63-
export type PermissionType =
64-
| 'native-token-transfer'
65-
| 'erc20-token-transfer'
66-
| 'erc721-token-transfer'
67-
| 'erc1155-token-transfer'
68-
| {
69-
custom: any
89+
90+
// ERC721 token transfer
91+
export type ERC721TokenTransferPermission = {
92+
type: 'erc721-token-transfer'
93+
data: {
94+
address: `0x${string}` // erc721 contract
95+
tokenIds: `0x${string}`[] // hex value array
96+
}
97+
}
98+
99+
// ERC1155 token transfer
100+
export type ERC1155TokenTransferPermission = {
101+
type: 'erc1155-token-transfer'
102+
data: {
103+
address: `0x${string}` // erc1155 contract
104+
allowances: {
105+
[tokenId: string]: `0x${string}` // hex value
70106
}
71-
export type PolicyType =
72-
| 'gas-limit'
73-
| 'call-limit'
74-
| 'rate-limit'
75-
| 'spent-limit'
76-
| 'value-limit'
77-
| 'time-frame'
78-
| 'uni-action'
79-
| 'simpler-signer'
107+
}
108+
}
109+
110+
// The maximum gas limit spent in the session in total
111+
export type GasLimitPermission = {
112+
type: 'gas-limit'
113+
data: {
114+
limit: `0x${string}` // hex value
115+
}
116+
}
117+
118+
// The number of calls the session can make in total
119+
export type CallLimitPermission = {
120+
type: 'call-limit'
121+
data: {
122+
count: `0x${string}` // hex value
123+
}
124+
}
125+
126+
// The number of calls the session can make during each interval
127+
export type RateLimitPermission = {
128+
type: 'rate-limit'
129+
data: {
130+
count: `0x${string}` //hex value: the number of times during each interval
131+
interval: `0x${string}` //hex value in seconds
132+
}
133+
}
134+
135+
// Union type for all possible permissions
136+
export type Permission =
137+
| ContractCallPermission
138+
| NativeTokenTransferPermission
139+
| ERC20TokenTransferPermission
140+
| ERC721TokenTransferPermission
141+
| ERC1155TokenTransferPermission
142+
| GasLimitPermission
143+
| CallLimitPermission
144+
| RateLimitPermission
80145
| {
81-
custom: any
146+
type: string
147+
data: Record<string, unknown>
82148
}
149+
150+
export type WalletGrantPermissionsRequest = {
151+
chainId: `0x${string}`
152+
address?: `0x${string}`
153+
expiry: number
154+
signer: Signer
155+
permissions: Permission[]
156+
policies: {
157+
type: string
158+
data: Record<string, unknown>
159+
}[]
160+
}
161+
162+
export type WalletGrantPermissionsResponse = WalletGrantPermissionsRequest & {
163+
context: `0x${string}`
164+
accountMeta?: {
165+
factory: `0x${string}`
166+
factoryData: `0x${string}`
167+
}
168+
signerMeta?: {
169+
// 7679 userOp building
170+
userOpBuilder?: `0x${string}`
171+
// 7710 delegation
172+
delegationManager?: `0x${string}`
173+
}
174+
}

advanced/wallets/react-wallet-v2/src/lib/smart-accounts/SafeSmartAccountLib.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,25 @@ import { EntryPoint } from 'permissionless/types/entrypoint'
99
import {
1010
Address,
1111
Hex,
12-
WalletGrantPermissionsParameters,
1312
createWalletClient,
1413
encodeFunctionData,
1514
getAddress,
1615
http,
1716
parseAbi,
18-
type WalletGrantPermissionsReturnType
17+
toHex
1918
} from 'viem'
2019
import { MultiKeySigner } from 'viem/_types/experimental/erc7715/types/signer'
2120
import { ModuleType } from 'permissionless/actions/erc7579'
2221
import {
2322
MOCK_VALIDATOR_ADDRESSES,
2423
TRUSTED_SMART_SESSIONS_ATTERSTER_ADDRESS
2524
} from './builders/SmartSessionUtil'
26-
import { Permission } from '@/data/EIP7715Data'
27-
import { getSmartSessionContext } from './builders/ContextBuilderUtil'
25+
import {
26+
Permission,
27+
WalletGrantPermissionsRequest,
28+
WalletGrantPermissionsResponse
29+
} from '@/data/EIP7715Data'
30+
import { getContext } from './builders/ContextBuilderUtil'
2831
import { readContract } from 'viem/actions'
2932
import { Execution, Module } from '@rhinestone/module-sdk'
3033

@@ -71,8 +74,8 @@ export class SafeSmartAccountLib extends SmartAccountLib {
7174

7275
/* 7715 method */
7376
async grantPermissions(
74-
grantPermissionsRequestParameters: WalletGrantPermissionsParameters
75-
): Promise<WalletGrantPermissionsReturnType> {
77+
grantPermissionsRequestParameters: WalletGrantPermissionsRequest
78+
): Promise<WalletGrantPermissionsResponse> {
7679
if (!this.client?.account) {
7780
throw new Error('Client not initialized')
7881
}
@@ -86,15 +89,12 @@ export class SafeSmartAccountLib extends SmartAccountLib {
8689
console.log('walletClient chainId:', walletClient.chain.id)
8790
let permissionContext = '0x'
8891
try {
89-
permissionContext = await getSmartSessionContext({
90-
walletClient,
92+
permissionContext = await getContext(walletClient, {
9193
account: getAccount({
9294
address: this.client.account.address,
9395
type: 'safe'
9496
}),
95-
permissions: [...grantPermissionsRequestParameters.permissions] as unknown as Permission[],
96-
expiry: grantPermissionsRequestParameters.expiry,
97-
signer: grantPermissionsRequestParameters.signer as MultiKeySigner
97+
grantPermissionsRequest: grantPermissionsRequestParameters
9898
})
9999
} catch (error) {
100100
console.error(`Error getting permission context: ${error}`)
@@ -103,13 +103,15 @@ export class SafeSmartAccountLib extends SmartAccountLib {
103103

104104
console.log(`Returning the permissions request`)
105105
return {
106-
permissionsContext: permissionContext,
107-
grantedPermissions: grantPermissionsRequestParameters.permissions,
108-
expiry: grantPermissionsRequestParameters.expiry,
109-
signerData: {
110-
submitToAddress: this.client.account.address
111-
}
112-
} as WalletGrantPermissionsReturnType
106+
...grantPermissionsRequestParameters,
107+
context: permissionContext as Hex,
108+
chainId: toHex(this.chain.id),
109+
accountMeta: {
110+
factory: (await this.client.account.getFactory()) || '0x',
111+
factoryData: (await this.client.account.getFactoryData()) || '0x'
112+
},
113+
expiry: grantPermissionsRequestParameters.expiry
114+
}
113115
}
114116

115117
/**

0 commit comments

Comments
 (0)