Skip to main content

Bittensor chain monitoring for AI agents.

Project description

Blockmachine Chainwake

Bittensor chain monitoring for AI agents.

Chainwake includes a watcher CLI and MCP server. A watcher invocation suspends until a Bittensor chain-state condition fires, then exits with a structured JSON payload. It is observation-only: no keys, no signing, no extrinsic submission.

Agents spawn a chainwake watcher as a subprocess and parse stdout to decide what to do next. The exit code is for shell-level control flow; the JSON is where the detail lives. Bittensor is the launch chain.


Install

Install the stable CLI in an isolated environment with uv:

uv tool install chainwake

Or install it in the active Python environment:

pip install chainwake

To try unreleased code or contribute, install the current GitHub source:

uv tool install git+https://github.com/taostat/chainwake.git

Quickstart

All three examples run against a live Bittensor node. Set CHAINWAKE_BT_RPC_URL or pass --rpc-url; the default is wss://rpc.blockmachine.io. Enable shell completion: chainwake --install-completion.

1. Threshold — wait until subnet price drops below 0.05 TAO

chainwake bt subnet 19 price --below 0.05

Polls subnet 19's alpha price at the chain's natural per-block cadence. Exits 0 when the price crosses below 0.05 TAO, with stdout:

{
  "schema_version": 1,
  "status": "matched",
  "watcher": { "chain": "bt", "resource": "subnet", "resource_id": "19",
               "sub_resource": "pool.price", "name": null,
               "primitive": "threshold",
               "invocation": ["chainwake", "bt", "subnet", "19", "price",
                              "--below", "0.05"] },
  "condition": { "operator": "below", "target": 0.05 },
  "observed": { "path": "subnet.19.pool.price", "value": 0.0487,
                "block": 4291820, "block_hash": "0xabc...",
                "timestamp": "2026-05-06T10:00:00Z" },
  "budget": { "runtime_ms": 3210, "rpc_calls": 3, "estimated_ru_consumed": 3 },
  "process": { "pid": 12345, "started_at": "2026-05-06T09:59:57Z" }
}

budget.estimated_ru_consumed and --max-ru form a registry-estimated observation budget, not a provider billing cap. They intentionally exclude connection bootstrap, transient retries, and RPCs hidden inside the SDK.

2. Delta — wait until price drops 5% within a 1-hour window

chainwake bt subnet 19 price --drop-pct 5 --window-time 1h

Fires when the oldest price in the rolling 1-hour window is more than 5% above the current price. The window controls which samples are compared; it does not impose a runtime limit. --max-runtime alone controls when an unmatched watcher exits with timeout.

Omit the window to keep the first successful observation as an unexpiring baseline for this watcher:

chainwake bt subnet 28 burnrate --move-pct 1

3. Event — wait for a new subnet to be registered

chainwake bt event --type subnet-registered --max-runtime 24h

Subscribes to subnet registration events. Exits 0 on the first match with the event's decoded args in observed. Exits 1 if no event fires within 24 hours.


Exit codes

Agents parse JSON for detail; exit codes are for shell-level control flow.

Code status field Meaning
0 matched Condition fired
1 stopped / timeout / budget_exhausted Watcher finished without a match
2 user_error Invalid args, unknown resource
3 provider_error / auth_error RPC unavailable, or credentials/access required
4 internal_error Bug in chainwake

For watcher automation, pass --json; every watcher exit then emits a JSON payload on stdout, including watcher errors. Without that flag, an interactive TTY uses human-readable output automatically. Stderr carries diagnostics and is not part of the stable contract.


Output schema

Every watcher invocation run with --json emits exactly one JSON object on exit. Piped stdout also selects JSON automatically, but agents should use the explicit flag instead of depending on TTY detection. MCP configuration helpers, help/version output, and parsing before a watcher is selected are outside this watcher-envelope guarantee and use their documented formats. The schema is at schemas/output-v1.json.

schema_version: 1 identifies a closed contract. Consumers must validate payloads against the matching schema and reject unknown fields. Any output shape change—including an additive field or status value—requires a new schema_version and a new schema file. The Chainwake package version is independent of the output-schema version; do not infer schema compatibility from the package version.


Adapters (--out)

