Skip to main content

ERC-8211 Developer Guide 2026: SDK, Predicates, and Integration

Ship composable smart-account bundles with the Biconomy reference SDK. One signature, predicate-gated steps, runtime balance references, and five integration paths from ERC-7579 modules to ERC-7702 EOA delegation.

Written by Eco


ERC-8211 turns a sequence of dependent onchain steps into a single signed bundle. You describe the intent in TypeScript, the SDK compiles it into a ComposableExecution[] array with predicates and runtime references, and the smart account executes the whole bundle atomically. One signature, one Merkle root, no custom Solidity. This guide walks through the reference SDK, the five integration paths, four production patterns, and the testing flow we use before submitting bundles to mainnet.

What ERC-8211 gives you as a developer

Answer capsule: ERC-8211 standardizes composable, predicate-gated, runtime-referenced batch execution for smart accounts. As a developer, you get atomic multi-step bundles, output-to-input chaining without offchain orchestration, and a single signature for the whole sequence. No new contracts to deploy if you adopt the reference module.

Before ERC-8211, batching a swap, a balance check, a supply, and a stake required either custom periphery contracts or a backend that watched mempool state and re-signed each step. The SDK collapses that into one call: each step declares its dependencies on prior outputs, and predicates abort the bundle cleanly if a precondition fails. The smart account verifies a Merkle root covering all steps, so signature reuse and partial execution are both prevented.

SDK overview: the Biconomy reference implementation

Answer capsule: The reference SDK at github.com/bcnmy/composable-batch-erc compiles a fluent TypeScript builder into the ComposableExecution[] wire format. You import primitives like swap, predicate, supply, and stake, pass runtime references like fullBalance(), and the SDK emits the ABI-encoded bundle plus the Merkle root to sign.

A typical four-step DeFi bundle looks like this:

const batch = smartBatch([  swap({ from: WETH, to: USDC, amount: fullBalance() }),  predicate({ balance: gte(USDC, account, 2500e6) }),  supply({ protocol: "aave", token: USDC, amount: fullBalance() }),  stake({ token: aUSDC, amount: fullBalance() })]);

Read top to bottom: swap all WETH to USDC, assert at least 2,500 USDC landed, supply the full USDC balance to Aave, then stake every aUSDC share received. fullBalance() is a runtime reference. The smart account reads the actual balance after each step rather than baking in a value at sign time. That is what makes the bundle slippage-tolerant without offchain re-signing.

One signature covers the Merkle root of all four steps. The SDK handles encoding, predicate ordering, and the gas estimation hints the bundler needs. You write no Solidity and deploy no custom contract.

Integration paths: which one fits your account?

Answer capsule: ERC-8211 ships in five integration shapes. Pick based on the account standard you already support and whether you want to gate the new behavior behind an explicit module install.

Integration path

When to use

Example

ERC-7579 executor module

You already ship a modular smart account and want a drop-in install with no core changes

Biconomy Nexus, ZeroDev Kernel users adding composable batching via module manager

ERC-6900 plugin

Your account follows the ERC-6900 plugin manifest model and you need declared permissions and dependencies

Alchemy Modular Account installing the bundle as a manifest-declared plugin

Native implementation

You control the smart account contract and want first-class support without module overhead

A custodian or wallet vendor shipping a purpose-built account with composable execution baked in

ERC-7702 EOA delegation

The user holds an EOA and you want composable execution for one transaction without deploying a smart account

A swap aggregator routing power users through ERC-7702 delegation to batch approve plus swap plus stake

ERC-4337 / EIP-5792 wire

You want bundlers and wallet RPC clients that already speak ERC-4337 or EIP-5792 to carry the bundle

A frontend calling wallet_sendCalls with composable-execution payload to a Pimlico or Alchemy bundler

Most teams start with the ERC-7579 executor module because the install is a single transaction and existing accounts keep working. Teams shipping their own account contract usually pick the native path so they avoid the per-call module dispatch overhead. ERC-7702 is the right choice when you are optimizing for users who refuse to move off an EOA.

