Chaintracks Server

Chaintracks Server is the reference implementation for BSV block header management. It maintains a complete chain of block headers and exposes a REST API for header lookup and Merkle proof validation — the header-side half of Simplified Payment Verification (SPV). Source lives in infra/chaintracks-server.

The Chaintracks primitives and client interface are defined in @bsv/wallet-toolbox. This server is the Express deployment wrapper around ChaintracksService from that package.

What it does

  • Wraps ChaintracksService from @bsv/wallet-toolbox behind an Express HTTP server
  • Maintains a chain of headers from genesis to the current tip via bulk + live ingestors
  • Exposes JSON v1 (legacy) and v2 (RESTful, with binary variants) APIs
  • Provides bulk header download in concatenated 80-byte format for SPV clients

Startup and Bootstrap

On first start, Chaintracks must acquire all existing BSV block headers before serving SPV queries. The bootstrap sequence:

  1. Bundled files — Repository ships with bulk header files. Used for initial ingest when no CDN URL is configured.
  2. CDN bulk ingest — If CHAINTRACKS_CDN_URL is set (typically another running Chaintracks server), headers are fetched in 100,000-block batches. Fastest path.
  3. WhatsOnChain bulk ingester — Fallback when bundled files and CDN are unavailable.
  4. Live tip sync — Once bulk headers are loaded, switches to live mode via Teranode P2P or the WhatsOnChain live ingester.

API

Two API surfaces are mounted on the same port (default 3011):

v1 (JSON, legacy)

MethodPathPurpose
GET/getChainNetwork name (main or test)
GET/getInfoService state: heights, storage backend, ingestors
GET/getPresentHeightLatest external blockchain height
GET/findChainTipHashHexActive chain tip hash
GET/findChainTipHeaderHexActive chain tip header
GET/findHeaderHexForHeight?height=NHeader at height
GET/findHeaderHexForBlockHash?hash=HHeader for hash (live storage)
GET/getHeaders?height=N&count=MConcatenated 80-byte hex header batch
GET/getFiatExchangeRatesBSV fiat exchange rates
POST/addHeaderHexSubmit a new block header for processing

v2 (RESTful, JSON + binary)

Mirrors the go-chaintracks v2 contract. All responses use the {status, value} / {status, code, description} envelope; binary variants return raw 80-byte headers with X-Block-Height / X-Start-Height / X-Header-Count headers.

MethodPathPurpose
GET/v2/networkNetwork name
GET/v2/tipChain tip header (JSON)
GET/v2/tip.binChain tip header (80-byte binary)
GET/v2/header/height/:heightHeader at height (JSON)
GET/v2/header/height/:height.binHeader at height (binary)
GET/v2/header/hash/:hashHeader by hash (JSON)
GET/v2/header/hash/:hash.binHeader by hash (binary)
GET/v2/headers?height=N&count=MHeader batch (binary, JSON envelope omitted)
GET/v2/headers.bin?height=N&count=MHeader batch (binary)

The v2 surface is exercised by the sync.chaintracks-v2-http conformance vectors so cross-language implementations (go-chaintracks, future Rust/Python ports) can be validated against the same contract.

Configuration

bash
PORT=3011                                  # HTTP listen port
CHAIN=main                                 # main | test
CHAINTRACKS_CDN_URL=https://chaintracks-us-1.bsvb.tech   # CDN bootstrap source
WHATS_ON_CHAIN_LIVE=true                   # Use WhatsOnChain live ingester instead of Teranode

Teranode P2P live ingest requires bootstrap peer configuration.

When to deploy this

  • Running @bsv/wallet-toolbox-based wallets in production (the toolbox calls Chaintracks for SPV)
  • Need in-house Merkle root validation instead of relying on a third-party instance
  • Building services that need to validate BEEF packages server-side

When NOT to deploy this

  • Development and testing — use the hosted Chaintracks instance or the bundled files
  • If another Chaintracks instance is already available in your infrastructure