Demand CLI is a proxy that let miners to connect to and mine with Demand Pool. It serves two primary purposes:
- Translation: Enables miners using StratumV1 to connect to the Demand Pool without requiring firmware updates. Sv1 messages gets translated to Sv2.
- Job Declaration (JD): Allows miners to declare custom jobs to the pool using StratumV2.
- Stratum V2 Support: Uses the secure and efficient Stratum V2 protocol for communication with the pool.
- Job Declaration: Enables miners to propose custom block templates to the pool. This helps make mining more decentralized by allowing miners to pick the transactions they want to include in a block.
- Stratum V1 Translation: Acts as a bridge, allowing StratumV1 miners to connect to the Demand Pool without firmware updates.
- Flexible Configuration: Provides options for customization. This allows users to optimize the tool for their specific mining environment.
- Monitoring API: Provides HTTP endpoints to monitor proxy health, pool connectivity, miner performace, and system resource usage in real-time.
- Rust (version 1.70.0 or higher recommended)
- Cargo (included with Rust)
- Bitcoin Node (Optional): Required for job declaration.
There are two options to get started:
- Visit the releases page.
- Download the binary for your system.
- Clone the repository and build the project:
git clone https://github.com/demand-open-source/demand-cli.git cd demand-cli cargo build --release
The executable will be located in the target/release/ directory.
Before running the CLI, set up the necessary environment variables.
-
TOKEN(Required): Your Demand Pool authentication token.
Export it with:export TOKEN=<your_token>
-
TP_ADDRESS(Optional): Template Provider address (default:127.0.0.1:8442). Set this if you want to use job declaration feature.Export it with
export TP_ADDRESS=<node_ip:port>
Note: if TP_ADDRESS id not set, job declaration is disabled, and the proxy uses templates provided by the pool.
Depending on whether you built from source or downloaded a binary, the command to run the proxy is slightly different. There are also different options you can use. Below are two example setups to get you started.
This example assumes you’ve built demand-cli from source and want to enable job declaration.
export TOKEN=abc123xyz
export TP_ADDRESS=192.168.1.100:8442
./target/release/demand-cli -d 100T --loglevel debug --nc onConnect Miners: Point your Stratum V1 miners to <your_proxy_ip>:32767.
This example assumes you downloaded a pre-built binary (for linux in this case) for from release page and wants to connect test endpoint Set Environment Variable:
export TOKEN=xyz789abc
./demand-cli-linux-x64 -d 10T --testPoint your Stratum V1 miners to <your_proxy_ip>:32767.
--test: Connects to test endpoint-d: Expected downstream hashrate (e.g.,10T,2.5P,5E). Default is100TH/s(100 Terahashes/second).
This helps the pool adjust to your hashrate.--loglevel: Logging verbosity (info,debug,error,warn). Default isinfo.--nc: Noise connection logging verbosity (info,debug,error,warn). Default isoff.
The proxy exposes REST API enspoints to monitor its health, pool connectivity, connected mining devices performance and system resource usage. All endpoints are served on http://0.0.0.0:3001 and return JSON responses in the format:
{
"success": boolean,
"message": string | null,
"data": object | string | null
}| Endpoint | Method | Description | Response Status Codes |
|---|---|---|---|
/api/health |
GET | Checks the health status of the proxy. | 200, 503 |
/api/pool/info |
GET | Retrieves the current pool address and latency. | 200, 404 |
/api/stats/miners |
GET | Returns device_name, hashrate, accepted and rejected shares count, and current_difficulty for all connected downstream devices (empty if none). | 200, 500 |
/api/stats/aggregate |
GET | Provides aggregated stats of all connected downstream devices. | 200, 500 |
/api/stats/system |
GET | Returns system resource usage (CPU and memory) for the proxy process. | 200 |
GET /api/health - Retrieves the health of the proxy
- Responses:
- 200 OK (Healthy):
{ "success": true, "message": null, "data": "Proxy OK" } - 503 Service Unavailable (Unhealthy):
{ "success": false, "message": "<reason>", "data": null }
- 200 OK (Healthy):
GET /api/pool/info - Retrieves the current pool’s address and latency in milliseconds or null if not currently connected to pool
- Responses:
- 200 OK (Connected to Pool):
{ "success": true, "data": { "address": "<pool_address>", "latency": "5072" } } - 400 NOT_FOUND (Not connected to Pool):
{ "success": true, "data": { "address": null, "latency": null } }
- 200 OK (Connected to Pool):
GET /api/stats/miners - Shows stats for connected devices, empty if none.
- Responses:
- 200 OK (Miing devices connected):
{ "success":true, "message":null, "data":{ "3":{ "device_name":"cpuminer/2.5.1", "hashrate":4721719.5, "accepted_shares":273, "rejected_shares":22, "current_difficulty":0.0065961657 }, "2":{ "device_name":"cpuminer/2.5.1", "hashrate":6464463.0, "accepted_shares":413, "rejected_shares":64, "current_difficulty":0.00903075 } } } - 200 OK (No connected devices):
{ "success": true, "message": null,"data": {} } - 500 Internal Server Error:
{ "success": false, "message": "Failed to collect stats: <error>", "data": null }
- 200 OK (Miing devices connected):
GET /api/stats/aggregate - Aggregates metrics across all devices
- Responses:
- 200 OK:
{ "success":true, "message":null, "data":{ "total_connected_device":2, "aggregate_hashrate":11186182.5, "aggregate_accepted_shares":686, "aggregate_rejected_shares":86, "aggregate_diff":0.01562692 } } - 500 Internal Server Error:
{ "success": false, "message": "Failed to collect stats: <error>", "data": null }
- 200 OK:
GET /api/stats/system - Reports CPU and memory usage (0 - 100%).
- Responses:
- 200 OK:
{"success":true,"message":null,"data":{"cpu_usage_%":"0.565","memory_usage_bytes":25935872}}
- 200 OK:
Contributions are welcome. Please refer to our CONTRIBUTING.md for guidelines.
Report issues via GitHub Issues.