This repository presents a full solution for the agent private-key problem.
AgentBoundAccount is the smart-contract component in that solution, focused on enforcing bounded, revocable execution permissions on-chain.
- Overview
- Architecture
- Agent Handoff Flow
- AA (ERC-4337) Flow
- Security Model
- Repository Structure
- Getting Started
- Testing
- Use Cases
- Current Limitations
- License
In many agent-wallet designs, the agent directly controls a spend-capable private key. If that key is leaked, over-scoped, or misused by adversarial input, assets are exposed.
This project enforces a split-responsibility model:
- Owner key: configures policy (session creation/revocation).
- Session key: executes actions within policy constraints.
- On-chain guards: enforce budget, expiry, allowlist, and replay protection.
The system combines ERC-6551 (NFT-bound wallets), session-based authorization, and ERC-4337 account abstraction:
- A user owns an NFT.
- The NFT maps to a Token Bound Account (TBA).
- The owner creates a session policy on the TBA:
validUntil,budgetToken,maxTotal,targets. - The agent activates a signer for that session:
activateSessionoractivateSessionBySig. - Execution is sent through the AA bundler flow (
EntryPoint.handleOps). - The TBA enforces policy via
executeWithSession. - The owner can revoke immediately with
revokeSession.
Design principle: the owner key configures and revokes permissions, while the session key only authorizes requests within those permissions.
High-level handoff flow:
- Owner sends the agent setup instructions (skill message).
- Agent prepares runtime and AA bundler RPC configuration (for example
PIMLICO_RPC_URL). - Owner creates a bounded session policy on the TBA.
- Owner sends session context (
tba,sessionId, intent in natural language) to the agent. - Agent signs and submits requests through AA.
- All execution is enforced by on-chain session constraints.
For operator-level UI details and exact frontend actions, see frontend/README.md.
Execution path:
- UserOperation is submitted to
EntryPoint.handleOps(...). - Account
callDataroutes into TBA calls. - Execution reaches
Agent6551Account.executeWithSession(...).
Session policy enforcement happens in Agent6551Account.
Current protections in Agent6551Account:
- EIP-712 signature verification.
- Deadline/expiry checks.
- Per-session nonce replay protection.
- Target-address allowlist enforcement.
- Session total-spend cap (
maxTotal). - Owner-triggered emergency revocation.
Auditability is provided via events:
SessionCreated, SessionActivated, SessionExecuted, SessionRevoked.
src/core/Agent6551Account.sol: core ERC-6551 + session authorization logic.src/interfaces/: account and executable interfaces.src/mocks/MockCharacterNFT.sol: demo NFT.src/mocks/MockERC20.sol: demo ERC-20 budget token.src/mocks/MockShop.sol: demo target contract.test/Agent6551Account.t.sol: Foundry unit tests for session constraints.frontend/: Next.js UI for session creation, activation flow, and log inspection.
- Node.js + npm
- Foundry (
forge)
npm install
cd frontend && npm installforge build --sizes
forge test -vvv
forge fmt --checkCreate frontend/.env.local:
NEXT_PUBLIC_REGISTRY_ADDRESS=0x...
NEXT_PUBLIC_IMPLEMENTATION_ADDRESS=0x...
# Optional (NFT discovery):
NEXT_PUBLIC_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/...
NEXT_PUBLIC_ALCHEMY_API_KEY=...Start the app:
cd frontend
npm run devtest/Agent6551Account.t.sol validates:
- successful session execution
- nonce replay rejection
- expired session rejection
- non-allowlisted target rejection
- budget overflow rejection
activateSessionBySigsuccess/failure paths- owner-only access to session enumeration APIs
- on-chain game agents (automated purchases/actions with spend limits)
- strategy wallets (bounded delegated execution)
- AI-agent workflows requiring revocable authority
- Allowlisting is at target-address level (not selector-level).
- This repository is a reference implementation and should be independently reviewed before production use.
MIT (see SPDX headers in source files).