Matador Docs
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.

On this page