Pattern 1: slippage-tolerant DeFi swap and deposit

Answer capsule: Use a runtime balance reference plus a predicate floor so the deposit step sizes itself off the actual swap output and the bundle reverts cleanly if slippage breaches your floor.

const batch = smartBatch([  swap({ from: WETH, to: USDC, amount: fullBalance() }),  predicate({ balance: gte(USDC, account, minOutUSDC) }),  supply({ protocol: "aave", token: USDC, amount: fullBalance() })]);

The predicate is your slippage floor. If the swap underdelivers, the supply step never runs and the user pays only the failed-bundle gas. No partial state, no stuck funds.

Pattern 2: vault redemption with share-aware downstream sizing

Answer capsule: Redeem the vault, reference the returned asset balance, then size the next step off that runtime value rather than a stale offchain estimate.

This pattern matters because vault share-to-asset rates move between quote and execution. Hard-coding the redemption amount means the next step either leaves dust behind or overshoots and reverts. fullBalance() on the asset token after redemption is the fix.

Pattern 3: cross-chain rebalancing with predicate-gated arrival

Answer capsule: On the destination chain, gate the rebalance bundle behind a predicate that asserts the bridged funds have arrived. The bundle stays valid in the mempool and only executes once the precondition is true.

The source-chain bundle initiates the bridge. The destination-chain bundle reads:

const batch = smartBatch([  predicate({ balance: gte(USDC, account, expectedAmount) }),  swap({ from: USDC, to: targetAsset, amount: fullBalance() }),  supply({ protocol: "aave", token: targetAsset, amount: fullBalance() })]);

Until USDC lands, the predicate fails and the bundle reverts. Once funds arrive, the same signed bundle executes. This replaces the watcher service most cross-chain DeFi teams currently run.

Pattern 4: dust sweep

Answer capsule: Loop over a token list, swap any non-zero balance to a target asset, and supply the consolidated amount. Predicates skip empty positions without aborting the bundle.

The SDK supports conditional steps via predicate blocks that mark the next step as optional rather than required. A dust sweep of fifteen tokens compiles into one bundle, one signature, and one transaction.

How do I test a bundle before submitting?

Answer capsule: Use eth_call against the smart account with the encoded ComposableExecution[] payload. Predicate failures revert with a typed error you can decode, so simulation tells you exactly which step would fail and why.

The flow we run in CI:

  1. Build the bundle with the SDK.

  2. Encode it as the calldata for the account's execute entrypoint.

  3. Call eth_call at the latest block with the user's address as from.

  4. If it reverts, decode the typed error. The SDK exposes a helper that maps the revert selector to a step index and reason (predicate failed, output reference unresolved, slippage breached).

  5. If it succeeds, submit through your bundler of choice.

Because predicates revert cleanly with typed errors, a failed simulation is actionable. You know whether to raise the slippage floor, wait for bridge arrival, or top up the source token before signing.

What about gas estimation for composable bundles?

Answer capsule: The SDK emits per-step gas hints based on the resolved runtime references. Bundlers that speak ERC-4337 or EIP-5792 accept these hints directly. For native or ERC-7702 paths, the account's execute function returns a gas-used trace you can use to set the next bundle's limit.

Where ERC-8211 fits next to ERC-4337 and EIP-5792

Answer capsule: ERC-8211 is a payload format. ERC-4337 and EIP-5792 are transport. You can sign an ERC-8211 bundle and ship it through either transport layer. They are not competitors.

If you want the long version of this comparison, see the dedicated breakdown linked below.

Related reading

Methodology and sources

Drafted from the ERC-8211 reference SDK at github.com/bcnmy/composable-batch-erc and the standard's tracking discussion in EIP PR #1638. Integration-path mapping follows the ERC-7579 executor module interface and the ERC-6900 manifest model. Tested patterns are from reference bundles target Aave V3 markets. No customer data is included.

Did this answer your question?