# `Attesto.CNonceStore`
[🔗](https://github.com/XukuLLC/attesto/blob/v2.0.1/lib/attesto/c_nonce_store.ex#L1)

Storage seam for server-issued OID4VCI c_nonces.

A server issues an opaque, time-limited c_nonce from the nonce endpoint and
requires the wallet to echo it in the proof sent to the credential endpoint.
This behaviour is where those nonces live: `issue/1` mints one, `valid?/1`
reports whether a presented nonce is still live (non-consuming, so every proof
in one OID4VCI `proofs` batch can validate against the shared nonce), and
`consume/1` atomically single-uses it (called once per credential request,
after the whole batch verifies, so a captured proof + nonce cannot be replayed
for another credential).

`Attesto.CNonceStore.ETS` is a ready single-node implementation. A
multi-node deployment implements this over a shared store so a nonce issued
by one node is honoured by another.

# `consume`

```elixir
@callback consume(nonce :: String.t()) :: :ok | {:error, :used | :expired | :unknown}
```

Atomically consume `nonce` so it cannot be used again.

Returns `:ok` to the single caller that wins the consume, and an `{:error, _}`
to everyone else so single-use is enforced (that is what stops a captured proof
from being replayed to mint duplicate credentials; a store that cannot
implement this MUST NOT be used for issuance). The precise error is
best-effort and implementation-dependent: a store that deletes the row on
consume (like `Attesto.CNonceStore.ETS`) reports `{:error, :unknown}` for an
already-consumed nonce because it is indistinguishable from one never issued;
a store that records a `used_at` marker instead can distinguish `{:error,
:used}` from `{:error, :expired}`/`{:error, :unknown}`. Callers MUST treat any
`{:error, _}` as "not consumable" and fail closed.

# `issue`

```elixir
@callback issue(ttl_seconds :: pos_integer()) :: String.t()
```

Mint and store a fresh nonce valid for `ttl_seconds`.

# `valid?`

```elixir
@callback valid?(nonce :: String.t()) :: boolean()
```

Returns true iff `nonce` was issued by this store and has not expired.

---

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