Skip to main content

Overview

RAMS (ERC-8226) is Brickken’s on-chain mandate system: a principal grants an AI agent a delegated, compliance-gated, value-capped authority to act on a specific asset. The mandate lives on the AgentMandate registry, eligibility is attested by a ComplianceProvider, and executions run through a per-principal AgentExecutor that enforces the caps and records usage.
RAMS runs on Ethereum Sepolia (11155111) at launch, on both sandbox and production. All /x402/rams/* prepare facades default to chainId: "11155111".
Every write follows the standard two-step flow: prepare (unsigned transaction) → send (POST /send-transactions), with the x402 charge split evenly between the two. Most RAMS operations require msg.sender to hold a specific role, so signerAddress must be the role holder itself. The four signed lifecycle operations are the exception: a principal EIP-712 signature authorizes them, so any wallet can send the transaction.

Actors

Mandate lifecycle

A mandate’s derived status is none → revoked → pending (now < validFrom) → expired (now > validUntil) → active. Extending preserves cumulativeUsed — spent value is not reset. Freezing is an enforcement overlay: a frozen agent fails canExecute regardless of mandate state.

Two signing flows

The four lifecycle operations — grant-mandate, revoke-mandate, extend-mandate, set-operator — support two modes:
  1. Direct. The transaction sender authorizes on-chain: the principal (or, for revoke/extend, an approved operator) is signerAddress, and signature is omitted (encoded as 0x).
  2. EIP-712 signature. The principal signs a typed-data payload off-chain (domain { name: "RAMS", version: "1" }, verifying contract = AgentMandate); any wallet can then send the transaction. Fetch the payload from GET /rams/typed-data/{operation} and submit the same parameters and the same deadline with the signature at prepare time.
The per-principal EIP-712 nonce is shared by all four signed operations and increments only on signature-verified calls — direct calls do not consume it. Signatures always come from the principal, never the operator. All other operations (execute, set-executor-action, freeze-agent, unfreeze-agent, grant-principal, revoke-principal) require signerAddress to be the role holder itself.

Actions and caps

  • Actions are bytes32 values holding a left-aligned 4-byte function selector (Solidity bytes32(selector): the selector in bytes 0–3, zeros after). Everywhere an action is accepted you may pass either the full bytes32 or the bare selector (e.g. 0x23b872dd for transferFrom); the server right-pads selectors to 32 bytes.
  • Caps (maxTransactionValue, maxCumulativeValue) are denominated in the asset’s raw base units — no decimals scaling is applied, because the backend cannot know arbitrary-asset decimals. This intentionally differs from the agent-token operations’ human-readable amounts.
  • The alias "max" / "unlimited" (case-insensitive) sets a cap to 2^256-1, the contract’s “no cap” value.

Executor setup checklist

Before an agent’s execute can succeed, the operational chain must be set up in this order:
  1. Deploy or choose the per-principal AgentExecutor (Brickken’s Sepolia default is bound to the platform principal).
  2. Grant the executor RECORDER_ROLE on the AgentMandate registry so it can record usage.
  3. Register each selector with setAction (Set Executor Action).
    Registering a value-bearing selector with hasAmount: false makes its transfers bypass the mandate caps. Always set hasAmount: true and the correct amountIndex for selectors that move value.
  4. The principal calls token.approve(executor, …) on the asset — the executor moves funds via transferFrom, and the token-level allowance is not checked by the mandate.
  5. Grant a wallet ENFORCER_ROLE for freeze/unfreeze. The AgentMandate admin cannot be its own enforcer (AdminEnforcerOverlap).
  6. The compliance provider owner runs grant-principal before any grant-mandate — an ineligible principal fails the grant pre-check.
The AgentExecutor is a contract, not a wallet. It has no private key, and nobody signs “as” the executor. Calls are signed by the principal, which is the executor’s owner, and the executor then calls the registry on its own behalf. Requesting a private key for an executor address means the model has been misread.
On the shared Sandbox deployment, Brickken owns the ComplianceProvider and administers the AgentMandate registry, so steps 2 and 6 cannot be self-served. Send your principal address to tech@brickken.com and you will be given a dedicated executor bound to that principal, already holding RECORDER_ROLE, together with the identityRef registered for you.
Use that exact identityRef when granting the mandate. The AgentMandate checks it against the ComplianceProvider record, and any mismatch makes the principal ineligible.

Sepolia contracts

Each endpoint accepts an optional override (agentMandateAddress, complianceProviderAddress, executorAddress) when you run your own contracts.

Endpoint groups

Grant Mandate

Grant, revoke, extend mandates and manage operators — direct, or authorized with an EIP-712 signature.

Execute

Run agent executions through the AgentExecutor, raw calldata or the transferFrom helper.

Reads & Typed Data

Inspect mandates, dry-run executions, and fetch EIP-712 payloads to sign.

Pricing

The x402 fee is split evenly between prepare and send.