Session Key Supported Permissions
Time range
Supports a start time and an end time for each session key.
Access control lists
Supports either an allowlist or a denylist for addresses. Optionally, access control lists may also specify specific functions on contracts to allow or deny.
ERC-20 spending Limits
Supports limiting how much of a specific ERC-20 token a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 100 USDC per week).
Native token spending limits
Supports limiting how much of the native token, e.g. ETH or MATIC, a key may spend. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).
Gas spending limits
Supports limiting how much of the native token (e.g. ETH or MATIC) a session key can spend on gas. This may be a total for the key, or refreshing on an interval (e.g. 1 ETH per week).
Alternatively, you can also require that a session key uses a specific paymaster address, instead of spending the account’s native token for gas.
Importance of Gas Limits
Gas spend limits are critically important to protecting the account. If you are using a session key, you should configure either a required paymaster rule or a gas spend limit. Failing to do so could allow a compromised session key to drain the account’s native token balance.
Note that the gas limit is tracked in terms of native token units (wei), not in units of gas. The gas usage of a user operation is considered to be the maximum gas a user operation can spend, i.e. total gas limit * maxFeePerGas
. This can overestimate when compared to the actual gas cost of each user operation.
Default values
Permissions start with the following default values:
Permission | Default Value |
---|---|
Access control list | Type: allowlist The list starts empty. When the allowlist is empty, all calls will be denied. |
Time range | Unlimited |
Native token spend limit | 0 This means all calls spending the native token will be denied, unless the limit is updated or removed. |
ERC-20 spend limit | Unset. If you want to enabled an ERC-20 spend limit, add the ERC-20 token contract to the access control list and set the spending limit amount. |
Gas spend limits | Unset. When defining the session key’s permissions, you should specify either a gas spending limit or a required paymaster. |
Using the PermissionsBuilder
To construct the data to set a key’s permissions, you will need to use the SessionKeyPermissionBuilder
class. This will allow you to specify a series of updates, and when complete, you may generate the encoded data to perform all updates at once.
The permissions data may be specified in 3 places:
- In the Session Key Plugin’s
onInstall
data, setting the intial permissions for a session key added at install time. - As data for the initial permissions of a session key added via
addSessionKey
. - As a parameter to the
updateKeyPermissions
function, to change the permissions of an existing key.
Generating the permissions
1 // Let's create an initial permission set for the session key giving it an eth spend limit 2 const keyPermissions = new SessionKeyPermissionsBuilder() 3 .setNativeTokenSpendLimit({ 4 spendLimit: 1000000n, 5 }) 6 // this will allow the session key plugin to interact with all addresses 7 .setContractAccessControlType(SessionKeyAccessListType.ALLOW_ALL_ACCESS) 8 .setTimeRange({ 9 validFrom: Math.round(Date.now() / 1000), 10 // valid for 1 hour 11 validUntil: Math.round(Date.now() / 1000 + 60 * 60), 12 });
Example: Permissions in plugin install data
1 const result = await client.installSessionKeyPlugin({ 2 // 1st arg is the initial set of session keys 3 // 2nd arg is the tags for the session keys 4 // 3rd arg is the initial set of permissions 5 args: [ 6 [await sessionKeySigner.getAddress()], 7 [zeroHash], 8 [keyPermissions.encode()], 9 ], 10 });
Example: Initial permissions for a new key
1 const result = await client.addSessionKey({ 2 key: "0x1234123412341234123412341234123412341234", // Session key address 3 tag: keccak256(new TextEncoder().encode("session-key-tag")), // Session key tag 4 permissions: keyPermissions.encode(), // Initial permissions 5 });
Exmaple: Updating a session key’s permissions
This example updates a key’s time range, but leaves other permissions to their current values.
1 const result = await client.updateSessionKeyPermissions({ 2 key: "0x1234123412341234123412341234123412341234", // Session key address 3 // add other permissions to the builder, if needed 4 permissions: new SessionKeyPermissionsBuilder() 5 .setTimeRange({ 6 validFrom: Math.round(Date.now() / 1000), 7 // valid for 1 hour 8 validUntil: Math.round(Date.now() / 1000 + 60 * 60), 9 }) 10 .encode(), 11 });
Permissions Builder full reference
View the full set of supported permissions here
1 import { encodeFunctionData, type Address, type Hex } from "viem"; 2 import { SessionKeyPermissionsUpdatesAbi } from "./SessionKeyPermissionsUpdatesAbi.js"; 3 4 export enum SessionKeyAccessListType { 5 ALLOWLIST = 0, 6 DENYLIST = 1, 7 ALLOW_ALL_ACCESS = 2, 8 } 9 10 export type ContractAccessEntry = { 11 // The contract address to add or remove. 12 contractAddress: Address; 13 // Whether the contract address should be on the list. 14 isOnList: boolean; 15 // Whether to check selectors for the contract address. 16 checkSelectors: boolean; 17 }; 18 19 export type ContractMethodEntry = { 20 // The contract address to add or remove. 21 contractAddress: Address; 22 // The function selector to add or remove. 23 methodSelector: Hex; 24 // Whether the function selector should be on the list. 25 isOnList: boolean; 26 }; 27 28 export type TimeRange = { 29 validFrom: number; 30 validUntil: number; 31 }; 32 33 export type NativeTokenLimit = { 34 spendLimit: bigint; 35 // The time interval over which the spend limit is enforced. If unset, there is no time 36 /// interval by which the limit is refreshed. 37 refreshInterval?: number; 38 }; 39 40 export type Erc20TokenLimit = { 41 tokenAddress: Address; 42 spendLimit: bigint; 43 // The time interval over which the spend limit is enforced. If unset, there is no time 44 /// interval by which the limit is refreshed. 45 refreshInterval?: number; 46 }; 47 48 // uint256 spendLimit, uint48 refreshInterval 49 export type GasSpendLimit = { 50 // The amount, in wei, of native tokens that a session key can spend on gas. 51 // Note that this is not the same as the gas limit for a user operation, which is measured in units of gas. 52 // This tracks gas units * gas price. 53 spendLimit: bigint; 54 // The time interval over which the spend limit is enforced. If unset, there is no time 55 /// interval by which the limit is refreshed. 56 refreshInterval?: number; 57 }; 58 59 /** 60 * A builder for creating the hex-encoded data for updating session key permissions. 61 */ 62 export class SessionKeyPermissionsBuilder { 63 private _contractAccessControlType: SessionKeyAccessListType = 64 SessionKeyAccessListType.ALLOWLIST; 65 private _contractAddressAccessEntrys: ContractAccessEntry[] = []; 66 private _contractMethodAccessEntrys: ContractMethodEntry[] = []; 67 private _timeRange?: TimeRange; 68 private _nativeTokenSpendLimit?: NativeTokenLimit; 69 private _erc20TokenSpendLimits: Erc20TokenLimit[] = []; 70 private _gasSpendLimit?: GasSpendLimit; 71 private _requiredPaymaster?: Address; 72 73 /** 74 * Sets the access control type for the contract and returns the current instance for method chaining. 75 * 76 * @example 77 * ```ts 78 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 79 * 80 * const builder = new SessionKeyPermissionsBuilder(); 81 * builder.setContractAccessControlType(SessionKeyAccessListType.ALLOWLIST); 82 * ``` 83 * 84 * @param {SessionKeyAccessListType} aclType The access control type for the session key 85 * @returns {SessionKeyPermissionsBuilder} The current instance for method chaining 86 */ 87 public setContractAccessControlType(aclType: SessionKeyAccessListType) { 88 this._contractAccessControlType = aclType; 89 return this; 90 } 91 92 /** 93 * Adds a contract access entry to the internal list of contract address access entries. 94 * 95 * @example 96 * ```ts 97 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 98 * 99 * const builder = new SessionKeyPermissionsBuilder(); 100 * builder.addContractAddressAccessEntry({ 101 * contractAddress: "0x1234", 102 * isOnList: true, 103 * checkSelectors: true, 104 * }); 105 * ``` 106 * 107 * @param {ContractAccessEntry} entry the contract access entry to be added 108 * @returns {SessionKeyPermissionsBuilder} the instance of the current class for chaining 109 */ 110 public addContractAddressAccessEntry(entry: ContractAccessEntry) { 111 this._contractAddressAccessEntrys.push(entry); 112 return this; 113 } 114 115 /** 116 * Adds a contract method entry to the `_contractMethodAccessEntrys` array. 117 * 118 * @example 119 * ```ts 120 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 121 * 122 * const builder = new SessionKeyPermissionsBuilder(); 123 * builder.addContractAddressAccessEntry({ 124 * contractAddress: "0x1234", 125 * methodSelector: "0x45678", 126 * isOnList: true, 127 * }); 128 * ``` 129 * 130 * @param {ContractMethodEntry} entry The contract method entry to be added 131 * @returns {SessionKeyPermissionsBuilder} The instance of the class for method chaining 132 */ 133 public addContractFunctionAccessEntry(entry: ContractMethodEntry) { 134 this._contractMethodAccessEntrys.push(entry); 135 return this; 136 } 137 138 /** 139 * Sets the time range for an object and returns the object itself for chaining. 140 * 141 * @example 142 * ```ts 143 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 144 * 145 * const builder = new SessionKeyPermissionsBuilder(); 146 * builder.setTimeRange({ 147 * validFrom: Date.now(), 148 * validUntil: Date.now() + (15 * 60 * 1000), 149 * }); 150 * ``` 151 * 152 * @param {TimeRange} timeRange The time range to be set 153 * @returns {SessionKeyPermissionsBuilder} The current object for method chaining 154 */ 155 public setTimeRange(timeRange: TimeRange) { 156 this._timeRange = timeRange; 157 return this; 158 } 159 160 /** 161 * Sets the native token spend limit and returns the instance for chaining. 162 * 163 * @example 164 * ```ts 165 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 166 * 167 * const builder = new SessionKeyPermissionsBuilder(); 168 * builder.setNativeTokenSpendLimit({ 169 * spendLimit: 1000000000000000000n, 170 * refreshInterval: 3600, 171 * }); 172 * ``` 173 * 174 * @param {NativeTokenLimit} limit The limit to set for native token spending 175 * @returns {SessionKeyPermissionsBuilder} The instance for chaining 176 */ 177 public setNativeTokenSpendLimit(limit: NativeTokenLimit) { 178 this._nativeTokenSpendLimit = limit; 179 return this; 180 } 181 182 /** 183 * Adds an ERC20 token spend limit to the list of limits and returns the updated object. 184 * 185 * @example 186 * ```ts 187 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 188 * 189 * const builder = new SessionKeyPermissionsBuilder(); 190 * builder.addErc20TokenSpendLimit({ 191 * tokenAddress: "0x1234", 192 * spendLimit: 1000000000000000000n, 193 * refreshInterval: 3600, 194 * }); 195 * ``` 196 * 197 * @param {Erc20TokenLimit} limit The ERC20 token spend limit to be added 198 * @returns {object} The updated object with the new ERC20 token spend limit 199 */ 200 public addErc20TokenSpendLimit(limit: Erc20TokenLimit) { 201 this._erc20TokenSpendLimits.push(limit); 202 return this; 203 } 204 205 /** 206 * Sets the gas spend limit and returns the current instance for method chaining. 207 * 208 * @example 209 * ```ts 210 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 211 * 212 * const builder = new SessionKeyPermissionsBuilder(); 213 * builder.setGasSpendLimit({ 214 * spendLimit: 1000000000000000000n, 215 * refreshInterval: 3600, 216 * }); 217 * ``` 218 * 219 * @param {GasSpendLimit} limit - The gas spend limit to be set 220 * @returns {SessionKeyPermissionsBuilder} The current instance for chaining 221 */ public setGasSpendLimit(limit: GasSpendLimit) { 222 this._gasSpendLimit = limit; 223 return this; 224 } 225 226 /** 227 * Sets the required paymaster address. 228 * 229 * @example 230 * ```ts 231 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 232 * 233 * const builder = new SessionKeyPermissionsBuilder(); 234 * builder.setRequiredPaymaster("0x1234"); 235 * ``` 236 * 237 * @param {Address} paymaster the address of the paymaster to be set 238 * @returns {SessionKeyPermissionsBuilder} the current instance for method chaining 239 */ 240 public setRequiredPaymaster(paymaster: Address) { 241 this._requiredPaymaster = paymaster; 242 return this; 243 } 244 245 /** 246 * Encodes various function calls into an array of hexadecimal strings based on the provided permissions and limits. 247 * 248 * @example 249 * ```ts 250 * import { SessionKeyPermissionsBuilder } from "@account-kit/smart-contracts"; 251 * 252 * const builder = new SessionKeyPermissionsBuilder(); 253 * builder.setRequiredPaymaster("0x1234"); 254 * const encoded = builder.encode(); 255 * ``` 256 * 257 * @returns {Hex[]} An array of encoded hexadecimal strings representing the function calls for setting access control, permissions, and limits. 258 */ 259 public encode(): Hex[] { 260 return [ 261 encodeFunctionData({ 262 abi: SessionKeyPermissionsUpdatesAbi, 263 functionName: "setAccessListType", 264 args: [this._contractAccessControlType], 265 }), 266 ...this._contractAddressAccessEntrys.map((entry) => 267 encodeFunctionData({ 268 abi: SessionKeyPermissionsUpdatesAbi, 269 functionName: "updateAccessListAddressEntry", 270 args: [entry.contractAddress, entry.isOnList, entry.checkSelectors], 271 }) 272 ), 273 ...this._contractMethodAccessEntrys.map((entry) => 274 encodeFunctionData({ 275 abi: SessionKeyPermissionsUpdatesAbi, 276 functionName: "updateAccessListFunctionEntry", 277 args: [entry.contractAddress, entry.methodSelector, entry.isOnList], 278 }) 279 ), 280 this.encodeIfDefined( 281 (timeRange) => 282 encodeFunctionData({ 283 abi: SessionKeyPermissionsUpdatesAbi, 284 functionName: "updateTimeRange", 285 args: [timeRange.validFrom, timeRange.validUntil], 286 }), 287 this._timeRange 288 ), 289 this.encodeIfDefined( 290 (nativeSpendLimit) => 291 encodeFunctionData({ 292 abi: SessionKeyPermissionsUpdatesAbi, 293 functionName: "setNativeTokenSpendLimit", 294 args: [ 295 nativeSpendLimit.spendLimit, 296 nativeSpendLimit.refreshInterval ?? 0, 297 ], 298 }), 299 this._nativeTokenSpendLimit 300 ), 301 ...this._erc20TokenSpendLimits.map((erc20SpendLimit) => 302 encodeFunctionData({ 303 abi: SessionKeyPermissionsUpdatesAbi, 304 functionName: "setERC20SpendLimit", 305 args: [ 306 erc20SpendLimit.tokenAddress, 307 erc20SpendLimit.spendLimit, 308 erc20SpendLimit.refreshInterval ?? 0, 309 ], 310 }) 311 ), 312 this.encodeIfDefined( 313 (spendLimit) => 314 encodeFunctionData({ 315 abi: SessionKeyPermissionsUpdatesAbi, 316 functionName: "setGasSpendLimit", 317 args: [spendLimit.spendLimit, spendLimit.refreshInterval ?? 0], 318 }), 319 this._gasSpendLimit 320 ), 321 this.encodeIfDefined( 322 (paymaster) => 323 encodeFunctionData({ 324 abi: SessionKeyPermissionsUpdatesAbi, 325 functionName: "setRequiredPaymaster", 326 args: [paymaster], 327 }), 328 this._requiredPaymaster 329 ), 330 ].filter((x) => x !== "0x"); 331 } 332 333 private encodeIfDefined<T>(encode: (param: T) => Hex, param?: T): Hex { 334 if (!param) return "0x"; 335 336 return encode(param); 337 } 338 }
Reading Permissions
You may wish to view the current permissions of a given session key. This can be done using view functions defined by the Session Key Plugin.
Here’s an example of viewing all permissions in TypeScript:
1 const sessionKeyPluginView = SessionKeyPlugin.getContract(client).read; 2 const accountAddress = client.getAddress(); 3 const sessionKeyAddress = await sessionKeySigner.getAddress(); 4 5 const exampleTargetAddress = "0x4567456745674567456745674567456745674567"; 6 const exampleTargetSelector = "0x78907890"; 7 const exampleERC20Address = "0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"; 8 9 // Using session key permissions view functions 10 11 // The key's current access control type. One of: 12 // - SessionKeyAccessListType.ALLOWLIST 13 // - SessionKeyAccessListType.DENYLIST 14 // - SessionKeyAccessListType.ALLOW_ALL_ACCESS 15 const accessControlType = await sessionKeyPluginView.getAccessControlType([ 16 accountAddress, 17 sessionKeyAddress, 18 ]); 19 20 // - Whether or not the address is on the access control list (either allowlist or denylist, depending on setting). 21 // - Whether or not the function selectors should be checked for the target address (checked according to the access control type). 22 const [isTargetAddressOnList, checkSelectors] = 23 await sessionKeyPluginView.getAccessControlEntry([ 24 accountAddress, 25 sessionKeyAddress, 26 exampleTargetAddress, 27 ]); 28 29 // Whether or not the selector is on the access control list 30 const isTargetSelectorOnList = 31 await sessionKeyPluginView.isSelectorOnAccessControlList([ 32 accountAddress, 33 sessionKeyAddress, 34 exampleTargetAddress, 35 exampleTargetSelector, 36 ]); 37 38 // The start and end timestamp of a key. 39 // If either is zero, that means the value is unset. 40 const [validAfter, validUntil] = await sessionKeyPluginView.getKeyTimeRange([ 41 accountAddress, 42 sessionKeyAddress, 43 ]); 44 45 // The native token spending limit of a key. Details below 46 const nativeTokenSpendingLimit = 47 await sessionKeyPluginView.getNativeTokenSpendLimitInfo([ 48 accountAddress, 49 sessionKeyAddress, 50 ]); 51 52 const { 53 hasLimit: hasNativeTokenSpendLimit, // Whether or not a native token spending limit is enforced on the session key 54 limit: nativeTokenSpendLimit, // The limit's maximum value. If a refresh interval is set, this is the max per interval. 55 limitUsed: nativeTokenSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval. 56 refreshInterval: nativeTokenRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit. 57 lastUsedTime: nativeTokenLastUsedTime, // The start of the latest interval, if using the refresh interval. 58 } = nativeTokenSpendingLimit; 59 60 // The spending limit for an ERC-20 token. 61 const erc20SpendingLimit = await sessionKeyPluginView.getERC20SpendLimitInfo([ 62 accountAddress, 63 sessionKeyAddress, 64 exampleERC20Address, 65 ]); 66 67 const { 68 hasLimit: hasErc20TokenSpendLimit, // Whether or not an ERC-20 token spending limit is enforced on the session key for this token address. 69 limit: erc20TokenSpendLimit, // The limit's maximum value. If a refresh interval is set, this is the max per interval. 70 limitUsed: erc20TokenSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval. 71 refreshInterval: erc20TokenRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit. 72 lastUsedTime: erc20TokenLastUsedTime, // The start of the latest interval, if using the refresh interval. 73 } = erc20SpendingLimit; 74 75 // - The spending limit on gas for a given session key, measured in wei. 76 // - Whether or not the spending limit will reset in the next interval, if a refresh interval is set. 77 const [gasSpendingLimit, shouldReset] = 78 await sessionKeyPluginView.getGasSpendLimit([ 79 accountAddress, 80 sessionKeyAddress, 81 ]); 82 83 const { 84 hasLimit: hasGasSpendLimit, // Whether or not a gas spending limit is enforced on the session key 85 limit: gasSpendLimit, // The gas limit's maximum spend amount, in wei. If a refresh interval is set, this is the max per interval. 86 limitUsed: gasSpendLimitUsed, // How much of the limit is used. If a refresh interval is set, this is the amount used in the current interval. 87 refreshInterval: gasRefreshInterval, // How often to reset the limit and start counting again. If zero, never refresh the limit. 88 lastUsedTime: gasLastUsedTime, // The start of the latest interval, if using the refresh interval. 89 } = gasSpendingLimit; 90 91 // The paymaster address required for a given session key. 92 // If there is no required paymaster, this will return the zero address. 93 const requiredPaymaster = await sessionKeyPluginView.getRequiredPaymaster([ 94 accountAddress, 95 sessionKeyAddress, 96 ]);
Permission View Functions
The following view functions are declared by the session key plugin and used to read information about permissions. These are the functions used in the example above.
1 enum ContractAccessControlType { 2 ALLOWLIST, // Allowlist is default 3 DENYLIST, 4 ALLOW_ALL_ACCESS // Disables contract access control, any address and selector are allowed. 5 } 6 7 // Struct returned by view functions to provide information about a session key's spend limit. 8 // Used for native token, ERC-20, and gas spend limits. 9 struct SpendLimitInfo { 10 bool hasLimit; 11 uint256 limit; 12 uint256 limitUsed; 13 uint48 refreshInterval; 14 uint48 lastUsedTime; 15 } 16 17 /// @notice Get the access control type for a session key on an account. 18 /// @param account The account to check. 19 /// @param sessionKey The session key to check. 20 /// @return The access control type for the session key on the account. 21 function getAccessControlType(address account, address sessionKey) 22 external 23 view 24 returns (ContractAccessControlType); 25 26 /// @notice Get an access control entry for a session key on an account. 27 /// @param account The account to check. 28 /// @param sessionKey The session key to check. 29 /// @param targetAddress The target address to check. 30 /// @return isOnList Whether the target address is on the list (either allowlist or blocklist depending on the 31 /// access control type). 32 /// @return checkSelectors Whether the target address should be checked for selectors during permissions 33 /// enforcement. 34 function getAccessControlEntry(address account, address sessionKey, address targetAddress) 35 external 36 view 37 returns (bool isOnList, bool checkSelectors); 38 39 /// @notice Get whether a selector is on the access control list for a session key on an account. 40 /// @param account The account to check. 41 /// @param sessionKey The session key to check. 42 /// @param targetAddress The target address to check. 43 /// @param selector The selector to check. 44 /// @return isOnList Whether the selector is on the list (either allowlist or blocklist depending on the 45 /// access control type). 46 function isSelectorOnAccessControlList( 47 address account, 48 address sessionKey, 49 address targetAddress, 50 bytes4 selector 51 ) external view returns (bool isOnList); 52 53 /// @notice Get the active time range for a session key on an account. 54 /// @param account The account to check. 55 /// @param sessionKey The session key to check. 56 /// @return validAfter The time after which the session key is valid. 57 /// @return validUntil The time until which the session key is valid. 58 function getKeyTimeRange(address account, address sessionKey) 59 external 60 view 61 returns (uint48 validAfter, uint48 validUntil); 62 63 /// @notice Get the native token spend limit for a session key on an account. 64 /// @param account The account to check. 65 /// @param sessionKey The session key to check. 66 /// @return A struct with fields describing the state of native token spending limits on this session key. 67 function getNativeTokenSpendLimitInfo(address account, address sessionKey) 68 external 69 view 70 returns (SpendLimitInfo memory); 71 72 /// @notice Get the gas spend limit for a session key on an account. 73 /// Note that this spend limit is measured in wei, not units of gas. 74 /// @param account The account to check. 75 /// @param sessionKey The session key to check. 76 /// @return info A struct with fields describing the state of gas spending limits on this session key. 77 /// @return shouldReset Whether this session key must be reset by calling `resetSessionKeyGasLimitTimestamp` 78 /// before it can be used. 79 function getGasSpendLimit(address account, address sessionKey) 80 external 81 view 82 returns (SpendLimitInfo memory info, bool shouldReset); 83 84 /// @notice Get the ERC20 spend limit for a session key on an account. 85 /// @param account The account to check. 86 /// @param sessionKey The session key to check. 87 /// @param token The token to check. 88 /// @return A struct with fields describing the state of ERC20 spending limits on this session key. 89 function getERC20SpendLimitInfo(address account, address sessionKey, address token) 90 external 91 view 92 returns (SpendLimitInfo memory); 93 94 /// @notice Get the required paymaster address for a session key on an account, if any. 95 /// @param account The account to check. 96 /// @param sessionKey The session key to check. 97 /// @return The required paymaster address for this session key on this account, or the zero address if the 98 /// rule is disabled. 99 function getRequiredPaymaster(address account, address sessionKey) external view returns (address);