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

Built-in `X402.Scheme` for `auth-capture` payments on EVM (`eip155:*`)
networks.

Implements both roles:

* **Client** — signs the single token authorization the scheme needs:
  an EIP-3009 `ReceiveWithAuthorization` toward the deployment's
  EIP-3009 token collector (default), or a witness-less Permit2
  `PermitTransferFrom` toward its Permit2 collector when
  `extra.assetTransferMethod` is `"permit2"`. The authorization's nonce
  is the payment's `signatureNonce`, which commits to every
  `PaymentInfo` field the facilitator reconstructs; `salt` (and, when
  the bind is on, `saltNonce`) ride alongside. The payload is identical
  under both payment flows — `extra.paymentFlow` only decides whether
  the facilitator settles it as `authorize` or `charge`.
* **Server** — `c:X402.Scheme.validate_payload/3` runs the offline shape
  guard and `c:X402.Scheme.precheck/3` the full structural checklist
  (`X402.Verify.AuthCaptureEVM` at level `:structural`). Both report
  `{:error, {:invalid_auth_capture_payment, reason}}`.

`reclaim_transaction/2` builds the payer's own `reclaim` call for a hold
the server never captured; the escrow restricts it to the payer, so it
is never relayed by a facilitator.

# `networks`
*since 0.9.0* 

```elixir
@spec networks() :: [String.t()]
```

Returns `["eip155:*"]` — every EVM network.

## Examples

    iex> X402.Scheme.AuthCaptureEVM.networks()
    ["eip155:*"]

# `precheck`
*since 0.9.0* 

```elixir
@spec precheck(map(), map(), keyword()) ::
  :ok
  | {:error,
     {:invalid_auth_capture_payment, X402.AuthCapture.reason() | term()}}
```

Runs the structural verification checklist locally (level `:structural`).

Honors `:now` and `:skew_seconds` from `opts` for the deadline checks.

# `reclaim_transaction`
*since 0.9.0* 

```elixir
@spec reclaim_transaction(map(), map()) ::
  {:ok, %{to: String.t(), data: String.t(), value: 0}} | {:error, term()}
```

Builds the payer's `reclaim(PaymentInfo)` transaction for an escrowed
hold whose capture deadline has passed.

Accepts the signed payment payload (v2 envelope or inner payload) and the
requirements it was signed for, and returns the call the payer submits
from its own account: `%{to: escrow, data: "0x...", value: 0}`.

# `scheme`
*since 0.9.0* 

```elixir
@spec scheme() :: String.t()
```

Returns `"auth-capture"`.

## Examples

    iex> X402.Scheme.AuthCaptureEVM.scheme()
    "auth-capture"

# `sign`
*since 0.9.0* 

```elixir
@spec sign(map(), X402.Signer.t(), keyword()) :: {:ok, map()} | {:error, term()}
```

Signs the `auth-capture` scheme payload for the selected transfer method.

The authorization is valid immediately (`validAfter` `"0"`) and expires
at `now + maxTimeoutSeconds`, which is also `PaymentInfo.preApprovalExpiry`.

## Options

* `:now` (`t:non_neg_integer/0`) - Unix seconds the authorization window starts from (default: current time).

* `:salt` (`t:String.t/0`) - Unbound `salt` (32-byte `0x` hex). Defaults to fresh random bytes.

* `:salt_nonce` (`t:String.t/0`) - Bound `saltNonce` (32-byte `0x` hex). Defaults to fresh random bytes.

# `signable?`
*since 0.9.0* 

```elixir
@spec signable?(map()) :: boolean()
```

Whether the client can sign this requirements entry: an EVM network, a
resolvable deployment, a supported transfer method and payment flow, and
the `extra` fields `PaymentInfo` needs.

## Examples

    iex> X402.Scheme.AuthCaptureEVM.signable?(%{
    ...>   "scheme" => "auth-capture",
    ...>   "network" => "eip155:84532",
    ...>   "amount" => "10000",
    ...>   "asset" => "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    ...>   "payTo" => "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
    ...>   "maxTimeoutSeconds" => 600,
    ...>   "extra" => %{
    ...>     "name" => "USDC",
    ...>     "version" => "2",
    ...>     "captureMode" => "deferred",
    ...>     "captureAuthorizer" => "0x1563915e194d8cfba1943570603f7606a3115508",
    ...>     "feeRecipient" => "0x0000000000000000000000000000000000000000",
    ...>     "captureDeadline" => 1_800_000_000,
    ...>     "refundDeadline" => 1_800_100_000,
    ...>     "minFeeBps" => 0,
    ...>     "maxFeeBps" => 0
    ...>   }
    ...> })
    true

    iex> X402.Scheme.AuthCaptureEVM.signable?(%{"network" => "eip155:84532", "extra" => %{}})
    false

# `validate_payload`
*since 0.9.0* 

```elixir
@spec validate_payload(map(), map(), keyword()) ::
  :ok | {:error, {:invalid_auth_capture_payment, X402.AuthCapture.reason()}}
```

Runs the offline shape guard (`X402.Verify.AuthCaptureEVM.validate_shape/2`).

## Examples

    iex> X402.Scheme.AuthCaptureEVM.validate_payload(
    ...>   %{"payload" => %{"salt" => "0x00"}},
    ...>   %{"extra" => %{}},
    ...>   []
    ...> )
    {:error, {:invalid_auth_capture_payment, :payload_format}}

---

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