X402.AuthCapture.Store behaviour (X402 v0.9.0)

Copy Markdown View Source

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.

Summary

Functions

Reads a record without converting adapter errors into cache misses.

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

Atomically reads and updates selected keys without scanning other records.

Validates an adapter for use with NimbleOptions.

Types

multi_mutation()

@type multi_mutation() :: (map() ->
                       {:commit, map(), term()}
                       | {:keep, term()}
                       | {:abort, term()})

mutation()

@type mutation() :: (value() ->
                 {:commit, map(), term()} | {:keep, term()} | {:abort, term()})

t()

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

value()

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

Callbacks

fetch(term, term)

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

transact_many(term, list, multi_mutation)

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

Functions

fetch(store, key)

(since 0.9.0)
@spec fetch(t(), term()) :: {:ok, value()} | {:error, term()}

Reads a record without converting adapter errors into cache misses.

transact(store, key, mutation)

(since 0.9.0)
@spec transact(t(), term(), mutation()) :: {:ok, term()} | {:error, term()}

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

transact_many(store, keys, mutation)

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

Atomically reads and updates selected keys without scanning other records.

validate(store)

(since 0.9.0)
@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"}