Skip to main content
Smart accounts let the AI agent trade on your behalf without requiring a signature popup for every transaction. Using ZeroDev Kernel and ERC-4337, you create session keys with granular permissions — spending limits, allowed contracts, and expiration times — so the agent operates autonomously within your defined boundaries.

Why Smart Accounts?

Traditional EOA wallets require the user to approve every transaction. This breaks the agent experience — you cannot ask the agent to execute a multi-step DeFi strategy if each step requires manual wallet confirmation. Smart accounts solve this with delegated execution:

No Signing Popups

The agent uses a session key to sign transactions without prompting you for each one.

Granular Permissions

Session keys are scoped to specific contracts, function selectors, and spending limits.

Batched Transactions

Multiple DeFi operations (swap + stake + LP) execute atomically in a single UserOperation.

Architecture

The smart account system uses three layers:
Your Wallet (EOA owner)
  |
  v
ZeroDev Kernel (ERC-4337 smart account)
  |
  v
Session Key (scoped permissions via CallPolicy)
  |
  v
Agent executes trades using the session key

ZeroDev Kernel

The AgentSmartAccount class wraps ZeroDev Kernel, an ERC-4337 smart account implementation. Kernel provides:
  • ECDSA validator: your EOA is the sudo owner
  • Permission plugins: session keys are installed as regular (non-sudo) validators
  • Batched execution: executeBatch() combines multiple calls into one UserOperation
  • Gas sponsorship: transactions can be sponsored via the Pimlico paymaster

EntryPoint

All UserOperations are submitted to the ERC-4337 EntryPoint contract:
ContractAddress
EntryPoint v0.70x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
Pimlico Bundler0x4337001fff419768e088ce247456c1b892888084
The Pimlico bundler processes UserOperations and submits them to the EntryPoint. It also provides paymaster functionality for gas sponsorship — users do not need ETH for gas if sponsorship is enabled.

Session Keys

Session keys are the core mechanism for safe agent delegation. Each session key is an ephemeral private key with constrained permissions enforced on-chain by the Kernel permission plugin.

Creating a Session Key

const sessionKey = await smartAccount.createSessionKey({
  validUntil: Math.floor(Date.now() / 1000) + 86400, // 24 hours
  spendingLimitUsdc: 1000_000000n, // 1,000 USDC (6 decimals)
  allowedTargets: [
    "0x4c60051384bd2d3c01bfc845cf5f4b44bcbe9de5", // Uniswap UniversalRouter
    "0x794a61358D6845594F94dc1DB02A252b5b4814aD", // Aave V3 Pool
  ],
  allowedSelectors: [
    "0x3593564c", // execute (UniversalRouter)
    "0x617ba037", // supply (Aave)
  ],
});

Session Key Parameters

ParameterTypeDescription
validUntilnumberUnix timestamp when the session key expires
spendingLimitUsdcbigintMaximum USDC the session key can spend (6 decimals)
allowedTargetsAddress[]Contract addresses the key may call
allowedSelectorsHex[]Optional: restrict to specific function selectors

On-Chain Enforcement

When @zerodev/sdk is installed, session keys are enforced on-chain through Kernel’s permission plugin:
  1. The agent creates an ECDSA signer from the session private key
  2. A CallPolicy is constructed with the allowed targets and selectors
  3. A PermissionValidator is registered that wraps the signer and policies
  4. A session-scoped Kernel account is created with the permission validator as the regular validator
  5. UserOperations signed by the session key are validated on-chain against the policy
If @zerodev/sdk is not installed, session keys are generated locally but permissions are NOT enforced on-chain. The agent still respects the limits in software, but there is no smart contract guarantee. Install the full SDK for production use.

CallPolicy

The CallPolicy is the heart of session key security. It defines exactly what the session key can do:
ConstraintDescription
targetThe contract address the key may call
valueLimitMaximum ETH value per call (0 = no ETH transfers)
sigFunction selector restriction (optional)
Multiple permissions can be combined in a single CallPolicy, allowing the session key to interact with several contracts while still being tightly scoped.

