Smart Wallet UX
Scopes & Permissions
Designing safe session scopes.
Scopes & Permissions
A Session Key is only safe if its scope is tightly defined.
1. Contract Scoping (The Allowlist)
Restrict the key to interacting with only specific contracts.
permission GameContractScope -> 1.0.0 {
parameters: {
authorizer: address,
gameContract: address
}
pub fn authorize() -> bool {
return authorizedBy(parameters.authorizer);
}
fn main() -> bool {
return context.target == parameters.gameContract;
}
}2. Function Scoping (Least Privilege)
Restrict the key to specific functions on that contract.
Demo ABI
GameActions.json is a local demo ABI for these scoping examples, not a
public protocol ABI.
import "abis/GameActions.json" as Game;
permission GameFunctionScope -> 1.0.0 {
parameters: {
authorizer: address,
gameContract: address
}
pub fn authorize() -> bool {
return authorizedBy(parameters.authorizer);
}
fn main() -> bool {
if (context.target != parameters.gameContract) {
return false;
}
if (context.selector == Game.move) {
return true;
}
return context.selector == Game.attack;
}
}3. Value Scoping (Spend Limits)
If the session involves spending tokens (e.g., buying in-game items), cap the total spend.
permission SessionSpendCap -> 1.0.0 {
parameters: {
authorizer: address,
maxSpend: uint256
}
pub fn authorize() -> bool {
return authorizedBy(parameters.authorizer);
}
fn main() -> bool {
return context.value <= parameters.maxSpend;
}
}4. Time Scoping (TTL)
Keep time-to-live checks in the account/session manager until a dedicated callable time context is added.
permission SessionExpiry -> 1.0.0 {
parameters: {
sessionKey: address
}
pub fn authorize() -> bool {
return authorizedBy(parameters.sessionKey);
}
fn main() -> bool {
return true;
}
}Stack scopes for safety
Combine contract, function, value, and time limits to build safe session keys.