E2E Test Suite: Configuration
Environment Variables
The test suite reads configuration from a .env file (loaded via dotenv) or falls back to xchain-hub discovery. All variables are optional if hub discovery is available.
Core Settings
| Variable |
Required |
Default |
Description |
COIN |
Yes |
None |
Blockchain coin: bitcoin, litecoin, or dogecoin |
NETWORK |
Yes |
None |
Network mode: regtest, testnet, or mainnet |
ALLOW_MAINNET |
No |
false |
Must be true to run tests against mainnet (safety guard) |
Coin Node
| Variable |
Required |
Default |
Description |
NODE_URL |
Hub fallback |
None |
Coin node RPC hostname |
NODE_PORT |
Hub fallback |
None |
Coin node RPC port (e.g., 18444 for BTC regtest) |
NODE_USER |
Hub fallback |
None |
RPC username |
NODE_PASSWORD |
Hub fallback |
None |
RPC password |
UTXO Tracker
| Variable |
Required |
Default |
Description |
UTXO_TRACKER_URL |
Hub fallback |
None |
UTXO tracker hostname |
UTXO_TRACKER_API_PORT |
Hub fallback |
None |
UTXO tracker API port |
Encoder
| Variable |
Required |
Default |
Description |
ENCODER_URL |
Hub fallback |
None |
Encoder service hostname |
ENCODER_API_PORT |
Hub fallback |
None |
Encoder API port |
Decoder
| Variable |
Required |
Default |
Description |
DECODER_URL |
Hub fallback |
None |
Decoder service hostname |
DECODER_API_PORT |
Hub fallback |
None |
Decoder API port |
Indexer
| Variable |
Required |
Default |
Description |
INDEXER_URL |
Hub fallback |
None |
Indexer service hostname |
INDEXER_API_PORT |
Hub fallback |
None |
Indexer API port |
INDEXER_DB_NAME |
Hub fallback |
None |
Indexer MariaDB database name |
INDEXER_DB_USER |
Hub fallback |
None |
Indexer MariaDB username |
INDEXER_DB_PASS |
Hub fallback |
None |
Indexer MariaDB password |
DATABASE_URL |
No |
mariadb |
MariaDB host for the indexer database connection. Use 127.0.0.1 in scripts (Node resolves localhost to IPv6; MariaDB binds IPv4). Defaults to mariadb for Docker Compose where that is the container hostname. |
DATABASE_PORT |
No |
3306 |
MariaDB port for the indexer database connection. |
Explorer
| Variable |
Required |
Default |
Description |
EXPLORER_URL |
Yes (not hub-discoverable) |
None |
Explorer service hostname |
EXPLORER_API_PORT |
Yes (not hub-discoverable) |
None |
Explorer API port |
Regtest Miner
| Variable |
Required |
Default |
Description |
REGTEST_MINER_URL |
Hub fallback |
None |
Regtest miner hostname |
REGTEST_MINER_API_PORT |
Hub fallback |
None |
Regtest miner API port |
Hub Discovery
| Variable |
Required |
Default |
Description |
HUB_VALIDATORS |
No |
None |
Comma-separated list of hub endpoints (e.g., hub1:10000,http://hub2:10000) |
HUB_URL |
No |
localhost |
Single hub hostname (used if HUB_VALIDATORS is not set) |
HUB_PORT |
No |
10000 |
Single hub port |
HUB_API_HOST |
No |
None |
Alternative to HUB_URL (backward compatibility) |
Hub Discovery Fallback
When direct environment variables are not set, the bootstrap sequence discovers configuration from xchain-hub:
flowchart TD
CHECK{"checkAllEnvironmentalVariables()<br>All 21 vars set?"}
DIRECT["Use direct config"]
FALLBACK["Hub fallback"]
PARSE["Parse endpoints:<br>HUB_VALIDATORS > HUB_URL+HUB_PORT > localhost:10000"]
NEWCONN["new XChainHubConnector(endpoints)"]
PING["hubConnector.ping()"]
GETCONFIG["hubConnector.getAllConfig()<br>→ config[coin][network][service][param]"]
EXTRACT["Extract host/port for:<br>node, database, utxo-tracker, encoder, decoder, indexer, regtest-miner"]
NOTE["Note: explorer is NOT hub-discoverable;<br>EXPLORER_URL/EXPLORER_API_PORT must be set directly"]
CHECK -->|Yes| DIRECT
CHECK -->|"No (missing)"| FALLBACK
FALLBACK --> PARSE --> NEWCONN --> PING --> GETCONFIG --> EXTRACT --> NOTE
Docker convention: When using hub discovery, all service hostnames are overridden to "localhost" (Docker Compose services are accessed via port mapping, not container hostnames). Database host defaults to "mariadb".
Internal Constants
| Constant |
Value |
Location |
Description |
GAS_TICK |
"XCHAIN" |
initialCheck.test.js |
Gas token ticker, auto-created if missing |
connectionLimit |
10 |
db.js |
MariaDB connection pool size |
insertIdAsNumber |
true |
db.js |
Return insert IDs as numbers, not BigInt |
bigIntAsNumber |
true |
db.js |
Deserialize BIGINT columns (e.g., action_index, tx_index) as Number, not BigInt. Keeps consensus hash serialization consistent with the indexer and sync prod pools, which also set this flag. |
timeMax (default) |
60000 |
db.js |
Default polling timeout for all waitFor* methods (ms) |
sleep interval |
1000 |
db.js |
Polling interval between check* calls (ms) |
waitForTx timeout |
10000 |
BlockchainConnector.js |
Default timeout for waitForTx polling (ms) |
waitForUtxos timeout |
60000 |
XChainUtxoTrackerConnector.js |
Default timeout for waitForUtxos polling (ms) |
tracker poll timeout |
20000 |
transactionHelper.js |
Timeout for UTXO verification cache polling after broadcast (ms) |
tracker poll interval |
500 |
transactionHelper.js |
Interval for UTXO verification polling (ms) |
_call timeout |
5000 |
XChainHubConnector.js |
HTTP timeout for hub JSON-RPC calls (ms) |
mining time |
1000, 1000 |
initialCheck.test.js |
Mining max_time and tx_added_time set during bootstrap (ms) |
Docker
Dockerfile
The suite provides a Dockerfile for containerized execution:
FROM node:22-bookworm
RUN mkdir /XChainE2ETest/
COPY ./xchain-hub /XChainE2ETest/xchain-hub
COPY ./xchain-sdk /XChainE2ETest/xchain-sdk
COPY ./package.json /XChainE2ETest/package.json
COPY ./package-lock.json /XChainE2ETest/package-lock.json
WORKDIR /XChainE2ETest
RUN npm ci
COPY ./src /XChainE2ETest/src
COPY ./test /XChainE2ETest/test
CMD ["npm", "test"]
Docker Compose
Run with an env file:
docker build -t xchain-e2e-test .
docker run --env-file .env --network host xchain-e2e-test
Or as part of a Docker Compose stack where all services are orchestrated together:
docker-compose up --exit-code-from xchain-e2e-test
Supported Coin/Network Combinations
| Coin |
Network |
BIP32 Derivation |
Address Type |
Dust Threshold |
| Bitcoin |
regtest |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
546 sats |
| Bitcoin |
testnet |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
546 sats |
| Bitcoin |
mainnet |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
546 sats |
| Litecoin |
regtest |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
5460 sats |
| Litecoin |
testnet |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
5460 sats |
| Litecoin |
mainnet |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
5460 sats |
| Dogecoin |
regtest |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
100000 sats |
| Dogecoin |
testnet |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
100000 sats |
| Dogecoin |
mainnet |
m/44'/0'/0'/0/{index} |
P2PKH (legacy) |
100000 sats |
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.
Edit this page on GitHub ↗