A reference implementation of an overlay node built on @bsv/overlay-express. Implements topic managers and lookup services to enable distributed applications to organize and query blockchain data efficiently.
The Overlay Server bootstraps topic managers and lookup services from @bsv/overlay-express. Topic managers validate which transaction outputs are admissible to the overlay by decoding PushDrop-encoded outputs, verifying signatures and cryptographic proofs, and returning AdmittanceInstructions. Lookup services store admitted outputs in MongoDB and respond to queries via the SLAP protocol. The server coordinates with a WalletAdvertiser for overlay advertising and connects to both MongoDB (lookup storage) and MySQL/Knex (overlay transaction tracking).
Clients submit transaction outputs via HTTP, the server routes valid outputs through registered topic managers, stores admitted outputs, and serves queries from any peer.
| Type | Requirement |
|---|---|
| Database | MongoDB (lookup data), MySQL/Knex (overlay tracking) |
| External services | Wallet Storage (service advertisement), Arcade and/or Arc (transaction propagation), Chaintracks/go-chaintracks-compatible headers and reorg stream |
| ts-stack packages | @bsv/sdk, @bsv/overlay-express, @bsv/auth-express-middleware, @bsv/overlay-topics 1.7.0+ for UMP reservations |
| Method | Path | Purpose |
|---|---|---|
| POST | /submit | Submit a tagged BEEF transaction for topic admission and network propagation |
| POST | /lookup | Query a lookup service |
| POST | /arc-ingest | Receive Arc/Arcade provider callbacks and Merkle proofs |
| GET | /health/live | Process liveness |
| GET | /health/ready | Readiness for critical dependencies |
| GET | /health | Full health report with provider/BASM context |
| POST | /admin/syncAdvertisements | Refresh SHIP/SLAP advertisements |
| POST | /admin/startGASPSync | Run GASP sync |
| POST | /admin/startBASMSync | Run BASM sync |
| POST | /admin/refreshUnprovenProofs | Try proof providers for old unproven transactions |
| POST | /admin/evictUnproven | Evict old unproven transactions without proof refresh |
| POST | /admin/maintainUnproven | Refresh proofs, then evict remaining old unproven transactions |
| POST | /admin/evictOutpoint | Remove an outpoint from lookup service indexes |
| POST | /admin/janitor | Run SHIP/SLAP host health checks and cleanup |
Additional endpoints exposed by configured topic managers and lookup services (see src/services/ for ProtoMap, CertMap, BasketMap, UHRP, Identity, MessageBox, UMP, etc.).
The UMP manager and lookup service share the Mongo-backed
ump_identity_reservations collection. The first current UTXO to claim a
presentation or recovery hash owns that value until a transaction consumes the
outpoint. Back up MongoDB before introducing the collection. Existing ambiguous
UMP rows stay queryable for lineage/WAB-pin recovery; the migration does not
delete them.
The infrastructure source capability-gates this wiring so pull-request image
contracts can still build against the latest published package. A production
image does not enable cross-replica reservations until the protected package
release publishes @bsv/overlay-topics 1.7.0 and the generated dependency-sync
PR pins that version in infra/overlay-server.
None (HTTP-only OverlayExpress endpoints).
| Variable | Required | Description |
|---|---|---|
| NODE_NAME | Yes | One-word, lowercase overlay service node identifier |
| SERVER_PRIVATE_KEY | Yes | 32-byte hex root private key for server wallet |
| HOSTING_URL | Yes | Public URL where the node is reachable |
| ADMIN_TOKEN | Yes | Token for admin API access |
| WALLET_STORAGE_URL | Yes | BSV wallet storage endpoint (e.g., https://store-us-1.bsvb.tech) |
| NETWORK | Yes | main or test (BSV blockchain network) |
| ARC_API_KEY | Conditionally | Arc key for fallback transaction broadcasting. Required only when ARCADE_URL is unset. |
| ARC_CALLBACK_TOKEN | No | Shared secret expected on /arc-ingest callbacks. Recommended for public deployments. |
| ARCADE_URL | Conditionally | Arcade endpoint used as the first-choice broadcaster and proof lookup provider. Required only when ARC_API_KEY is unset. |
| ARCADE_API_KEY | No | Arcade API key, when the deployment requires one. |
| ARCADE_DEPLOYMENT_ID | No | Stable Arcade deployment identifier used for callback/proof routing. |
| CHAINTRACKS_URL | No | Explicit go-chaintracks compatible endpoint for headers and reorg SSE. If unset, Arcade can be reused when USE_ARCADE_CHAINTRACKS=true. |
| CHAINTRACKS_API_PREFIX | No | Chaintracks API prefix. Defaults to /chaintracks/v2 for Arcade-mounted Chaintracks. |
| USE_ARCADE_CHAINTRACKS | No | Reuse ARCADE_URL for Chaintracks when CHAINTRACKS_URL is unset. Defaults to true when ARCADE_URL is set. |
| THROW_ON_BROADCAST_FAIL | No | Reject overlay admission if no broadcast provider accepts the transaction. Defaults to true. |
| MONGO_URL | Yes | MongoDB connection string |
| KNEX_URL | Yes | MySQL connection string for Knex |
| GASP_ENABLED | No | true or false (Graph Aware Sync Protocol for overlay sync) |
| BASM_ENABLED | No | Enable BRC-136 BASM synchronization. Defaults to false. |
| BASM_REORG_STREAM_ENABLED | No | Subscribe to Chaintracks reorg SSE when Chaintracks is configured. Defaults to true. |
| BASM_REORG_SCAN_DEPTH | No | Number of recent blocks to revalidate on reorg reconnect/poll. |
| BASM_BLOCK_POLL_INTERVAL_MS | No | Interval for BASM anchor/header polling. Set to 0 to disable periodic polling. |
| UNPROVEN_EVICTION_BLOCKS | No | Block-age threshold for unproven transaction eviction. |
| UNPROVEN_MAINTENANCE_INTERVAL_MS | No | Periodic refresh-then-evict cadence for unproven transactions. 0 disables periodic maintenance. |
| LOG_LEVEL | No | pino log level. Defaults to info. |
| OTEL_* | No | OpenTelemetry exporter/resource configuration. See infra/OBSERVABILITY.md. |
At least one transaction propagation provider must be configured:
ARCADE_URL or ARC_API_KEY. Production deployments should prefer
Arcade-first plus Arc fallback when both are available.
# Install dependencies
npm install
# Development with hot-reload (uses tsx)
npm run dev
# Build TypeScript to dist/
npm run build
# Run production build
npm start
# Full stack with Docker Compose (app + MongoDB + MySQL)
docker compose up --build# Multi-stage build: Node builder → production runtime
docker build -t overlay-server:latest .
# Run with environment variables
docker run -d \
-e NODE_NAME=overlay-node-1 \
-e SERVER_PRIVATE_KEY=<32-byte-hex> \
-e HOSTING_URL=https://overlay.example.com \
-e ADMIN_TOKEN=<secure-token> \
-e WALLET_STORAGE_URL=https://store-us-1.bsvb.tech \
-e NETWORK=main \
-e ARCADE_URL=https://arcade-v2-us-1.bsvblockchain.tech \
-e ARCADE_API_KEY=<arcade-key> \
-e ARCADE_DEPLOYMENT_ID=overlay-node-1 \
-e ARC_API_KEY=<arc-key> \
-e ARC_CALLBACK_TOKEN=<callback-token> \
-e USE_ARCADE_CHAINTRACKS=true \
-e BASM_ENABLED=true \
-e UNPROVEN_EVICTION_BLOCKS=144 \
-e UNPROVEN_MAINTENANCE_INTERVAL_MS=3600000 \
-e MONGO_URL=mongodb://mongo:27017/overlay \
-e KNEX_URL=mysql://user:pass@mysql:3306/overlay \
-p 8080:8080 \
overlay-server:latest
# Or with Docker Compose (includes MongoDB, MySQL, janitor service)
docker compose up -dService listens on port 8080 by default. Kubernetes deployment files available in deploy/ (app-deployment.yaml, mongodb, mysql with persistent volumes).
Managed by @bsv/overlay-express and Knex. Auto-run on startup. Tables: outputs, topic_managers, lookup_services, with indexes on identity_key, output_hash, blockchain_height.
The deployment wrapper configures providers in this order:
ARCADE_URL is set.ARC_API_KEY is set.CHAINTRACKS_URL, or from
ARCADE_URL when USE_ARCADE_CHAINTRACKS=true.THROW_ON_BROADCAST_FAIL=true is the production default. With that setting, a
submitted transaction is not committed to overlay state unless a provider accepts
it or reports it already known. Transient provider errors should be retried by the
client or caller; terminal provider errors are not treated as successful overlay
admission.
Provider callbacks posted to /arc-ingest are used to attach proofs or mark
terminal outcomes. Double-spend or terminal invalid callbacks evict the
transaction from admitted overlay state and notify lookup services through the
normal eviction path.
When UNPROVEN_MAINTENANCE_INTERVAL_MS is greater than zero, the server
periodically runs proof refresh followed by unproven eviction. The same behavior
is available manually through POST /admin/maintainUnproven.
Use:
GET /health/live for Kubernetes liveness.GET /health/ready for readiness.GET /health for operator diagnostics.The full health response includes provider context showing whether Arc, Arcade,
and Chaintracks are configured, plus BASM and unproven-maintenance settings.
Alert on readiness failures, repeated provider callback errors, repeated
overlay.unproven_maintenance failures, and increasing unproven transaction
counts.
tm_, lookup service IDs with ls_CHAINTRACKS_URL or
USE_ARCADE_CHAINTRACKS=true should be configured so anchors use canonical
block headers and reorg handling.THROW_ON_BROADCAST_FAIL=true unless the deployment intentionally accepts
local overlay admission while broadcast providers are unavailable./chaintracks/v2; a standalone go-chaintracks
deployment may use a different prefix, so set CHAINTRACKS_API_PREFIX
explicitly when needed.