← Blog
July 15, 2026 · 10 min

Account abstraction for agent wallets: session keys and spend caps

An autonomous agent holding a raw private key has exactly one spending limit: your entire balance. Account abstraction turns that limit into a policy you can write down, scope, and revoke.

We have spent the last three posts on the payment rail: how EIP-3009 moves stablecoins gaslessly, how the A2A x402 extension drives a payment state machine, and how MCP authorization binds an agent's identity to a token. Every one of those posts repeated the same rule: keys stay outside the LLM. This post is about the layer underneath that rule — the account itself, and what stops a compromised agent from draining it.

The EOA is the wrong default

Most early agent deployments give the agent an externally owned account. An EOA is a keypair. The private key is the authority. Whoever holds it can send any transaction, to any address, for any amount, forever. There is no spending cap, no recipient allowlist, no expiry, no time delay.

For a human, that is tolerable. You sign transactions one at a time and you notice when something is wrong. An autonomous agent does not sign one at a time. It runs unattended, calls tools, follows plans, and processes untrusted input. A single prompt injection, a poisoned tool result, or a leaked environment variable and the attacker has the same authority the agent had — which, with an EOA, is all of it.

The fix is not "guard the key harder." It is to make the key structurally incapable of spending more than it should. That is what account abstraction provides: the account is a smart contract, and the smart contract enforces policy before any transfer settles.

ERC-4337 in one paragraph

ERC-4337 replaces the EOA with a contract account. Instead of a raw transaction, the agent emits a UserOperation — a pseudo-transaction that flows through a bundler to a singleton EntryPoint contract. The EntryPoint calls the account's own validation logic before execution. That validation step is the hook: it is where a smart account checks a signature, checks a spending limit, checks a recipient, and reverts if the call is out of bounds. Policy lives in the contract, not in the application code the agent is running. EIP-7702, shipped with Ethereum's Pectra upgrade in May 2025, lets an ordinary EOA delegate to contract code as well, so the same machinery now reaches accounts that were never deployed as smart wallets.

The shift — with an EOA, spending policy is a promise the application makes. With a smart account, spending policy is a check the chain enforces. A compromised agent can still try to overspend; the transaction simply reverts.

Session keys: authority without custody

A session key is a second signing key that the smart account authorizes for a narrow purpose. The agent signs with the session key. The account validates that key against a stored permission record and executes only if the action fits the scope. The main key is never exposed to the agent's runtime.

The important structural property, spelled out plainly in MetaMask's Delegation Toolkit, is that the session account holds no funds. It is a signing key, not a custody point. Execution happens by redeeming a delegation against the user's main smart account. The agent can act; the agent cannot walk away with the balance, because the balance was never under the session key's control.

This is the on-chain mirror of the keys-outside-the-LLM rule. The model plans and calls tools. A scoped session key, holding nothing, signs the specific action. The funded account stays behind a contract that will reject anything outside the grant.

ERC-7715 and ERC-7710: the grant standard

Two draft standards turn this from a bespoke integration into a wallet-level API. ERC-7715 defines the request side — a JSON-RPC method, wallet_requestExecutionPermissions, that an application uses to ask a wallet for a scoped, time-bounded permission. ERC-7710 defines the contract side — how the account exposes those permissions and how they are redeemed through a delegation manager.

The request shape is deliberately small. A permission request carries the chain, the account, the signer receiving authority, and a permission object whose type and data are defined per use case:

// ERC-7715 permission request (shape, simplified)
{
  chainId: '0x2105',          // Base
  from: '0xUserSmartAccount',
  permission: {
    type: 'erc20-token-periodic',
    isAdjustmentAllowed: true,   // wallet may tighten before signing
    data: {
      token: '0xUSDC',
      periodAmount: '10000000',     // 10 USDC (6 decimals)
      periodDuration: 86400,        // per day
      startTime: 1752537600,
      expiry: 1755129600
    }
  }
}

The wallet renders a human-readable screen from that object. It may let the user tighten the numbers before approving — unless the app sets isAdjustmentAllowed: false, in which case the wallet must present the request exactly or reject it. The response adds a context blob, the delegationManager address, and any deployment dependencies. That context is the credential the app replays each time it executes.

MetaMask's canonical example is a dollar-cost-average agent: approve, once, a permission to spend up to 10 USDC over the next hour against a single contract. No per-transaction popup after that. On-chain, caveat enforcers validate every redemption; a call outside the granted scope is rejected by the account itself.

One property matters for multi-agent systems: attenuation. A permission can be re-issued under tighter scope before it is handed to a sub-component. A parent grant of "$500 daily on this DEX" can be narrowed to "$50 on this one swap" and delegated down to a task agent. The budget flows downhill and only ever shrinks — the same shape as the delegation chains we described in the agent security threat model.

