X402.Facilitator (X402 v0.6.0)

Copy Markdown View Source

Client for the x402 facilitator API: verify, settle, supported, discovery.

The facilitator process is a supervised configuration holder: it resolves and stores connection settings (URL, Finch pool, hooks, retry policy, auth state) once at startup. The HTTP work for verify/2, settle/2, supported/1, and list_resources/2 — including retries with backoff, lifecycle hooks, telemetry spans, and per-request auth header minting — executes in the calling process. Concurrent payment operations therefore never serialize behind the facilitator process; throughput is bounded only by the Finch pool.

Because operations run in the caller, X402.Hooks callbacks are invoked in the calling process (not in the facilitator process), and the duration of an operation is bounded by the configured :receive_timeout_ms and retry policy rather than by a GenServer.call/3 timeout.

Summary

Payment Verification

Verifies a payment using the default facilitator process name.

Verifies a payment using the given facilitator process.

Verifies a payment using the given facilitator process and hook module.

Payment Settlement

Settles a payment using the default facilitator process name.

Settles a payment using the given facilitator process.

Settles a payment using the given facilitator process and hook module.

Facilitator Discovery

Lists discoverable x402 resources from the facilitator's bazaar.

Fetches the payment kinds, extensions, and signers a facilitator supports.

Types

Pagination metadata returned by GET /discovery/resources.

Facilitator response payload, including values recovered or transformed by hooks.

Facilitator server identifier accepted by GenServer.call/3.

One supported payment kind advertised by GET /supported.

Validated response of supported/1.

Functions

Returns a child specification for X402.Facilitator.

Starts the facilitator client.

Payment Verification

verify(payment_payload, requirements)

(since 0.1.0)
@spec verify(map(), map()) :: response()

Verifies a payment using the default facilitator process name.

verify(server, payment_payload, requirements)

(since 0.1.0)
@spec verify(server(), map(), map()) :: response()

Verifies a payment using the given facilitator process.

The HTTP request (including retries, hooks, and telemetry) executes in the calling process; the facilitator process is only consulted for its configuration.

verify(server, payment_payload, requirements, hooks_module)

(since 0.1.0)
@spec verify(server(), map(), map(), module()) :: response()

Verifies a payment using the given facilitator process and hook module.

This overrides the hook module configured when the facilitator process started. Hook callbacks run in the calling process.

Payment Settlement

settle(payment_payload, requirements)

(since 0.1.0)
@spec settle(map(), map()) :: response()

Settles a payment using the default facilitator process name.

settle(server, payment_payload, requirements)

(since 0.1.0)
@spec settle(server(), map(), map()) :: response()

Settles a payment using the given facilitator process.

The HTTP request (including retries, hooks, and telemetry) executes in the calling process; the facilitator process is only consulted for its configuration.

settle(server, payment_payload, requirements, hooks_module)

(since 0.1.0)
@spec settle(server(), map(), map(), module()) :: response()

Settles a payment using the given facilitator process and hook module.

This overrides the hook module configured when the facilitator process started. Hook callbacks run in the calling process.

Facilitator Discovery

list_resources(server_or_params \\ X402.Facilitator, params \\ [])

(since 0.6.0)
@spec list_resources(
  server() | keyword(),
  keyword()
) ::
  {:ok, discovery_resources_response()}
  | {:error, X402.Facilitator.Error.t() | NimbleOptions.ValidationError.t()}

Lists discoverable x402 resources from the facilitator's bazaar.

Performs GET /discovery/resources in the calling process. Filter and pagination parameters are validated with NimbleOptions and encoded as query string parameters. The response is validated fail-closed: a malformed body returns {:error, %X402.Facilitator.Error{type: :malformed_facilitator_response}}.

Items are returned as raw, string-keyed maps exactly as sent by the facilitator. X402.Hooks callbacks do not apply to this read-only operation.

When called with just a keyword list — list_resources(limit: 20) — the parameters apply to the default facilitator process name.

Parameters

  • :type (String.t/0) - Filter by resource type (for example "http" or "mcp").

  • :pay_to (String.t/0) - Filter by payment recipient address (sent as payTo).

  • :scheme (String.t/0) - Filter by payment scheme (for example "exact").

  • :network (String.t/0) - Filter by CAIP-2 payment network (for example "eip155:8453").

  • :extensions (String.t/0) - Filter by extension key present on each discovered resource.

  • :limit - Maximum number of results to return (1–100; server default 20).

  • :offset (non_neg_integer/0) - Number of results to skip for pagination.

Examples