By default Chainwake uses human output on an interactive TTY and indented JSON when stdout is piped. Automation should pass --json explicitly. Use --out to redirect output:

# NDJSON to stdout, keep running after each match
chainwake bt subnet 19 price --below 0.05 --out stream

# Append NDJSON to a file
chainwake bt subnet 19 price --below 0.05 --out file:///tmp/watchers.ndjson

# Notify via Telegram (any apprise URI)
chainwake bt subnet 19 price --below 0.05 --out "tgram://bottoken/chatid"

--out is repeatable. Apprise supports ~100 notification destinations (Telegram, Discord, Slack, email, webhooks, and more). See the apprise URI reference for the full list.


MCP server

chainwake includes a built-in MCP server that exposes chain watchers as MCP tools for Hermes, OpenClaw, Claude Desktop, Cursor, and other MCP clients. Its exit-oriented catalogue maps each wired command to a tool; one filtered event tool covers both curated friendly names and raw Module.Event types. See the MCP guide.

chainwake mcp serve --stdio
chainwake mcp config hermes
chainwake mcp config openclaw

Configuration

Method Precedence Example
--rpc-url flag Highest --rpc-url wss://my-node:9944
CHAINWAKE_BT_RPC_URL env var Middle export CHAINWAKE_BT_RPC_URL=wss://...
Default (Blockmachine RPC) Lowest wss://rpc.blockmachine.io

Blockmachine is the default RPC provider for Bittensor at launch. The free tier works anonymously, so no configuration is needed for a first watcher. No API key is required. The architecture also supports any Substrate-compatible WebSocket endpoint.

--api-key is accepted by every command for higher-limit Blockmachine access or other authenticated RPC endpoints.

--max-runtime accepts duration strings: 30s, 10m, 2h, 1d. Default is unbounded. Agent and automation calls should always set an explicit bounded runtime.


Agent integration

Agents spawn a chainwake watcher as a subprocess, pass --json, and parse stdout. For watcher invocations, the contract is stable in JSON mode: stdout is one valid JSON object, exit code is always 0–4, and stderr is not parsed. Without --json, an interactive TTY is rendered as human-readable text.

import json, subprocess

proc = subprocess.run(
    [
        "chainwake", "bt", "subnet", "19", "price",
        "--below", "0.05", "--max-runtime", "5m",
        "--json",
    ],
    capture_output=True, text=True,
)
payload = json.loads(proc.stdout)
if proc.returncode == 0:
    print(f"Matched at block {payload['observed']['block']}")
elif proc.returncode == 1:
    print(f"No match: {payload['reason']}")  # timeout or budget_exhausted
elif payload["status"] == "auth_error":
    raise RuntimeError(
        "RPC access needs operator action; do not retry unchanged credentials"
    )

For MCP continuation, CLI supervisor re-entry, notification-only delivery, and restart durability, see Agent integration and MCP integration.


Status

chainwake is in active development. See PROGRESS.md for in-flight work.


License — MIT


Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chainwake-0.1.0.tar.gz (109.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chainwake-0.1.0-py3-none-any.whl (134.0 kB view details)

Uploaded Python 3

File details

Details for the file chainwake-0.1.0.tar.gz.

File metadata

  • Download URL: chainwake-0.1.0.tar.gz
  • Upload date:
  • Size: 109.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for chainwake-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3c82222aa4bd4f1a6b758040d64c55d4262ec57abb80c21adcb42b8f735234b0
MD5 06316d630c40abe740d3db1b930876ed
BLAKE2b-256 7f7b1c0939e5c491d23b8f027245d39ebfd0c1333ba7b69b49eb6ee218321666

See more details on using hashes here.

Provenance

The following attestation bundles were made for chainwake-0.1.0.tar.gz:

Publisher: publish.yml on taostat/chainwake

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chainwake-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: chainwake-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 134.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for chainwake-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a5cfb392934638416c2ecafa9902e4500c0aedfa2be0d265c287444ac43b7768
MD5 3d2fccebc53f6f452acc3dd55150bec0
BLAKE2b-256 4b2a9cd203eaf5067f74de7ceb466ec555c54647840e98bae14ce6887b67eea1

See more details on using hashes here.

Provenance

The following attestation bundles were made for chainwake-0.1.0-py3-none-any.whl:

Publisher: publish.yml on taostat/chainwake

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page