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.
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.
The Pear Runtime CLI is required to run the application. Before installing Pear, refer to the official Pear documentation for the latest recommended version and installation instructions. For this project, the latest Pear CLI is compatible.
Install Pear globally:
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.
git clone -b <tag> --single-branch git@github.com:Trac-Systems/main_settlement_bus.git
cd main_settlement_bus
npm installBefore 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.
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 is validated before MSB finishes booting. This applies to direct CLI flags and to the .env / inline environment-variable entry points, because those scripts ultimately pass the same runtime flags into pear run ..
--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.
This variant reads configuration from .env:
# .env
STORES_DIRECTORY=<stores_directory>
NETWORK=<network>
then
npm run env
The script sources .env before invoking program and falls back to stores for STORES_DIRECTORY and mainnet for NETWORK when unset.
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
npm run start -- --stores-directory <stores_directory> --network testnetSupported network values are mainnet, development, testnet1, and testnet (testnet maps to testnet1).
# .env
STORES_DIRECTORY=<stores_directory>
MSB_HOST=127.0.0.1
MSB_PORT=5000
NETWORK=mainnet
npm run env-rpc
This 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.
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).
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.
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-rpcAny of the following launch methods can be applied:
-
Using a
.envfile β populate.env, then start the service:docker compose up -d msb-rpc
or
docker compose --env-file .env up -d msb-rpc
Add 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=1337
-
Passing 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-rpc
Skip
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-rpc
Adjust
/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.
- 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.
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"
}
}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.