Permissions & Session Keys
All of the account contracts [Simple, Dynamic and Managed] share the same permission model. In this section, we'll describe this permission model in detail.
Account Permissions
An account recognizes only two types of actors: Session Keys and Admins.
[1] Admins
Admins have unrestricted access to the account; call any functions on the contract, use the contract without going through the ERC-4337 infrastructure (bundlers, EntryPoint, etc.), withdraw the account's native token balance, and so on.
Assigning Admin Permissions
Existing admins on the account can add new admins, remove existing admins or renounce their own admin status.
This can be done by simply calling the setAdmin
function from your account contract page:
/// @notice Adds / removes an account as an admin.
function setAdmin(address account, bool isAdmin) external;
You can also use the Wallet SDK to do it programmatically:
const smartWallet = new SmartWallet(config);
await smartWallet.addAdmin("0x...");
[2] Session Keys
Session Keys are additional authorized signers that must go through ERC-4337 infrastructure (bundlers, EntryPoint, etc.) to use an account to execute transactions. Session keys can use an account under certain restrictions.
Assigning Session Key Permissions
Each individual session key has its own permissions to use the account. Only admins can set the permissions for session keys.
Session keys can be assigned the following permissions:
- Allow interaction with specific contracts with the account.
- Have a maximum amount of native tokens that can be transferred per transaction.
- Have access to the account only during a specific time window.
These restrictions are set in the SignerPermissionsRequest
struct.
To set the permissions for a given signer, the setPermissionsForSigner
function is called.
- Wallet SDK
- React
The easiest way to manage session keys is using the Wallet SDK, in TypeScript:
const smartWallet = new SmartWallet(config);
// create and add a session key with permissions
await smartWallet.createSessionKey(
"0x...", // the session key address
{
approvedCallTargets: ["0x..."], // the addresses of contracts that the session key can call
nativeTokenLimitPerTransaction: 0.1, // the maximum amount of native token (in ETH) that the session key can spend per transaction
startDate: new Date(), // the date when the session key becomes active
expirationDate = new Date(Date.now() + 24 * 60 * 60 * 1000); // the date when the session key expires
}
);
From a React application, you can use the useCreateSessionKey
hook:
const Component = () => {
const {
mutate: createSessionKey,
isLoading,
error,
} = useCreateSessionKey();
if (error) {
console.error("failed to create session key", error);
}
return (
<button
disabled={isLoading}
onClick={() => createSessionKey(
"0x...", // the session key address
{
approvedCallTargets: ["0x..."], // the addresses of contracts that the session key can call
nativeTokenLimitPerTransaction: 0.1, // the maximum amount of native token (in ETH) that the session key can spend per transaction
startDate: new Date(), // the date when the session key becomes active
expirationDate = new Date(Date.now() + 24 * 60 * 60 * 1000); // the date when the session key expires
}
)}
>
Create Session Key
</button>
);
};
Security note:
A session key cannot have 'catch-all' permissions where they can call any target contract, or transfer any amount of native tokens. This is an important security consideration, since it is common (unfortunately) for private keys to get lost or leaked. In this way, the account encourages usage through purposeful session keys.
Even though an account may have 'recovery', having your admin keys leaked means whoever has your admin keys has unrestricted control over the smart wallet.