# `X402.Scheme.Registry`
[🔗](https://github.com/cardotrejos/x402/blob/v0.9.0/lib/x402/scheme/registry.ex#L1)

Resolves (scheme, network) pairs to `X402.Scheme` modules.

The default mapping is seeded with the built-in schemes —
`X402.Scheme.ExactEVM` (`"exact"` on `"eip155:*"`),
`X402.Scheme.ExactSVM` (`"exact"` on `"solana:*"`), and
`X402.Scheme.UptoEVM` (`"upto"` on `"eip155:*"`), and
`X402.Scheme.AuthCaptureEVM` (`"auth-capture"` on `"eip155:*"`). There is no global
registration and no application environment: callers pass additional
scheme modules explicitly (the `:schemes` option on
`X402.Client.build_payment/3`, `X402.Plug.PaymentGate`, and
`X402.PaymentSignature.validate/3`), and those are consulted **before**
the built-ins, so a user module can override a built-in kind.

## Resolution semantics

Candidate modules are the extra schemes followed by the built-ins,
filtered to those whose `c:X402.Scheme.scheme/0` equals the requested
scheme. Among candidates, the network decides:

1. An **exact** CAIP-2 match in `c:X402.Scheme.networks/0` always wins
   over any wildcard match; ties go to the earlier module in the list.
2. Otherwise the **wildcard** patterns (trailing `*`, matched as a
   prefix — `"eip155:*"`, or `"*"` for any network) are consulted; the
   longest (most specific) matching pattern wins, and ties go to the
   earlier module in the list.

Kinds that resolve to no module return `:error`; callers treat that as
"no scheme module registered" and fall back to their historical neutral
behavior (pass-through validation, skipped pre-checks, or the client's
`{:unsupported_kind, scheme, network}` error).

## Examples

    iex> X402.Scheme.Registry.resolve("exact", "eip155:8453")
    {:ok, X402.Scheme.ExactEVM}

    iex> X402.Scheme.Registry.resolve("upto", "eip155:84532")
    {:ok, X402.Scheme.UptoEVM}

    iex> X402.Scheme.Registry.resolve("exact", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp")
    {:ok, X402.Scheme.ExactSVM}

# `builtins`
*since 0.6.0* 

```elixir
@spec builtins() :: [module()]
```

Returns the built-in scheme modules, in consultation order.

## Examples

    iex> X402.Scheme.Registry.builtins()
    [X402.Scheme.ExactEVM, X402.Scheme.ExactSVM, X402.Scheme.UptoEVM, X402.Scheme.AuthCaptureEVM]

# `network_matches?`
*since 0.6.0* 

```elixir
@spec network_matches?(String.t(), String.t()) :: boolean()
```

Returns whether a CAIP-2 network matches a network pattern.

A pattern ending in `*` matches any network starting with the prefix
before it; any other pattern must match exactly.

## Examples

    iex> X402.Scheme.Registry.network_matches?("eip155:*", "eip155:8453")
    true

    iex> X402.Scheme.Registry.network_matches?("eip155:8453", "eip155:1")
    false

    iex> X402.Scheme.Registry.network_matches?("*", "solana:mainnet")
    true

# `resolve`
*since 0.6.0* 

```elixir
@spec resolve([module()], term(), term()) :: {:ok, module()} | :error
```

Resolves a (scheme, network) pair to a scheme module.

`extra_schemes` are consulted before the built-ins. Non-binary scheme or
network values resolve to `:error`.

## Examples

    iex> X402.Scheme.Registry.resolve([], "exact", "eip155:1")
    {:ok, X402.Scheme.ExactEVM}

    iex> X402.Scheme.Registry.resolve([], "cash", "eip155:1")
    :error

    iex> X402.Scheme.Registry.resolve([], nil, "eip155:1")
    :error

---

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