# ERC-4337 user operations: when the transaction isn't yours

> An ERC-4337 smart account sends user operations, not transactions. What a bundler, the EntryPoint and a paymaster do, and which hash and fee are the agent's.

Source: https://hashspan.dev/learn/erc-4337-user-operations

## Short answer

A user operation is the transaction-like request an ERC-4337 smart account signs. A bundler packs several of them into one ordinary transaction that calls the EntryPoint contract, which verifies and runs each one. So the transaction on chain belongs to the bundler, and your operation is identified by its own hash, the userOpHash, and paid by its own cost.

Figure: An agent's smart account signs a user operation, a bundler packs it with other accounts' operations into one handleOps transaction, and the EntryPoint runs each one: the bundle receipt can say success while the agent's own operation reverted, so hashspan keys its spans by the userOpHash.

## Who sends what?

ERC-4337 adds account abstraction without changing Ethereum's protocol ([ERC-4337](https://eips.ethereum.org/EIPS/eip-4337)). An agent with a smart account doesn't send transactions itself. It signs user operations and hands them to a bundler.

| Role | What it does |
|---|---|
| Smart account | The agent's wallet, a contract. It decides how a signature is checked |
| User operation | The signed request: sender, nonce, calls, gas limits, signature |
| Bundler | Packs user operations into one transaction calling `handleOps` on the EntryPoint |
| EntryPoint | One contract per version that verifies and runs each operation, and charges for it |
| Paymaster | An optional contract that pays the gas instead of the account |

## Which hash identifies the agent's action?

The bundle transaction has a normal hash, but it isn't the agent's. It may carry other people's operations too.

The agent's handle is the **userOpHash**. It covers the operation without its signature, plus the EntryPoint address and the chain id. The same operation on another chain or EntryPoint has a different hash.

That changes how you follow an action:

1. The agent gets the userOpHash back from the bundler.
2. The bundler includes the operation in a bundle transaction.
3. The EntryPoint emits an event for the operation, with its success and its actual gas cost.

## What did it cost, and did it work?

Two things differ from a plain transaction.

- **Success is per operation.** The bundle transaction can succeed while one operation's calls revert. Its receipt status says nothing about yours.
- **Cost is per operation.** The operation pays its share, the actual gas cost the EntryPoint charged. The bundle transaction's fee is the bundler's, and covers everyone in the bundle.

An agent that reads the bundle receipt's status and fee gets both wrong.

**In a hashspan trace:**
`@hashspan/viem` traces `sendUserOperation` and `waitForUserOperationReceipt` on a bundler client, and `@hashspan/cdp` the user operations of CDP smart accounts ([ADR 0021](https://github.com/selimaytac/hashspan/blob/main/docs/adr/0021-user-operations.md)). The spans are keyed by chain and userOpHash, not by the bundle's hash:

  - `send`: `blockchain.user_operation.hash`, `.sender`, `.entry_point`, `.call_count`
  - `confirm`, linked to it: `blockchain.user_operation.success`, `.gas.used`, `.gas.cost` (the operation's own cost), `.nonce`, `.paymaster`, and the bundle's `blockchain.tx.hash` and `blockchain.block.number`

No `blockchain.tx.status` or bundle fee is recorded on a user operation's confirm span. An operation whose calls reverted ends with `error.type` `reverted`; one that CDP reports as `failed`, without a reason, ends with `failed`. The [user operation attributes](https://hashspan.dev/docs/reference/attributes/user-operations) list every field.

## FAQ

### Is the userOpHash a transaction hash?

No. It hashes the user operation (without its signature) together with the EntryPoint address and the chain id. Searching for it as a transaction hash finds nothing; the bundle transaction has a hash of its own.

### Can the bundle transaction succeed while my operation fails?

Yes. The EntryPoint runs each operation and reports its own success. The bundle transaction can succeed while the calls of one operation revert.

### Who pays the gas?

The smart account, from its deposit in the EntryPoint, unless a paymaster agreed to pay instead.