{:ok, %{items: items, pagination: pagination}} =
  X402.Facilitator.list_resources(MyFacilitator,
    network: "eip155:8453",
    limit: 20
  )

supported(server \\ X402.Facilitator)

(since 0.6.0)
@spec supported(server()) ::
  {:ok, supported_response()} | {:error, X402.Facilitator.Error.t()}

Fetches the payment kinds, extensions, and signers a facilitator supports.

Performs GET /supported in the calling process and validates the response fail-closed: a malformed body returns {:error, %X402.Facilitator.Error{type: :malformed_facilitator_response}} rather than partial data. Missing extensions and signers fields default to [] and %{} (matching the reference TypeScript client); a missing or malformed kinds field is an error.

X402.Hooks callbacks do not apply to this read-only operation.

Examples

{:ok, %{kinds: kinds, extensions: _, signers: signers}} =
  X402.Facilitator.supported(MyFacilitator)

Enum.any?(kinds, &(&1.scheme == "exact" and &1.network == "eip155:8453"))

Types

discovery_pagination()

@type discovery_pagination() :: %{
  limit: non_neg_integer(),
  offset: non_neg_integer(),
  total: non_neg_integer()
}

Pagination metadata returned by GET /discovery/resources.

discovery_resources_response()

@type discovery_resources_response() :: %{
  x402_version: integer() | nil,
  items: [map()],
  pagination: discovery_pagination() | nil
}

Validated response of list_resources/2.

Each item is the raw, string-keyed discovered-resource map from the wire.

operation_result()

@type operation_result() :: map()

Facilitator response payload, including values recovered or transformed by hooks.

response()

@type response() ::
  {:ok, operation_result()}
  | {:error, X402.Facilitator.Error.t() | X402.Hooks.hook_error() | term()}

server()

@type server() :: GenServer.server()

Facilitator server identifier accepted by GenServer.call/3.

state()

@type state() :: %{
  url: String.t(),
  finch: term(),
  hooks: module(),
  auth: nil | X402.Facilitator.Auth.t(),
  max_retries: non_neg_integer(),
  retry_backoff_ms: non_neg_integer(),
  receive_timeout_ms: non_neg_integer()
}

supported_kind()

@type supported_kind() :: %{
  x402_version: integer(),
  scheme: String.t(),
  network: String.t(),
  extra: map() | nil
}

One supported payment kind advertised by GET /supported.

supported_response()

@type supported_response() :: %{
  kinds: [supported_kind()],
  extensions: [String.t()],
  signers: %{optional(String.t()) => [String.t()]}
}

Validated response of supported/1.

Functions

child_spec(init_arg)

(since 0.1.0)
@spec child_spec(keyword()) :: Supervisor.child_spec()

Returns a child specification for X402.Facilitator.

start_link(opts)

(since 0.1.0)
@spec start_link(keyword()) ::
  GenServer.on_start() | {:error, NimbleOptions.ValidationError.t()}

Starts the facilitator client.

When an otp_app is given, options are merged over the config :app, <name> configuration entry, with the explicit options taking precedence. This enables configuring the facilitator at runtime without hardcoding secrets:

# config/runtime.exs
config :my_app, MyX402,
  url: X402.Facilitator.Auth.CDP.facilitator_url(),
  finch: MyFinch,
  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")}

# application.ex
children = [{X402.Facilitator, otp_app: :my_app, name: MyX402}]

Options

  • :name (term/0) - Registered name of the facilitator client process. The default value is X402.Facilitator.

  • :otp_app (atom/0) - Application that holds this facilitator's configuration. When set, config :app, <name> is merged under the given options, with the options taking precedence. Enables the Ecto-style pattern where config/runtime.exs is the single source of truth. Available since v0.5.0.

  • :url (String.t/0) - Facilitator base URL. The default value is "https://x402.org/facilitator".

  • :finch (term/0) - Required. Finch process name used for HTTP requests.

  • :hooks - Lifecycle hook module implementing X402.Hooks. The default value is X402.Hooks.Default.

  • :max_retries (non_neg_integer/0) - Maximum retry count for transient errors. The default value is 2.

  • :retry_backoff_ms (non_neg_integer/0) - Initial retry backoff in milliseconds. The default value is 100.

  • :receive_timeout_ms (non_neg_integer/0) - HTTP receive timeout in milliseconds. The default value is 5000.

  • :auth - Request authentication. Either nil (no authentication), an X402.Facilitator.Auth module, or a {module, opts} tuple. See X402.Facilitator.Auth.CDP for the Coinbase Developer Platform facilitator. Available since v0.5.0. The default value is nil.