# `EEVM.Handler`
[🔗](https://github.com/mw2000/eevm/blob/v0.1.0/lib/eevm/handler.ex#L1)

End-to-end transaction handler.

Orchestrates the per-transaction pipeline, deferring each phase to a
sibling module so the layering stays inspectable:

- `EEVM.Handler.Validation`    — decode → recover sender → validate
- `EEVM.Handler.PreExecution`  — charge upfront → intrinsic gas → bump nonce →
  apply EIP-7702 authorizations
- `EEVM.Handler.Execution`     — top-level CALL or CREATE through the EVM
- `EEVM.Handler.PostExecution` — settle refund, credit coinbase, build result

This split mirrors revm's `handler/` crate (`validation.rs`,
`pre_execution.rs`, `execution.rs`, `post_execution.rs`) and keeps each
phase independently testable.

# `opts`

```elixir
@type opts() :: [
  hardfork: EEVM.HardforkConfig.spec_id(),
  config: EEVM.Config.t(),
  tracer: boolean() | EEVM.Tracer.t(),
  commit: boolean(),
  details: boolean(),
  chain_id: non_neg_integer()
]
```

# `wire_tx`

```elixir
@type wire_tx() :: EEVM.Handler.Validation.wire_tx() | EEVM.TxEnv.t()
```

A transaction: raw signed bytes, a signed `EEVM.Transaction` struct, or,
for simulation, an unsigned `EEVM.TxEnv` whose `origin` is the sender.

# `execute`

```elixir
@spec execute(wire_tx(), EEVM.BlockEnv.t(), EEVM.Database.t(), opts()) ::
  {:ok, EEVM.TransactionResult.t()}
  | {:error, EEVM.Error.reason() | EEVM.TransactionError.t()}
```

Execute a single transaction end-to-end. `EEVM.transact/4` delegates here;
call that instead.

`tx_or_bytes` may be either raw wire bytes (legacy RLP or a typed envelope
prefix + RLP) or one of the typed `EEVM.Transaction.*` structs. For
simulation it may also be an unsigned `EEVM.TxEnv`: its `origin` is the
sender, with no signature to recover, and every other rule applies unless
a simulation switch in the config turns it off.

## Options

- `:config` — the `EEVM.Config`: hardfork, chain id (used to recover the
  sender and check EIP-7702 authorizations), custom precompiles, and the
  simulation switches, which are never for consensus.
- `:hardfork` — shorthand for `config: EEVM.Config.new(hardfork)` (default
  `:cancun`). `:config` takes precedence when both are given.
- `:tracer` — `true` or an `EEVM.Tracer` to record an EIP-3155 trace,
  returned as `result.trace`.
- `:commit` — `false` to leave the writes in `result.db`'s overlay and
  skip `result.changes`; `EEVM.Block` does this to commit once per block.
  By default the writes are committed when the backend implements
  `c:EEVM.Database.commit/2`.
- `:details` — `true` to return each rejection as
  `{:error, %EEVM.TransactionError{}}`, which carries the values the rule
  compared (the nonces, balance and cost, fees, gas limits) next to the
  reason. Default `false`: `{:error, reason}` with the bare atom.
- `:chain_id` — deprecated; set it with `EEVM.Config.new/2`. Overrides the
  config's chain id when given.

## Returns

- `{:ok, %EEVM.TransactionResult{}}` for any transaction that made it past
  validation, including reverted and halted ones. Inspect `result.status`
  to tell them apart.
- `{:error, reason}` when decoding, sender recovery, validation, or upfront
  balance charging fail, and `{:error, {:database, reason}}` when the
  backend fails a read or commit. The database is unchanged in each case.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
