Skip to main content
RAMS (ERC-8226) lets a principal grant an agent a compliance-gated, value-capped mandate to move a specific asset. Caps are enforced on chain, usage is recorded, and an enforcer can freeze an agent across every mandate at once.
RAMS runs on Ethereum Sepolia (11155111) at launch, on both sandbox and production. All /x402/rams/* prepare facades default to chainId: "11155111".
Every rams.* call defaults to chainId: '11155111', so you can omit it entirely.

The actors

Set up the client

An apiKey also works for RAMS — reads, typed data, and the two client-controlled execution modes all accept one. Only brickken-relayed requires x402.

1. Check the principal is eligible

A mandate cannot be granted to an ineligible principal, so check before you spend anything.
If the principal is not yet registered, whoever holds the compliance role grants it:
grantPrincipal is role-bound: it requires msg.sender to hold the role, so it is always client-signed.

2. Grant the mandate

The four lifecycle operations — grantMandate, revokeMandate, extendMandate, setOperator — accept either authorization flow.

Direct authorization

The transaction sender authorizes on chain. This is the default.

Signature authorization

The principal signs EIP-712 off chain, so any relayer can send the transaction. Doing this by hand means fetching the typed data, signing it, and resubmitting the same parameters with the same deadline — the constraint most easily broken. authorize: 'signature' does all three steps for you.
Before signing, the SDK checks the fetched domain against the expected RAMS domain ({ name: "RAMS", version: "1" }) and refuses to sign anything else.
maxTransactionValue and maxCumulativeValue are raw base units — no decimal scaling, because the backend cannot know an arbitrary asset’s decimals. 1000000 on a 6-decimal USDC mandate is 1 USDC, not one million. Agent-token amounts, by contrast, are human-readable and scaled.

3. Register the executor’s selectors

An executor can only perform actions whose selectors are registered. This is role-bound and always client-signed.
Registering a value-bearing selector with hasAmount: false makes its transfers bypass the mandate caps entirely. Set it deliberately.

4. Dry-run before spending

canExecute answers whether a specific spend would pass right now, without touching the chain.

5. Execute under the mandate

Two paths: the transferFrom helper, or raw calldata.
execute is role-bound — msg.sender must be the agent — so it cannot be relayed.

6. Extend, revoke, freeze

Reads

Need the raw envelope rather than the automatic flow — to sign in a different process, or with hardware?
Pass the resulting signature and that exact deadline back into the lifecycle call. A fresh deadline will not verify.

What can and cannot be relayed

The second group’s on-chain call checks msg.sender against a role, so no relayer can stand in. Asking for brickken-relayed on one raises ValidationError locally rather than a 400 from the server.

RAMS reference

Actors, lifecycle, caps, and the executor setup checklist.

Namespaces

Every rams.* method and its endpoint.