> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polygon.technology/llms.txt
> Use this file to discover all available pages before exploring further.

# Run a Paychannels hub

> Operate your own Paychannels hub: deploy a channel contract with a verifier set, run the hub engine, verifiers, and facilitator, and monitor settlements.

This guide shows you how to run your own Paychannels hub, so your platform can process payments under its own brand and settle them to Polygon on its own schedule. It assumes you are comfortable operating Linux services and EVM contracts.

<Note>
  Hub operator binaries and contracts are available through early access. [Contact Polygon](https://polygon.technology/get-access) to get the operator release.
</Note>

## What a hub is

A hub is the service that holds Paychannels accounts and processes their payments. Payers deposit once into the hub's channel contract on Polygon and register a session key. From then on, every payment is a signed voucher that the hub verifies, applies to its in-memory ledger, and writes to its journal on disk. Nothing touches the chain per payment.

Once per epoch, the hub posts a single settlement root that covers every account balance, about 112,500 gas no matter how many payments or payers it covers. Accounts cash out separately with `requestWithdraw` and `withdrawAttested`, about 96,700 gas per account. Independent verifiers must sign each root before the contract accepts it, so the operator never holds the money. See [Trust model](/pos/paychannels/trust-model).

Merchants and agents reach the hub through a facilitator, the x402 endpoint that accepts payments over HTTP and streams them to the hub. The facilitator is open: any address can be paid, with no allowlist or registration.

A platform can run a hub in three ways:

* **Run a hub** for its own users and merchants, with its own brand on receipts and its own settlement cadence.
* **Embed the facilitator** in an existing edge, gateway, or API platform, so the services behind it can charge per request.
* **Offer per-request billing as a product**, where merchants add one integration and the platform owns the relationship and the volume.

## How hubs scale

Hubs do not coordinate on the payment path. Each hub serves its own accounts, so capacity adds up as you add hubs:

| Measurement | Verified payments per second |
| - | - |
| One hub on a 16-vCPU server, as part of the fleet run | About 450,000 |
| 100 hubs, sustained for 10 minutes | 45,017,796 |

Settlement cost grows with the number of hubs and epochs, not with the number of payments: each hub posts one root per epoch whether it settled one payment or 100 million. One facilitator can serve one hub or many, and you can run a facilitator in each region close to your users. See [Performance](/pos/paychannels/overview#performance) for the full benchmark.

## What you will run

A hub deployment has three required services and two optional ones:

| Service | Binary | Role |
| - | - | - |
| Hub engine | `engine serve` | Verifies and applies payments, keeps the ledger and journal, closes epochs, and posts settlements |
| Verifiers | `tp-verifier` (one per signer) | Re-check each epoch's evidence and sign the settlement root |
| Facilitator | `facilitator` | The x402 endpoint merchants call: `/quote`, `/settle`, `/verify`, `/meta` |
| Indexer (optional) | `indexer` | Payment explorer and owner-signed account reads |
| Claim runner (optional) | `claim-runner` | Automated withdrawals for an account |

The engine and verifiers communicate over a private network. Only the facilitator, and the indexer if you run it, need to be reachable from the internet.

You will also need an RPC endpoint for the chain your hub settles on, and a funded key for the operator to post settlements.

## Try the full stack locally first

The operator release includes a local stack that starts a development chain, deploys a hub with three verifiers, runs payments end to end, withdraws, and checks that funds balance exactly. It needs `anvil`, `forge`, `cast`, `cargo`, `jq`, `curl`, and `python3`:

```bash theme={null}
just build
just demo-local
```

The run takes about 40 seconds once built. Use it to confirm your toolchain before deploying anywhere else.

## Generate shared secrets

The engine and every verifier share two secrets. Generate them once and install them on every host that runs either service:

```bash theme={null}
# Blinding key ring: salts each epoch's account commitments (see Privacy)
printf '0 %s\n' "$(openssl rand -hex 32)" > blind-key.txt

# Evidence token: gates the operator- and verifier-only endpoints
openssl rand -hex 24 > evidence-token.txt

chmod 600 blind-key.txt evidence-token.txt
```

<Warning>
  Back up `blind-key.txt`. If you lose it, you cannot recompute or re-attest past epochs' roots. The ring is read once at startup, so appending a new key takes effect only after you restart the engine and every verifier.
</Warning>

Also create:

* An **operator key** for the engine, funded with gas. It posts settlement roots.
* One **signer key per verifier**. Verifier keys never hold funds.
* A **submitter key** for the facilitator, funded with gas. It broadcasts direct (`exact`) payments.

## Deploy the channel contract

Deploy a channel contract with your verifier set and threshold using the deploy script in the operator release. Give it your RPC URL, a deployer key, the verifier signer addresses (`VERIFIERS`, comma-separated), and the signature threshold (`ATTEST_THRESHOLD`). The script refuses to deploy a configuration whose delays are inconsistent, and it appends the new deployment to a deployments file that every service reads.

The deployments file records the hub address, the settlement asset, the deploy block, the verifier set, and the delays. Note the hub address and deploy block for the next steps.

## Start the verifiers

Run one verifier per signer key. Each verifier reads the hub's evidence, so point it at the engine's HTTP address:

```bash theme={null}
tp-verifier \
  --listen 10.0.0.2:9600 \
  --rpc-url "$RPC_URL" \
  --chain-id "$CHAIN_ID" \
  --deployments deployments.json \
  --hubs 0 \
  --signer-key "$VERIFIER_SIGNER_KEY" \
  --data-dir /var/lib/paychannels/verifier-0 \
  --confirmation-depth 15 \
  --blind-key-file /etc/paychannels/blind-key.txt \
  --evidence-token-file /etc/paychannels/evidence-token.txt \
  --evidence-base-url http://10.0.0.1:9100
```

`--hubs` selects hubs by their index in the deployments file, so `0` is the first hub. A verifier that cannot read its blinding key ring refuses to start.

## Start the hub engine

```bash theme={null}
engine serve \
  --listen 10.0.0.1:9100 \
  --grpc-listen 10.0.0.1:10100 \
  --hub "$HUB_ADDRESS" \
  --asset "$USDC_ADDRESS" \
  --operator-key "$OPERATOR_KEY" \
  --rpc-url "$RPC_URL" \
  --chain-id "$CHAIN_ID" \
  --data-dir /var/lib/paychannels/engine-0 \
  --watch-from-block "$DEPLOY_BLOCK" \
  --confirmation-depth 15 \
  --epoch-interval-secs 600 \
  --ack-durability fsync \
  --verifiers http://10.0.0.2:9600,http://10.0.0.3:9600,http://10.0.0.4:9600 \
  --attest-threshold 2 \
  --blind-key-file /etc/paychannels/blind-key.txt \
  --evidence-token-file /etc/paychannels/evidence-token.txt
```

The key flags:

* `--grpc-listen` is the only way a facilitator sends payments into the hub. By convention it is the HTTP port plus 1000. It accepts connections only from private address ranges unless you change `--ingress-allow-cidr`.
* `--watch-from-block` starts the deposit and withdrawal watcher at your deploy block.
* `--epoch-interval-secs` sets how often the hub closes an epoch and posts a settlement. Shorter intervals shrink the window in which new earnings cannot yet be withdrawn.
* `--ack-durability` controls when a payment is acknowledged. `fsync` acknowledges only after the payment is on disk. `async` acknowledges once the payment is applied and queued, which is about four times faster but can lose the last few acknowledged payments in a crash. See [when a receipt is final](/pos/paychannels/trust-model#when-a-receipt-is-final).
* `--min-delta-floor` (default `100`, or \$0.0001) rejects payments below a minimum amount to limit ledger growth.

Run `engine serve --help` for the full flag list.

## Start the facilitator

```bash theme={null}
facilitator \
  --listen 0.0.0.0:9200 \
  --rpc-url "$RPC_URL" \
  --chain-id "$CHAIN_ID" \
  --deployments deployments.json \
  --engine-url http://10.0.0.1:9100 \
  --engine-grpc http://10.0.0.1:10100 \
  --engine-token-file /etc/paychannels/evidence-token.txt \
  --submitter-key "$FACILITATOR_SUBMITTER_KEY" \
  --data-dir /var/lib/paychannels/facilitator-0
```

Put the facilitator behind TLS and publish its URL. Merchants point their integrations at it, and agents discover your hub from its `/meta` endpoint. There is no merchant allowlist: any address can be paid.

## Check that it works

Confirm each service is ready:

```bash theme={null}
curl -s http://10.0.0.1:9100/readyz         # engine: {"ready":true,"ackDurability":"fsync",...}
curl -s https://<facilitator-host>/readyz   # facilitator: 200 when it can serve payments
curl -s https://<facilitator-host>/meta | jq '.hubs'
```

Then run through the terminal steps in [Try a demo](/pos/paychannels/try-a-demo#from-your-terminal) with `SITE_URL` and `FACILITATOR_URL` pointed at your own deployment. After the first epoch interval passes, your engine posts its first attested settlement root onchain.

## Monitor the hub

The engine and facilitator expose Prometheus metrics at `/metrics`. Watch these first:

| Metric | What to watch for |
| - | - |
| `tp_engine_journal_flush_lag_records` | In `async` mode, the live number of acknowledged payments not yet on disk. Alert if it grows. |
| `tp_engine_ingress_batch_size` | The main throughput lever. A rising median means payments are being batched efficiently. |
| `tp_engine_ingress_rate_limited_frames_total` | Should stay at 0 unless you configured rate limits. |
| `tp_engine_idempotency_evictions_total` | Nonzero means the retry deduplication window is shorter than 24 hours. |

`/readyz` returns `503` if the journal writer or ingress stops. The engine fails closed and should be restarted by your process supervisor.

## Rotate verifiers

Verifier set changes are made onchain in two steps: propose the new set, then activate it after the rotation delay. The outgoing set stays valid for one more delay period, so settlements continue during the change.

## Related

* [Trust model](/pos/paychannels/trust-model): what verifiers check and what the operator is trusted for.
* [Privacy](/pos/paychannels/privacy): how the blinding key protects account data.
* [Accept Paychannels payments](/pos/paychannels/accept-payments): the merchant side of your facilitator.
