# `X402.AuthCapture.Store`
[🔗](https://github.com/cardotrejos/x402/blob/v0.9.0/lib/x402/auth_capture/store.ex#L1)

Atomic storage contract for auth-capture execution and recovery.

Applications must supply a shared, durable implementation in production.
A successful `transact_many/3` must be serializable across all selected keys
and durable before returning. The mutation receives a map containing every
selected key, with `nil` for absent values. Commit maps may update only
selected keys. `{:keep, reply}` returns a successful, atomic read without
writing; it must still validate the snapshot when using compare-and-swap.
It must be pure: adapters may evaluate it more than once while retrying a
compare-and-swap. Never sign, broadcast, or execute a handler in a mutation.

Neither unresolved work nor completed replay records may expire or be
evicted. Read errors are not missing records. A timeout is ambiguous: the
mutation may have committed, so callers must reconcile rather than assume
ownership or repeat an external effect. Use a dedicated gas account unless
every writer participates in an external global coordinator. Sharing a
backend does not coordinate this journal with other schemes, the existing
per-node nonce manager, or transactions submitted outside this SDK.

`X402.AuthCapture.ETSStore` is a volatile development implementation, not a
production durability adapter. Store records contain signed payment and
transaction data; restrict access and do not log their contents.

# `multi_mutation`

```elixir
@type multi_mutation() :: (map() -&gt;
                       {:commit, map(), term()}
                       | {:keep, term()}
                       | {:abort, term()})
```

# `mutation`

```elixir
@type mutation() :: (value() -&gt;
                 {:commit, map(), term()} | {:keep, term()} | {:abort, term()})
```

# `t`

```elixir
@type t() :: {module(), term()}
```

# `value`

```elixir
@type value() :: map() | nil
```

# `fetch`

```elixir
@callback fetch(term(), term()) :: {:ok, value()} | {:error, term()}
```

# `transact_many`

```elixir
@callback transact_many(term(), [term()], multi_mutation()) ::
  {:ok, term()} | {:error, term()}
```

# `fetch`
*since 0.9.0* 

```elixir
@spec fetch(t(), term()) :: {:ok, value()} | {:error, term()}
```

Reads a record without converting adapter errors into cache misses.

# `transact`
*since 0.9.0* 

```elixir
@spec transact(t(), term(), mutation()) :: {:ok, term()} | {:error, term()}
```

Applies a pure, atomic mutation and returns its reply only after persistence.

# `transact_many`
*since 0.9.0* 

```elixir
@spec transact_many(t(), [term()], multi_mutation()) ::
  {:ok, term()} | {:error, term()}
```

Atomically reads and updates selected keys without scanning other records.

# `validate`
*since 0.9.0* 

```elixir
@spec validate(term()) :: {:ok, t()} | {:error, String.t()}
```

Validates an adapter for use with `NimbleOptions`.

This checks callbacks, not the implementation's durability.

## Examples

    iex> X402.AuthCapture.Store.validate(nil)
    {:error, "expected {adapter, context} implementing the auth-capture store"}

---

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