<!-- Generated raw Markdown for /quickstarts/facilitator; product pin 638fa1e9ca7face19a442cef43754f0d627c7705. -->

The facilitator is the settlement daemon: it serves the payment HTTP API,
derives one-time burn addresses, verifies and settles payments, and runs the
**finalize loop** — the asynchronous half of the two-phase settlement. It is
**source-only**: `subetha-facilitator` is a private workspace package inside
the product repository, published to no registry (npm answers 404 for
`@subetha/facilitator` — see
[Versions & compatibility](/reference/compatibility/)). You build it from the
product repo and run its build output. Everything below is the **local,
non-production** profile; commands and outputs are taken from the pinned
operator runbook,
[`docs/FACILITATOR.md`](https://github.com/peaceandwhisky/SubEtha/blob/638fa1e9ca7face19a442cef43754f0d627c7705/docs/FACILITATOR.md),
and labeled as what that runbook defines.

## 0. Prerequisites

- Node.js, pnpm, and Foundry (`anvil` is the local chain; the runbook treats
  Foundry as a hard prerequisite).
- A running local zERC20 stack — anvil (chain 31337, `:8545`), indexer
  (`:8080`), decider-prover (`:8081`), and your deployed `token` /
  `verifier` / `hub` addresses. Build it with
  [`docs/BUILDING-THE-STACK.md`](https://github.com/peaceandwhisky/SubEtha/blob/638fa1e9ca7face19a442cef43754f0d627c7705/docs/BUILDING-THE-STACK.md),
  start it with
  [`docs/RUNNING-THE-STACK.md`](https://github.com/peaceandwhisky/SubEtha/blob/638fa1e9ca7face19a442cef43754f0d627c7705/docs/RUNNING-THE-STACK.md).

## 1. Get the source and build

```bash
git clone https://github.com/peaceandwhisky/SubEtha
cd SubEtha
pnpm install
pnpm -r build
```

The daemon's CLI is the build output at `apps/facilitator/dist/cli.js`. Do
not look for an npm install path — there isn't one, by design.

## 2. Write a config (TOML), keep secrets in the environment

Copy the annotated reference config and edit it:

```bash
cp apps/facilitator/fac.example.toml fac.toml
$EDITOR fac.toml
```

A minimal local config has this shape (placeholder addresses — use the ones
from **your** local deployment; every `[network]` field is required, with no
defaults, so the daemon can never silently run against the wrong chain):

```toml
profile = "local"        # required for local experiments — see "Profiles" below

[network]                # the zERC20 deployment — ALL fields required
rpc_url = "http://127.0.0.1:8545"
indexer_url = "http://127.0.0.1:8080"
decider_url = "http://127.0.0.1:8081"
chain_id = 31337
token = "0x…"            # your deployed zERC20 token
verifier = "0x…"         # your deployed verifier
hub = "0x…"              # your deployed hub

[listen]
host = "127.0.0.1"       # non-loopback binds require SUBETHA_ADMIN_TOKEN
port = 4032

[settlement]
treasury = "0x…"                          # mint destination
# permit_burner = "0x…"                   # deployed PermitBurner — enables the gasless permit path
journal = "./facilitator-journal.jsonl"   # crash-recovery journal; "none" opts out (local experiments only)
```

Secrets are **environment-only** — they have no defaults and are never read
from the config file:

```bash
export SUBETHA_TREASURY_PK=0x…   # placeholder — seed derivation + custodial fee-sweep signing
export SUBETHA_RELAYER_PK=0x…    # placeholder — teleport mints + gasless permit-burn relaying
# SUBETHA_ADMIN_TOKEN is optional on a local loopback config; unset ⇒ /admin/* is locked (401).
```

The well-known anvil dev keys are accepted (with a warning) **only** when all
four local predicates hold: `profile = "local"`, loopback `listen.host`,
loopback RPC host, and `chain_id` 31337. Any missing predicate aborts
startup. Everywhere else, real keys belong in your own environment
management — never in a file, never in docs. Key-by-key details are in the
[configuration reference](/reference/configuration/).

## 3. Validate without starting

```bash
node apps/facilitator/dist/cli.js check --config fac.toml
```

`check` probes config, RPC, contracts, splitter, journal, and keys, and exits
non-zero with a `✗` line per problem. Against a healthy local stack the
runbook's expected output ends with:

```
✅ configuration checks out
```

## 4. Start

```bash
node apps/facilitator/dist/cli.js start --config fac.toml
```

`start` logs one JSON line per event to stdout; the runbook's expected
readiness marker is the `started` event:

```json
{"ts":"…","level":"info","event":"started","listen":"127.0.0.1:4032","chain_id":31337,…}
```

## Endpoints served

| endpoint | role |
|---|---|
| `GET /supported` | advertises the `subetha-zerc20` kind; resource servers using the official middleware require it at initialization |
| `POST /verify` | read-only substantive check of a payment payload |
| `POST /settle` | executes the payment; **success == accepted** |
| `POST /challenge` | SubEtha extension: mints a fresh one-time burn-address offer for a list price |
| `/admin/*` | operations surface; locked (401) unless `SUBETHA_ADMIN_TOKEN` is set |

Field-by-field request/response shapes are in the
[wire protocol reference](/reference/protocol/#facilitator-http-api). The
finalize loop runs every `daemon.finalize_interval_ms` (default 15000 ms),
driving accepted burns to finalized — that asynchronous half is the reason
[accepted is never finalized](/concepts/accepted-vs-finalized/) on the
request path.

## Profiles: local-only payment acceptance

Payments in the pinned release are **local-experiment only**. The top-level
`profile` key classifies the deployment explicitly — it is never inferred
from bind address or chain id, and an **unset profile is treated as
non-local** (fail-safe). Any non-local profile starts **gated**: `/challenge`,
`/verify`, and `/settle` refuse with profile-gating errors and chain-changing
finalization is frozen. In practice: the daemon accepts payments only with
`profile = "local"`, a loopback bind, a loopback RPC, and chain 31337.

## Next steps

- [Provider quickstart](/quickstarts/provider/) — the resource server that
  points `SubethaFacilitatorClient` at this daemon.
- [Local end-to-end tutorial](/tutorial/local-flow/) — the full
  402 → payment → accepted → finalized walkthrough.
- [Configuration reference](/reference/configuration/) — every TOML key,
  default, and secret.
