trac-msb
v0.2.21
Published
[](https://github.com/Trac-Systems/main_settlement_bus/releases/latest) [](https://
Readme
Main Settlement Bus (MSB)
A peer-to-peer crypto validator network to verify and append transactions.
Always follow the guidance in the Security Policy for release compatibility, upgrade steps, and required follow-up actions.
The MSB leverages the Pear Runtime and Holepunch.
Prerequisites
Node.js is required to run the application. Before installing Node.js, refer to the official Node.js documentation for the latest recommended version and installation instructions. For this project, Node.js v22.22.0 (LTS) and npm 11.6.1 or newer are compatible.
MSB supports both Pear v2 and Pear v3. Its Pear runner uses pear run with Pear v2 and the embedded pear-runtime module with Pear v3.
The Pear CLI is required for Pear v2 and for Pear deployment commands. Pear v3 can run MSB through the embedded module without a globally installed CLI. Install the CLI when it is needed:
npm install -g pear
which pearDocker is optional and only needed for running the containerized RPC node. Before installing Docker, refer to the official Docker documentation for the latest recommended version and installation instructions. For running the containerized RPC node, the latest Docker is recommended. Tested with Docker version 28.3.2, build 578ccf6.
Install
git clone -b <tag> --single-branch [email protected]:Trac-Systems/main_settlement_bus.git
cd main_settlement_bus
npm installPost-install checklist
Before running tests, install bare globally:
npm install -g bare- ✅
npm run test:unit:all– confirms the codebase builds and runs under both supported runtimes. - 📋
npm run test:acceptance– optional but recommended before upgrades. This suite spins up in-process nodes and may take a few minutes. - 🌐 RPC smoke test – start
STORES_DIRECTORY=smoke-store MSB_HOST=127.0.0.1 MSB_PORT=5000 NETWORK=mainnet npm run env-rpcin one terminal, then executecurl -s http://127.0.0.1:5000/v1/feefrom another terminal to verify/v1routes respond. Stop the node withCtrl+Conce finished.
Usage
Runtime entry points cover CLI-driven runs (start, rpc) and .env-aware runs (env, env-rpc). Each section below lists the accepted configuration inputs.
Startup input validation
Startup input is validated before MSB finishes booting. This applies to direct CLI flags and to the .env / inline environment-variable entry points, because those scripts pass the same flags through the Pear v2/v3 runner.
--network/NETWORKmust be one ofmainnet,development,testnet1, ortestnet(testnetis treated as an alias fortestnet1).--stores-directory/STORES_DIRECTORYmust be a non-empty string.--host/MSB_HOSTmust be a non-empty string when RPC mode is enabled.--port/MSB_PORTmust be an integer in range1-65535when RPC mode is enabled.
MSB also validates the high-risk overrideable config values that are normalized into shared runtime state before startup:
bootstrapmust be a 32-byte hex string orBuffer.channelmust be a string orBufferwith length1-32bytes.storesDirectory,host,port, anddhtBootstrapoverrides are validated before the node starts.
When one of these values is invalid, startup fails immediately with a field-specific error instead of silently falling back.
Interactive regular node
Regular node with .env file
This variant reads configuration from .env:
# .env
STORES_DIRECTORY=<stores_directory>
NETWORK=<network>then
npm run envThe script sources .env before invoking program and falls back to stores for STORES_DIRECTORY and mainnet for NETWORK when unset.
Inline environment variables
STORES_DIRECTORY=<stores_directory> NETWORK=testnet npm run envThis run persists data under ${STORES_DIRECTORY} (defaults to stores under the project root), connects to testnet (defaults to mainnet) and is intended for inline or CLI-supplied configuration. Each network will have its own store subfolder to avoid collision
CLI flags
npm run start -- --stores-directory <stores_directory> --network testnetSupported network values are mainnet, development, testnet1, and testnet (testnet maps to testnet1).
RPC-enabled node
RPC with .env file
# .env
STORES_DIRECTORY=<stores_directory>
MSB_HOST=127.0.0.1
MSB_PORT=5000
NETWORK=mainnetnpm run env-rpcThis entry point sources .env automatically and defaults to stores, 127.0.0.1, 5000, and mainnet when variables are not present. Supported NETWORK values are mainnet, development, testnet, and testnet1.
Inline environment variables
STORES_DIRECTORY=<stores_directory> MSB_HOST=<host> MSB_PORT=<port> NETWORK=<network> npm run env-rpcOverride any combination of STORES_DIRECTORY, MSB_HOST, MSB_PORT, or NETWORK. Data is persisted under <stores_directory>/<store_name> (default stores/mainnet for this script).
CLI flags
npm run rpc --host=<host> --port=<port> -- --stores-directory <stores_directory> --network <network>Supported network values are mainnet, development, testnet1, and testnet (testnet maps to testnet1). Invalid --host, --port, --stores-directory, or --network values fail before the RPC node starts.
Docker usage
You can run the RPC node in a containerized environment using the provided docker-compose.yml file. The msb-rpc service is already wired up. You usually only need to tweak these variables:
MSB_STORE: name of the store directory under./stores.MSB_HOST: host interface to bind (defaults to127.0.0.1to avoid exposing everything).MSB_PORT: port the RPC server listens on inside the container (defaults to5000).MSB_PUBLISH_PORT: host port to expose (defaults toMSB_PORT, so set it only when the host port should differ).NETWORK: network environment for the RPC process (defaults tomainnet). Supported values aremainnet,development,testnet, andtestnet1.
Leave MSB_PORT=5000 if you just want to publish the default RPC port and only bump MSB_PUBLISH_PORT when the host side must change. Set both to the same value if you want the RPC server itself to listen on another port.
Example (keep container port 5000, expose host port 6000):
MSB_STORE=rpc-node-store \
MSB_HOST=127.0.0.1 \
MSB_PORT=5000 \
NETWORK=mainnet \
MSB_PUBLISH_PORT=6000 \
docker compose up -d msb-rpcRunning msb-rpc with Docker Compose
Any of the following launch methods can be applied:
Using a
.envfile – populate.env, then start the service:docker compose up -d msb-rpcor
docker compose --env-file .env up -d msb-rpcAdd any of the variables listed above to
.env. When the host port needs to differ from the container port, setMSB_PUBLISH_PORTwithout touchingMSB_PORT.Example
.env(publishes host port 1337, keeps the container on 5000):MSB_STORE=rpc-node-store MSB_HOST=127.0.0.1 MSB_PORT=5000 NETWORK=mainnet MSB_PUBLISH_PORT=1337Passing variables inline – use this method when environment variables should be provided directly in the command line, without modifying the
.envfile:MSB_STORE=<store_name> MSB_HOST=<host> MSB_PORT=<container_port> NETWORK=<network> MSB_PUBLISH_PORT=<host_port> docker compose up -d msb-rpcSkip
MSB_PORTwhen you just want to keep the container on5000and expose a different host port.Reusing an existing store directory – mount the path that already holds your store and pin the host binding you need:
docker compose run -d --name msb-rpc \ -e MSB_STORE=<store_name> \ -e MSB_HOST=<host> \ -e MSB_PORT=<container_port> \ -e NETWORK=<network> \ -e MSB_PUBLISH_PORT=<host_port> \ -p <host_address>:<host_port>:<container_port> \ -v /absolute/path/to/your/store_directory:/msb/stores \ msb-rpcAdjust
/absolute/path/to/your/store_directoryto the directory that already contains the persisted store. Once the container exists, bring it back withdocker compose start msb-rpc. If the container should stay on5000, omit-e MSB_PORT=<container_port>and just setMSB_PUBLISH_PORTplus the matching-pflag.Example with specific values:
docker compose run -d --name msb-rpc \ -e MSB_STORE=rpc-node-store \ -e MSB_HOST=127.0.0.1 \ -e MSB_PORT=5000 \ -e NETWORK=mainnet \ -e MSB_PUBLISH_PORT=6000 \ -p 127.0.0.1:6000:5000 \ -v /absolute/path/to/your/store_directory:/msb/stores \ msb-rpc
Stop the service with docker compose stop msb-rpc, remove the stack entirely with docker compose down when you are finished.
Note: The RPC instance must synchronize with the network after startup, so full readiness may take some time.
Troubleshooting
- Dependency install failures – confirm you are on Node.js v22.22.0 (LTS) and npm ≥ 11.6.1. If packages still fail to build, clear artifacts (
rm -rf node_modules package-lock.json && npm install) and rerunnpm run test:unit:all. - Unit tests fail only in one runtime – run the targeted commands (
npm run test:unit:nodeornpm run test:unit:bare) to isolate regressions, then inspecttests/unit/unit.test.jsfor the failing cases.
Development
VS Code
Open the repository root in VS Code so the editor can resolve the local eslint dependency, the root eslint.config.js, and the existing debugger launch configurations in .vscode/launch.json.
Install these extensions:
dbaeumer.vscode-eslint(microsoft.com)
For linting, add the following to your workspace or user .vscode/settings.json:
{
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.useFlatConfig": true,
"eslint.workingDirectories": [
{
"mode": "auto"
}
],
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
}
}Linting and tests
Use these commands during development:
npm run lintchecks the full repository with ESLint.npm run lint:fixapplies ESLint autofixes where possible.npm run test:unit:allruns both unit suites and is the main pre-commit test command.npm run test:acceptanceruns the RPC acceptance test suite.
