Self-host Fiber Offers
Each merchant can run an independent Fiber Offers deployment connected to a Fiber node they own. There is no required central Fiber Offers account, shared platform key, or hosted control plane.
What you operate
| Component | Location | Responsibility |
|---|---|---|
| Merchant Fiber node | Private server process | Owns funds and keys, creates invoices, and receives Fiber payments. |
| Resolver and dashboard | Docker, exposed through HTTPS for public use | Publishes offers, requests invoices from the merchant node, and exposes payment state. |
| PostgreSQL | Private Docker network or managed database | Stores offers, resolutions, webhooks, and reconciliation records. |
| Redis and worker | Private Docker network | Coordinates rate limits, settlement polling, and webhook delivery across replicas. |
| CLI | Merchant computer or server | Generates lifecycle keys locally and manages offers. |
| Payer wallet or SDK | Payer device | Requests an invoice and pays it through the payer's own Fiber node. |
The node-to-resolver bridge
The resolver is the application bridge to the merchant node. It calls node_info, new_invoice, and get_invoice over the node's private JSON-RPC endpoint. It never receives the Fiber node seed or private key.
Merchant Fiber node (127.0.0.1:8227)
-> host relay
-> private Unix socket
-> Fiber RPC proxy
-> resolver replicas
-> public dashboard, API, CLI, and SDK clients
The included Docker relay lets the Fiber node remain bound to host loopback. For a remote private RPC endpoint, configure FIBER_RPC_URL directly and add RPC credentials when required.
Initialize a merchant deployment
Start and fund the merchant Fiber node first. Its RPC defaults to http://127.0.0.1:8227.
npm install
npm run cli -- init \
--resolver-url https://offers.merchant.example \
--fiber-rpc-url http://127.0.0.1:8227
The command creates a mode-0600 .env with random values and a mode-0700 lifecycle-key directory. Run it before the first Docker startup because PostgreSQL applies its configured password when initializing a new volume.
| Setting | Purpose | Where it belongs |
|---|---|---|
RESOLVER_API_KEY | Authorizes merchant registration and operator actions. | Server, trusted CLI, or merchant backend only. |
RESOLVER_SECRET_ENCRYPTION_KEY | Encrypts persisted webhook secrets. | All API and worker replicas; never a browser bundle. |
POSTGRES_PASSWORD | Protects the merchant database. | Database and resolver deployment only. |
FIBER_RPC_HOST / FIBER_RPC_PORT | Selects the private merchant node endpoint used by the Docker relay. | Server environment only. |
RESOLVER_PUBLIC_URL | Sets the public origin embedded in offers and payment links. | Server environment; must be the final HTTPS origin. |
cli init or use a secret manager before exposing a deployment publicly. Preserve the encryption key while encrypted records exist.Start and prove the connection
docker compose up -d --build
npm run cli -- doctor
doctor verifies resolver health, calls the host-reachable Fiber node, and confirms that the CLI and resolver report the same node public key. Open the resolver URL and unlock the dashboard with RESOLVER_API_KEY; the browser exchanges it for a signed HttpOnly session cookie.
npm run cli -- create \
--description "Merchant checkout" \
--amount 100000000 \
--username merchant
npm run cli -- list
The CLI signs the offer locally, stores its lifecycle private key, registers the public offer with the resolver, and prints the offer ID and payment URL.
What happens when someone pays
- The payer opens the public offer link or resolves the offer with the SDK.
- The resolver validates the request and calls
new_invoiceon the merchant Fiber node. - The payer sends that invoice through their own Fiber wallet or node. Payment funds do not pass through the resolver.
- The worker polls
get_invoiceon the merchant node every three seconds by default. - The resolver updates PostgreSQL, the dashboard, receipts, reconciliation records, and webhooks.
A payer needs only the public resolver URL plus a Fiber-capable wallet or node. The payer never receives the merchant API key, encryption key, database password, lifecycle key, or Fiber RPC credentials.
Horizontal Docker deployment
The supplied Compose stack runs two resolver replicas behind Nginx. Both replicas use the same PostgreSQL database, Redis namespace, API key, encryption key, public URL, and merchant Fiber RPC endpoint. A separate worker owns settlement polling and webhook retries so API replicas do not duplicate background work.
resolver-1 --\
+-> PostgreSQL
resolver-2 --/ +-> Redis -> worker
| |
+-> Fiber RPC proxy-+-> merchant Fiber node
Back up the PostgreSQL volume, .env or secret-manager entries, and .fiber-offers/keys together. Redis append-only data is operational state, but PostgreSQL and lifecycle keys are authoritative business records.
Public deployment checklist
- Point a domain at the server and terminate TLS at a trusted ingress.
- Expose only the HTTPS resolver gateway; keep Fiber RPC, PostgreSQL, and Redis private.
- Set the final
RESOLVER_PUBLIC_URLbefore publishing offers. - Use generated production secrets and keep the same encryption key on every API and worker replica.
- Run
doctor,npm run smoke, and the live Fiber E2E check before accepting payments. - Monitor
GET /healthandGET /diagnostics, worker failures, and webhook delivery failures.
See Production and security for hardening and troubleshooting, and Fiber integration for topology and live route checks.