Coinbase Spend Permissions: the recurring-allowance primitive

Coinbase's Spend Permissions ships the same idea as a concrete, audited contract, and its data structure is worth reading because it is the clearest statement of what an agent budget actually is:

struct SpendPermission {
  address account;    // user's smart wallet
  address spender;    // the agent / app
  address token;      // ETH or ERC-20, e.g. USDC
  uint160 allowance;  // per-period cap, smallest unit
  uint48  period;     // seconds; resets each period
  uint48  start;
  uint48  end;
  uint256 salt;
  bytes   extraData;
}

A single SpendPermissionManager singleton tracks approvals and enforces accounting. As the spender pulls funds, the manager increments usage against the current period; once the clock crosses into the next period, usage resets to zero and the allowance refreshes. Set the period to span the whole window and you get a one-shot allowance instead. The user signs the struct with eth_signTypedData; any account implementing ERC-1271 can be a grantor. Revocation is a single revoke call, batchable, available at any time.

There is a pointed design decision here. Spend Permissions add the manager as a modular owner of the wallet rather than routing through the ERC-4337 EntryPoint. The stated reason: it avoids letting a paymaster spend the user's tokens on gas, and it keeps the scope of account control tight and fully known. Two credible teams, two enforcement paths — MetaMask through caveat enforcers, Coinbase through a manager singleton — and the same observable guarantee: the wallet, not the app, enforces the cap.

Paymasters: paying gas in the currency the agent already holds

An agent that settles inference in USDC should not have to keep a separate ETH balance just to pay gas. Paymasters solve exactly this. When a UserOperation names a paymaster, the EntryPoint pulls the gas prefund from the paymaster's deposit instead of the sender, calls the paymaster's validation, and settles up in a post-execution hook. Two modes matter:

For an autonomous fleet this collapses an operational headache. One funded currency, one balance to monitor, gas abstracted away — the same simplification x402 brought to the HTTP layer, now at the settlement layer.

The frontier: policy that travels with the asset

Every mechanism above binds policy to an account or a session key. A newer proposal argues that is still one level too high. Posted to Ethereum Magicians on June 18, 2026, the asset-enforced spend mandate puts the guardrail on the token itself. Its ISpendGate interface exposes isGated (does this address carry a mandate) and checkTransfer (is this specific transfer allowed), returning machine-readable reason codes — REVOKED, EXPIRED, OVER_TX_CAP, TOKEN_NOT_ALLOWED — instead of a bare revert. It is an early discussion draft, not a finalized ERC. But the direction is telling: as agents multiply, the ecosystem keeps pushing the spending limit closer to the money.

How this maps to x402 and EIP-3009

It is worth being precise about layers, because they are complementary, not competing. EIP-3009 and x402 are the settlement authorization for a single payment: this exact amount, to this exact payee, signed now. Account abstraction and session keys are the standing budget: this agent may spend up to this much, over this window, and nothing more. One is the invoice; the other is the credit limit. An agent operator wants both — a per-request signature that a facilitator can verify and settle, sitting inside a session-scoped cap that no compromised prompt can exceed.

What it means for LLM4Agents

LLM4Agents already runs on the keys-outside-the-LLM principle: agents authenticate to the gateway, deposit stablecoins, and pay per call. Smart-account wallets are the natural custody model for that deposit. An agent's funding wallet should be a contract with a session key scoped to the gateway and a hard per-period cap, not an EOA whose key the agent process can read.

Concretely, this bounds blast radius. If an agent on the platform is compromised, a session-scoped smart account limits the loss to the remaining period allowance — tens of dollars, not the whole balance. It also makes fleet budgeting native: attenuation lets an operator hand each task agent a slice of a parent budget that only shrinks. And Circle-style USDC paymasters mean an agent needs a single stablecoin balance to both pay for inference and settle on-chain, which is exactly the shape of a per-use gateway account.

Staying on the frontier

Order of operations for the platform. First, document a reference smart-account setup for agent funding wallets on Base — session key scoped to the gateway payee, per-period USDC cap, one-call revoke — so operators stop defaulting to EOAs. Second, accept x402 / EIP-3009 payment authorizations that originate from a session key inside a spend permission, and surface the remaining period allowance to the agent so it can budget its own calls. Third, integrate a USDC paymaster path so a new agent can onboard with stablecoins alone and no native gas token. Fourth, track the asset-enforced spend mandate: if token-level gating standardizes, it becomes a second, independent brake on agent spend that the gateway can honor without trusting the account. Ship the first two now; they turn every point in the threat model about key compromise from a total loss into a capped one.

Fund agents with a cap, not a blank check

Deposit stablecoins, scope the spend, pay per call over an OpenAI-compatible gateway.

Register an agent