Batched Execution

One of the most powerful features of smart accounts is atomic batched execution. Instead of sending 3 separate transactions (approve + swap + supply), the agent can bundle them into a single UserOperation:
const hash = await smartAccount.batchExecute([
  { target: usdcAddress, data: approveCalldata, value: 0n },
  { target: routerAddress, data: swapCalldata, value: 0n },
  { target: aavePoolAddress, data: supplyCalldata, value: 0n },
]);
All three calls succeed or fail together. This eliminates the risk of partial execution where a swap succeeds but the subsequent supply fails.
Batched execution also saves gas. A single UserOperation with 3 internal calls costs less than 3 separate transactions because it avoids repeated base transaction overhead.

Fallback Behavior

The batchExecute method has a graceful degradation chain:
  1. Session key client — if a session key is provided and a session-scoped Kernel client exists, uses it
  2. Owner Kernel client — if ZeroDev SDK and Pimlico are configured, submits as a batched UserOperation
  3. Deployed smart account — if the Kernel account is deployed on-chain, sends batch calldata directly
  4. EOA sequential — if no smart account exists, executes calls one at a time from the owner EOA

Gas Sponsorship

With a Pimlico API key configured, the smart account can sponsor gas for users. The Pimlico paymaster covers the gas cost of UserOperations, so users do not need ETH in their wallet to interact with DeFi protocols.
const hash = await smartAccount.sponsoredExecute({
  target: poolAddress,
  data: supplyCalldata,
  value: 0n,
});
// User pays nothing for gas -- Pimlico covers it
Gas sponsorship requires a Pimlico API key. The paymaster is configured during AgentSmartAccount.init() if the key is provided.

Web Frontend Integration

The web UI integrates smart accounts with the Dynamic Labs wallet SDK:
  1. User connects their wallet via Dynamic Labs (supports MetaMask, WalletConnect, Coinbase Wallet, etc.)
  2. The frontend derives a ZeroDev Kernel address from the connected wallet
  3. User approves a session key with their desired permissions
  4. The session key is stored in sessionStorage for the browser session
  5. All subsequent agent actions use the session key — no more wallet popups

Session Recovery

If the browser tab is refreshed, the useChat hook recovers the active session from sessionStorage and reconnects to the agent thread. The session key remains valid until its validUntil timestamp expires.

Revoking Session Keys

Session keys can be revoked immediately:
const revoked = smartAccount.revokeSessionKey(sessionKeyAddress);
// Returns true if the key was found and removed
This removes the session-scoped Kernel client from memory. The on-chain validator remains installed but the agent can no longer use it to sign UserOperations.
Revoking a session key in the AgentSmartAccount class only removes the local client. For full on-chain revocation, the Kernel permission validator must be uninstalled via a sudo UserOperation. This is not yet automated.

SDK Reference

The smart account is in the @arb-agent/smart-account package as AgentSmartAccount.

Constructor

const account = new AgentSmartAccount({
  ownerPrivateKey: "0x...",
  rpcUrl: "https://arb1.arbitrum.io/rpc",       // optional
  pimlicoApiKey: "pk_...",                       // optional, enables UserOps
});

Methods

MethodDescription
init()Initialize the Kernel account and optional Pimlico client
createSessionKey(params)Create a scoped session key with on-chain permissions
batchExecute(calls, sessionKey?)Execute multiple calls atomically
sponsoredExecute(call)Execute a single call with gas sponsorship
revokeSessionKey(address)Revoke a session key locally

Properties

PropertyTypeDescription
addressAddressThe smart account address (call init() first)

Example Prompts

Create a session key that can trade on Uniswap for 24 hours with a 500 USDC limit
Execute a swap and supply in one transaction
What's my smart account address?
Revoke my current session key