Nonce lanes and ordering
How DALP maps UserOperations to ERC-4337 nonce lanes, why three distinct work states matter, and the trade-offs between strict, grouped, and independent ordering.
A smart-account execution layer has one core tension. It must accept authorized work durably and drain it without violating nonce order or exceeding capacity. Getting that wrong causes one of two failures: silent drops, where the platform discards a submission, or false serialization, where independent work queues behind unrelated operations and the whole flow looks slow.
DALP resolves this with a two-dimensional nonce space and a small set of ordering policies. The policy is not arbitrary. It reflects whether two operations have a real causal dependency.
Three states, not one queue
Most reasoning errors here come from treating "the queue" as a single thing. There are three distinct states.
Accepted work is the durable intake record. When the platform accepts a submission it writes a durable entry. This answers "did the platform drop it?" independently of whether the operation can be prepared or bundled right now. Accepted work survives restarts, is bounded only by authorization and org scope, and is never silently discarded.
Preparing work is bounded by shared capacity: simulation RPC slots, signing key access, and mempool submission bandwidth. A submission moves from accepted to preparing when capacity is available. 500 accepted operations from one account will eventually prepare. They cannot all prepare at once, but they are not rejected at intake just because they exceed what a single bundle can hold.
Ready work is what can become an on-chain bundle, constrained by bundle size, gas limits, and EntryPoint nonce sequence. The EntryPoint consumes the sequence portion of the nonce in order per key, so ready work must respect that order or the bundle reverts.
Confusing "not yet ready to bundle" with "rejected" is the common design error. The queue is not the bundle.
How the 2D nonce encodes ordering scope
ERC-4337 nonces are 256 bits split as (key << 64) | sequence. The key (uint192) identifies a lane. The sequence (uint64) must increment without gaps within that lane. DALP uses ERC-7579 validator-scoped keys, so the key packs the validator address and a subKey:
nonce = ((validatorAddress || subKey) << 64) | sequenceThe EntryPoint tracks per-sender, per-key sequences independently. Two operations with different nonce keys have no ordering constraint relative to each other, even from the same sender. That is what makes lanes useful.
Per-partition coordination is keyed by (sender address, chain id, nonce key). On first use DALP cold-starts the sequence by reading EntryPoint.getNonce(sender, key). Reservations carry a TTL (default five minutes) so a failed or abandoned operation releases its slot instead of blocking the lane.
Ordering policies and when to use each
DALP exposes three ordering scopes.
Transaction scope gives each UserOperation its own independent lane. The subKey is derived deterministically from the transaction identifier. There is no ordering constraint between any two operations. Use it when operations are fully independent, for example parallel token transfers to different recipients.
Group scope assigns operations that share an explicit orderingKey to a single lane. Everything in the group stays sequenced, and operations in different groups run in parallel. Use it when step A must precede step B (a grant that must follow a role creation) but the flow has no dependency on unrelated flows running at the same time.
Wallet scope places all of a wallet's operations on subKey 0x0, giving one globally ordered lane per wallet. This is strict FIFO: every operation waits behind the one before it. Use it only when the product genuinely requires total ordering, because it serializes everything.
The lane policy is either strict (always subKey 0x0, strict FIFO regardless of scope) or independent (deterministic subKey derivation per seed, or an explicit subKey, which enables the parallelism that transaction and group scopes provide).
Why this matters for product flows
Consider a token-creation flow: create the token, assign roles, optionally attach a price feed. If those steps have no causal dependency they can each claim an independent lane and prepare in parallel, and all three settle quickly. If they are forced onto one wallet lane they queue sequentially behind each other and the flow looks slow. The cause is not a slow bundler. It is an ordering model that does not match the work.
The same logic applies at scale. An organization submitting 500 authorized operations should not have those submissions rejected at intake because they exceed a single bundle. They are accepted, prepared in batches bounded by capacity, and drained across lanes. The platform accepts authorized work durably and drains it correctly. It does not gate acceptance on bundle capacity.
Trade-off summary
| Ordering scope | Parallelism | Causal safety | Typical use |
|---|---|---|---|
| Transaction | Maximum | None | Independent transfers, parallel mints |
| Group | Per-group | Within group | Multi-step flows with internal dependencies |
| Wallet | None | Total | Strict FIFO requirement, audit-critical work |
A stricter scope than the work needs is not safer. It trades throughput for a constraint the work does not have. A looser scope than the work needs risks an on-chain revert when a dependent operation reaches the EntryPoint before its prerequisite.
Related pages
- UserOperations for the structure and lifecycle of a UserOperation before it reaches intake.
- Bundlers for how DALP's controlled bundler differs from a public ERC-4337 bundler.
- Account abstraction design for validator-scoped keys and the ERC-7579 module model.
Paymasters and gas sponsorship
How DALP uses system paymasters to sponsor eligible account abstraction transactions without changing identity, custody, or asset policy checks.
Key Guardian
Understand how DALP routes each signing request to local signing, DFNS, Fireblocks, or Luna HSM while keeping custody-provider policy outside the business workflow.