# `X402.Facilitator.Auth.CDP`
[🔗](https://github.com/cardotrejos/x402/blob/v0.9.0/lib/x402/facilitator/auth/cdp.ex#L1)

Authentication for the Coinbase Developer Platform (CDP) x402 facilitator.

CDP's hosted facilitator (`facilitator_url/0`) requires an
`Authorization: Bearer <JWT>` header on every request. The JWT is an EdDSA
or ES256 signed token carrying the API key id and a `uris` claim binding it
to the exact request.

## API keys

Credentials are passed to `new/1` via the `:api_key_id` and
`:api_key_secret` options. In applications that want a single source of
truth at runtime, put them in application configuration and let the
facilitator resolve them (see the `otp_app` option on
`X402.Facilitator.start_link/1`):

    # config/runtime.exs
    config :my_app, MyX402,
      auth: {X402.Facilitator.Auth.CDP,
             api_key_id: System.fetch_env!("CDP_API_KEY_ID"),
             api_key_secret: System.fetch_env!("CDP_API_KEY_SECRET")}

Two API key secret formats are supported, matching the CDP SDK:

  * **Ed25519** — base64 of the 64-byte private key (32-byte seed + 32-byte
    public key). This is the default for new API keys.
  * **EC (P-256)** — a PEM `EC PRIVATE KEY` (SEC1) or PKCS#8 private key.
    Used by legacy API keys.

The secret format is detected automatically; no configuration is required.

## Usage

    X402.Facilitator.start_link(
      finch: MyFinch,
      url: X402.Facilitator.Auth.CDP.facilitator_url(),
      auth: {X402.Facilitator.Auth.CDP, api_key_id: "...", api_key_secret: "..."}
    )

The JWT is generated per facilitator operation with a fresh nonce and
timestamps. Transport retries reuse it within its 120-second validity
window. The `aud` claim is intentionally omitted to match the reference CDP
SDK's x402 facilitator client.

# `key_format`

```elixir
@type key_format() :: :ed25519 | :ecdsa_p256
```

API key secret format.

# `t`

```elixir
@type t() :: %X402.Facilitator.Auth.CDP{
  api_key_id: String.t(),
  key_format: key_format(),
  key_material: binary()
}
```

CDP auth state.

# `facilitator_url`
*since 0.5.0* 

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

Returns the CDP x402 facilitator base URL.

Note that this URL is never used as a default; a facilitator must be
configured with an explicit `url:` option.

# `headers`
*since 0.5.0* 

```elixir
@spec headers(t(), X402.Facilitator.Auth.request_info()) ::
  {:ok, [{String.t(), String.t()}]}
```

Builds the `Authorization` (and `Correlation-Context`) headers for a request.

The JWT binds the request method, host, and path in its `uris` claim and is
signed fresh each time headers are built; transport retries within one
facilitator operation reuse the same token inside its 120-second validity
window.

# `new`
*since 0.5.0* 

```elixir
@spec new(keyword()) :: {:ok, t()} | {:error, term()}
```

Builds CDP auth state from `:api_key_id` and `:api_key_secret` options.

Returns `{:error, reason}` when credentials are missing or the secret is not
a valid Ed25519 or P-256 key. For config-driven credentials, see the
`otp_app` option on `X402.Facilitator.start_link/1`.

---

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