Integration Guide
Architecture for integrating Matador into smart accounts and protocols.
Matador is designed to be the "permission engine" for modular smart accounts. This guide explains how to integrate the interpreter into your account implementation or use it with popular frameworks like Kernel and Safe.
Integration Lifecycle
The integration of Matador generally follows three stages:
graph LR
Deploy[1. Deployment] --> Grant[2. Provisioning]
Grant --> Enforce[3. Enforcement]- Deployment: Deploy the
PermissionInterpreterand register modules. (One-time setup per network). - Provisioning: The account owner grants a permission by storing the compiled bytecode on the account.
- Enforcement: Before executing a user transaction, the account calls
interpreter.enforce()to validate the action against the stored policy.
Base Implementation
The simplest integration is to inherit from BasePermissionAccount. This provides the storage layout and internal functions needed to manage permissions.
Inherit Base Contract
import { BasePermissionAccount } from "@matador/core/accounts/BasePermissionAccount.sol";
contract MyAccount is BasePermissionAccount {
// ...
}Implement Execution Logic
In your execution function, construct the ExecutionContext and call _enforcePermission.
function execute(
bytes32 permissionId,
address target,
uint256 value,
bytes calldata data
) external {
// 1. Build Context
IPermissionInterpreter.ExecutionContext memory exec = IPermissionInterpreter.ExecutionContext({
caller: msg.sender,
target: target,
value: value,
data: data,
gasLimit: gasleft(),
gasPrice: tx.gasprice,
nonce: 0,
blobBaseFee: block.blobbasefee,
blobGasPrice: 0
});
// 2. Enforce (Reverts on failure)
_enforcePermission(permissionId, exec);
// 3. Execute
(bool success, ) = target.call{value: value}(data);
require(success, "Execution failed");
}Modular Accounts (ERC-7579)
For modular accounts like Kernel or Safe, Matador acts as a Validation Module or Guard.
Kernel Integration
Matador can serve as a Validator or an Executor plugin.
As a Validator:
The kernel calls validateUserOp on the plugin. The plugin uses Matador to verify the session key signature and policy constraints.
As an Executor: The kernel delegates execution to the plugin. The plugin enforces the policy before performing the call.
Safe Guard
Matador integrates as a Transaction Guard.
- Deploy a
SafeMatadorGuardcontract. - Enable the guard on the Safe via
setGuard(). - Every transaction executed by the Safe is passed to
checkTransaction()on the guard. - The guard constructs the context and calls the interpreter.
ERC-4337 Session Keys
Matador is the ideal engine for ERC-4337 Session Keys.
The Flow
- UserOp Creation: The user signs a UserOp with a temporary session key.
- Validation: The
validateUserOpfunction checks that the session key is authorized and active. - Execution: The
executefunction enforces the Matador policy to ensure the session key is only performing allowed actions (e.g., swapping specific tokens).
Storage Restrictions
During validateUserOp, access to external storage is restricted by the bundler. If your policy uses stateful checks (like RATE_LIMIT_CHECK), you must enforce them during the execution phase, not the validation phase.
function validateUserOp(PackedUserOperation calldata userOp, ...) returns (uint256) {
// 1. Recover signer from userOp.signature
// 2. Verify signer corresponds to a valid permissionId
// 3. Return validation success (pay prefund)
}
function execute(bytes32 permissionId, ...) external {
// 1. Enforce Matador Policy (Full access to storage/opcodes)
interpreter.enforce(bytecode, address(this), execContext);
// 2. Perform Action
}Best Practices
- Fail Closed: Ensure that if a
permissionIddoes not exist, the transaction reverts immediately. - Gas Overhead: Complex policies add overhead. Profile your gas usage using the Matador benchmarks.
- Context Integrity: Ensure that the
caller,target, andvaluepassed to the interpreter accurately reflect the transaction about to be executed.