Run a Whatsminer Worker
Start an MDK Worker for a MicroBT Whatsminer device.
Overview
Whatsminer support ships as the external
whatsminer-mdk-worker contract plugin — a plain mdk-contract.json plus handler files, with
no startWhatsminerWorker export, no provisioning store, no alerts/stats templates, and no model validation. You host
it yourself on WorkerRuntimeV2 through a small adapter; this repo ships a working one to
copy from (examples/mvp-site/backend/whatsminer-adapter.js).
Prerequisites
Review the common deployment prerequisites before you start.
Deployment-specific requirements:
- The
whatsminer-mdk-workerpackage added as a dependency (it's distributed as a git dependency, not on the npm registry — see its own README for the exact version/ref to pin) - A Node.js service or script in your deployment that constructs the adapter below and registers the resulting Worker
- A supported Whatsminer device reachable from the machine or container running the Worker
- The miner API reachable over encrypted TCP: with no
portset, the plugin probes API v3 on4433first, then API v2 on4028; set either port to pin that version - The Whatsminer API password, from which the plugin derives its auth tokens. API v3 firmware also takes an API
account: the account set up on your miner
Development
Run against a mock
The plugin ships its own mock at whatsminer-mdk-worker/mock/api-v3-server. examples/mvp-site
boots one mock per seed device and points the adapter's devices at them — read startMocks alongside
startWhatsminerWorker in that example's backend/site.js for the full wiring (mock lifecycle, port assignment,
device seeding all come from config/devices.json).
There is no minimal single-file runnable example for Whatsminer anymore (the old repo-root example shipped against
the retired in-repo package); the mvp-site example stack is the reference implementation.
cd examples/mvp-site && npm run setup:example && npm start boots the whole stack — Kernel, mocks, and the Whatsminer Worker included — against seed data in
config/devices.json.
Connect a miner
2.1 Write the adapter
whatsminer-mdk-worker has no boot helper of its own — construct a WorkerRuntimeV2 pointed at
the package directory, translating your seed device list into the { deviceId, config } shape it expects:
const path = require('path')
const { WorkerRuntimeV2 } = require('@tetherto/mdk-worker')
const PKG_DIR = path.dirname(require.resolve('whatsminer-mdk-worker/package.json'))
async function startWhatsminerWorker (opts) {
const devices = (opts.seedDevices || []).map((seed) => ({
deviceId: seed.info?.serialNum || seed.id,
config: { ...seed.opts }
}))
const runtime = new WorkerRuntimeV2(PKG_DIR, {
workerId: opts.workerId,
kernelTopic: opts.kernelTopic || null,
storeDir: opts.storeDir,
allowedKeys: opts.allowedKeys || [],
devices
})
await runtime.start()
return { runtime, seeded: devices.length, stop: () => runtime.stop() }
}
module.exports = { startWhatsminerWorker }This is the adapter examples/mvp-site/backend/whatsminer-adapter.js ships, trimmed of its
input validation and debug logging — copy the real file rather than this excerpt for a production deployment.
2.2 Register your miner
Add this to the Node.js service or script that runs your Worker. The snippet shows the minimum boot call seeding one Whatsminer device; replace the example IP address, password and account with your miner's values:
const { getKernel } = require('@tetherto/mdk-core')
const { startWhatsminerWorker } = require('./whatsminer-adapter')
const main = async () => {
const kernel = await getKernel()
const worker = await startWhatsminerWorker({
workerId: 'whatsminer-rack-1',
storeDir: './store/whatsminer-rack-1',
allowedKeys: [kernel.getClientPublicKey()],
seedDevices: [{
info: { serialNum: 'WM-001' },
opts: { address: '192.168.1.10', password: 'admin', account: 'admin' }
}]
})
await kernel.registerWorker(worker.runtime.getPublicKey())
}
main().catch((err) => { console.error(err); process.exit(1) })Leave port unset so the plugin probes API v3 on 4433 and then API v2 on 4028; set it only to pin one version.
account is read by API v3 firmware and ignored by API v2. Leave it unset and the plugin sends super.
allowedKeys lists the RPC callers the Worker accepts. The Worker refuses to start without it
(ERR_WORKER_ALLOWED_KEYS_REQUIRED), so pass the Kernel's client key.
Make sure each miner's IP is reachable from the machine or container running the Worker before registering. Commands act on physical hardware. Prioritize thermal safety.
The device list is fixed at construction — there is no registerThing/updateThing/forgetThings equivalent.
Adding, updating, or removing a device means editing seedDevices and restarting the Worker.
The whatsminer-mdk-worker README documents the plugin's own mdk-contract.json, supported
models, and connection options in full; the shared install pattern covers the broader deployment
mechanics.
Troubleshooting
There is no minimal single-file development example to check readiness output against — the reference deployment is
examples/mvp-site's full stack. npm start launches it under PM2 and returns; the Whatsminer
Worker's process log shows MDK_READY worker devices=<n> once the Worker is up (pm2 logs worker).
If the Worker does not come up, or a mock port is already in use, follow miner troubleshooting.
Next steps
- Understand the deployment topologies for running the Worker service
- Review
whatsminer-mdk-worker's ownmdk-contract.jsonfor telemetry units, command shapes, and error codes — it isn't vendored into this repo