# `X402.Facilitator.NonceManager`
[🔗](https://github.com/cardotrejos/x402/blob/v0.9.0/lib/x402/facilitator/nonce_manager.ex#L1)

Serializes fee-payer transaction nonces for concurrent settlements.

`X402.Facilitator.Engine.settle/3` broadcasts an EIP-1559 transaction from
the facilitator's fee-payer account. Reading `eth_getTransactionCount`
per settlement races under concurrency: two settles can read the same
pending nonce, sign two different payments with it, and the node rejects
one even though its EIP-3009 authorization was never used.

This process assigns nonces instead, tracking the full lifecycle:

  * `checkout/3` — assigns the next nonce (fetching from the node only on
    first use per address) and marks it in flight.
  * `complete/3` — the transaction reached the node; the nonce is consumed.
  * `release/3` — the settlement failed before the node could have seen
    the transaction. The tail nonce is rolled back so no gap forms; a
    released middle nonce marks the address for a re-fetch once every
    in-flight settlement drains, since a gap would stall later
    transactions at the node.
  * `reset/2` — forget the address (re-fetch on next checkout). With
    settlements still in flight, the reset is deferred until they drain,
    so an in-flight nonce is never reissued.

Start one manager (state is keyed by address) and pass it to
`X402.Facilitator.Engine.new/1` via `:nonce_manager`:

    children = [
      {X402.Facilitator.NonceManager, name: MyApp.NonceManager},
      ...
    ]

> #### Per-node only {: .warning}
>
> Nonce tracking lives on the local node. Running the same fee-payer key
> on several facilitator nodes still races at the chain level — use one
> fee payer per node, or coordinate externally.

# `fetch_fun`

```elixir
@type fetch_fun() :: (-&gt; {:ok, non_neg_integer()} | {:error, term()})
```

A function fetching the current pending nonce from the node.

# `server`

```elixir
@type server() :: GenServer.server()
```

Server identifier accepted by `GenServer.call/3`.

# `checkout`
*since 0.6.0* 

```elixir
@spec checkout(server(), String.t(), fetch_fun()) ::
  {:ok, non_neg_integer()} | {:error, term()}
```

Checks out the next nonce for `address` and marks it in flight.

Runs `fetch_fun` (inside the manager — first use per address and after a
drain-triggered re-fetch) when no nonce is tracked. A fetch error — or a
raise, which is caught — is returned as an error and nothing is stored.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `complete`
*since 0.6.0* 

```elixir
@spec complete(server(), String.t(), non_neg_integer()) :: :ok
```

Marks `nonce` as consumed: its transaction reached (or may have reached)
the node.

# `release`
*since 0.6.0* 

```elixir
@spec release(server(), String.t(), non_neg_integer()) :: :ok
```

Returns `nonce` unused: its settlement failed before the node could have
seen the transaction.

The tail nonce rolls straight back; releasing a middle nonce (later
checkouts still in flight) marks the address for a node re-fetch once the
in-flight settlements drain, because the resulting gap would stall later
transactions.

# `reset`
*since 0.6.0* 

```elixir
@spec reset(server(), String.t()) :: :ok
```

Forgets the tracked nonce state for `address`.

With settlements still in flight, the reset is deferred until they drain
so an in-flight nonce is never reissued.

# `start_link`
*since 0.6.0* 

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts a nonce manager.

## Options

  * `:name` — optional registered name.

---

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