CLI management and orchestration tool for the XChain Platform. Installs, configures, and manages all XChain services and coin nodes (bitcoind, litecoind, dogecoind) as Docker containers. Generates per-service environment variables from a two-layer configuration system, manages LevelDB state, provisions MariaDB databases, and provides multi-pane log monitoring.
- Multi-chain orchestration: manages Bitcoin, Litecoin, and Dogecoin across mainnet, testnet, and regtest; each chain/network gets its own Docker network and container set
- Order-independent argument parsing: CLI arguments auto-classified as service, coin, network, or branch name regardless of position
- Docker container lifecycle: install, start, stop, restart, update, uninstall, and reset services with single commands
- Configuration generation: two-layer system (hardcoded defaults + config file overrides) producing 40+ environment variables per service
- Crypto node management: downloads Bitcoin Core, Litecoin, and Dogecoin binaries from official sources with SHA-256 verification; includes per-chain regtest tuning applied automatically
- Database orchestration: provisions shared MariaDB, creates per-service databases and users with subnet-based permissions
- Bootstrap snapshots: create and restore gzipped snapshots of UTXO tracker, decoder, and indexer data; integrity is double-verified with SHA-256 checksums and a detached Ed25519 signature pinned to a bundled public key
- Validator mode:
validator initgenerates an Ed25519 signing key and capabilities config; the hub boots in PBFT validator mode when a key is present - Anonymous telemetry: opt-out usage ping reports service versions and running module set; IP is never stored; respects
--no-telemetry, env var, or preference file - Multi-pane monitoring: Blessed terminal UI showing live logs from up to 6 containers in split-screen
- Pre-flight checks: Docker verification, directory creation, LevelDB open, remote version fetch, Docker network creation, and stale container-registry GC on every command
- Go-live gate: asserts safe launch settings together at the one chokepoint every service deploy passes through; warns pre-launch, refuses a mainnet write surface once
XCHAIN_NODE_GO_LIVE=1is set (escape hatch:XCHAIN_NODE_SKIP_GO_LIVE_GATE=1, logged loudly) - Skew guard: refuses an
updatethat would deploy a downstream module (e.g. the indexer) past the hub version it requires, per axchainRequiresHubminimum-semver field in the module's ownpackage.json - Container auto-discovery: rebuilds the module-to-container-ID registry from
docker ps -awhen it drifts from LevelDB state, since container names deterministically encode module/coin/network - Credentials persistence: accepted MariaDB root passwords persist per-OS-user to
~/.xchain-node/credentials.json(0600), ping-verified and reused as a non-interactive fallback - State persistence: LevelDB maps each module to its 64-char container ID via composite keys
- execFile security: all child process calls use
execFilewith array arguments, eliminating shell injection - Input validation: branch name, port, and container ID validation with strict regex enforcement
- 1,636+ tests: unit, integration, e2e, smoke, boundary, security, fuzz, chaos, regression, performance, and mutation testing
Full xchain-node documentation is available in the xchain-documentation repository:
| Document | Description |
|---|---|
| README | Overview, features, installation, quick start, scripts, dependencies |
| Architecture | Data pipeline position, internal components, source files, runtime directory structure |
| Configuration | Config file system, generated environment variables, naming conventions, internal constants |
| Operations | CLI commands reference, global options, parameters, troubleshooting |
git clone https://github.com/XChain-Platform/xchain-node.git
cd xchain-node
npm install
npm linkInstall all services for Bitcoin regtest:
xchain-node install master all bitcoin regtestCheck status:
xchain-node psStart/stop:
xchain-node stop all bitcoin regtest
xchain-node start all bitcoin regtestBy default the bundled xchain-hub runs as a standalone config oracle. To run it
as a full validator (P2P + PBFT + capability staking), generate a validator
identity first. This is offline and needs no running stack:
xchain-node validator init \
--seed-nodes seed1.example:10001,seed2.example:10001 \
--p2p-addr <your-public-host>:10001 \
--oracle-epoch-start <shared-federation-unix-ms> \
--capabilities price,cross_chain,oracle_publish,attestationIt generates an Ed25519 signing key (saved 0600 under config/validator/),
prints the pubkey to stake XCHAIN to, and writes a starter capabilities.json
under config/validator/hub-caps/ (its own subdirectory, mounted read-only into
the hub container; the signing key is never mounted). Edit that file to set real
cross_chain RPC endpoints and oracle_publish DOGE values, then install/start
the hub. It will boot in validator mode with your key and capability config
mounted automatically:
xchain-node install master xchain-hub
xchain-node validator status # show pubkey, peers, capabilitiesFive env vars override where xchain-node stores its filesystem state. Set them in the shell or systemd unit before running xchain-node install. Each falls back to a path inside this repo if unset, so existing installs are unaffected.
| Variable | What goes here |
|---|---|
XCHAIN_NODE_DATA_DIR | Per-coin state + bootstrap output archives (tens to hundreds of GB) |
XCHAIN_NODE_TMP_DIR | Bootstrap inner work archives (tens of GB during bootstrap ops) |
XCHAIN_NODE_MODULES_DIR | Git clones of sibling xchain-* repos |
XCHAIN_NODE_CRYPTO_NODES_DIR | Downloaded coin-node binaries |
XCHAIN_NODE_CONFIG_DIR | Generated per-service .env files |
On boxes with a small / partition and a large data volume (e.g., OVH RISE-3 with /misc), point DATA_DIR and TMP_DIR at the large volume before installing. Full docs in CONFIGURATION.md.
When xchain-node manages its own MariaDB container, these optional env vars override server defaults. They are applied as mysqld startup args at install time, so they persist across a container recreate (a conf.d file edited inside a running container does not). Each is unset by default so image defaults remain unchanged. Set them before xchain-node install.
| Variable | mysqld setting | When to set |
|---|---|---|
XCHAIN_NODE_DB_DATA_DIR | datadir bind-mount (-v <dir>:/var/lib/mysql) | Pin the datadir to a fast NVMe mount instead of the Docker data-root |
XCHAIN_NODE_DB_BUFFER_POOL_SIZE | innodb-buffer-pool-size (e.g. 16G) | Large/multi-DB hosts where the stock 128 MB thrashes on multi-GB datasets |
XCHAIN_NODE_DB_MAX_CONNECTIONS | max-connections (e.g. 300) | Many connection pools against one DB (replicas, shared services) |
XCHAIN_NODE_DB_FLUSH_LOG_AT_TRX_COMMIT | innodb-flush-log-at-trx-commit (e.g. 2) | Replica/cache DBs where a 1-second crash window is acceptable for speed |
Every persistent service container carries a Docker healthcheck, but Docker itself takes no action on the unhealthy state (--restart unless-stopped only fires when the process exits). An alive-but-stalled service would otherwise stay wedged until an operator notices it in docker ps. xchain-node autoheal closes that loop: it restarts containers that have been continuously unhealthy past a grace window, for services opted in via autoheal: true in the healthcheck table (currently the decoder, encoder, and indexer; the utxo-tracker is deliberately excluded because it halts on purpose rather than exiting, and a restart would just re-halt it).
The command is one-shot and never prompts or daemonizes. Unattended remediation requires wiring it to a cron entry or systemd timer, e.g. */5 * * * * xchain_node autoheal. Detection-to-restart latency is the timer interval plus the health retry budget plus the grace window. Use --dry-run to see restart candidates without acting. Exit code is non-zero only when a restart was attempted and failed.
| Variable | Default | What it controls |
|---|---|---|
XCHAIN_NODE_AUTOHEAL_GRACE_MS | 120000 | How long a container must be continuously unhealthy before a restart is considered |
XCHAIN_NODE_AUTOHEAL_COOLDOWN_MS | 600000 | Minimum time between two autoheal restarts of the same container (anti-flap) |
XCHAIN_NODE_AUTOHEAL_STATE_DIR | ~/.xchain-node | Where the anti-flap state file (autoheal-state.json) lives |
xchain-node sends an anonymous usage ping (xchain-node + service versions, which services are running, basic OS/Docker info). Your IP address is never sent or stored: the receiver derives only a coarse country/region and an anonymous one-way network hash from the connection, then discards the IP. It contains no secrets, wallet data, addresses, or config. It is on by default, sent only on install/update and at most once per day otherwise, and never blocks a command.
Turn it off with any of: --no-telemetry on any command (sticks for future runs), XCHAIN_NODE_NO_TELEMETRY=1, or "optOut": true in ~/.xchain-node/telemetry.json. Point at a different collector with XCHAIN_NODE_TELEMETRY_URL. Full details: Privacy & Telemetry.
| Command | Description |
|---|---|
npm test | Unit tests (1,084 tests) |
npm run test:integration | Integration tests (87 tests) |
npm run test:smoke | Smoke tests (50 tests) |
npm run test:boundary | Boundary condition tests (57 tests) |
npm run test:security | Security tests (27 tests) |
npm run test:e2e | End-to-end tests (57 tests) |
npm run test:fuzz | Fuzz tests (95 tests) |
npm run test:chaos | Chaos engineering tests (121 tests) |
npm run test:regression | Regression tests (58 tests) |
npm run test:regression:p0 | Regression P0: critical gate (33 tests) |
npm run test:regression:p0p1 | Regression P0+P1: standard gate (51 tests) |
npm run test:mutation | Mutation testing (Stryker Mutator) |
npm run test:all | All tests (~1,552 tests; excludes security/boundary) |
npm run benchmark | Performance benchmarks (5 scenarios) |
npm run benchmark:quick | Quick benchmarks |
| Type | Tests | Description |
|---|---|---|
| Unit | 1,084 | 37 files: config generation, Docker/module orchestration, database, credentials, bootstrap + signing, validator, telemetry, autoheal, discovery, go-live/skew guards, precheck, state, and CLI helpers |
| Integration | 87 | Config pipeline, Docker commands, module lifecycle (LevelDB), status queries, hub/explorer config, database setup, network management, multi-module orchestration |
| Smoke | 50 | Module imports, CLI registration, global options, constants/enums, config templates, config composition, Docker exports, parameter expansion, state init, Dockerfiles |
| Boundary | 57 | Config file parsing edge cases (values with =, base64, empty, blank lines), resolveArgs boundaries, filterCommandParameters, LevelDB key format |
| Security | 27 | Shell injection prevention (execFile), container ID validation, NODE_PREFIX validation, branch name validation, path traversal, database command safety, source code scanning |
| E2E | 57 | Install lifecycle, multi-coin, config overrides, precheck, update flow, reset, error handling, exec/logs |
| Fuzz | 95 | Port validation, resolveArgs, config parsing, command construction, env escaping, branch validation, filter params, container ID |
| Chaos | 121 | Download resilience, LevelDB resilience, config resilience, Docker resilience, git clone resilience, process resilience, network resilience |
| Regression | 58 | Three-tier suite: P0 critical (33), P1 high (18), P2 standard (7): argument parsing, config generation, Docker commands, security, lifecycle, state, E2E workflows |
| Performance | 5 scenarios | Config generation, filter params, config parsing scale, resolveArgs, naming helpers |
| Mutation | 2 configs | Full service and ConfigService-only pilot via Stryker Mutator |
| Total | 1,636+ |
Copyright © 2025-2026 Dankest, LLC
Based on XChain Platform by Dankest, LLC – https://dankest.llc
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later) with a commercial license available for proprietary use.
You may use, modify, and distribute this material under the terms of the License. See LICENSE and NOTICE for full terms. See the licensing overview.