Synopsis
Admin
cowboy watchtower init
Deploy and initialize the WatchtowerRegistry actor on the chain.
Behavior:
- Load the private key using key auto-discovery.
- Deploy the
WatchtowerRegistryactor. - Store the registry address in
.cowboy/config.json.
Publisher
cowboy watchtower new feed
Create a new feed (StreamActor) and register it in WatchtowerRegistry.
Flags:
| Flag | Default | Description |
|---|---|---|
--name | required | Feed name |
--description | "" | Feed description |
--access-mode | open | open (plaintext) or subscriber-paid (CBSS-routed ciphertext) |
--fee-per-epoch-cby | 0 | Per-epoch publisher fee in CBY wei. Required when --access-mode=subscriber-paid. |
--protocol-fee-bps | 0 | Protocol fee in basis points (0..=5000). Credited to system Treasury 0x08. |
--key-epoch-blocks | 600 | Blocks per key epoch (default 10 min at 1s blocks) |
--ring-buffer-capacity | 10000 | Max retained messages |
--max-subscribers | 10000 | Subscriber cap |
--publisher-treasury | tx signer | Where publisher revenue is credited |
--access-mode=subscriber-paid, the publisher must follow up with pre-wrap-epochs (or run wrap-daemon) before subscribers can acquire access.
cowboy watchtower feed <id> pre-wrap-epochs
Register a batch of per-epoch wrapped content keys, ready for subscriber pickup via CBSS committee delivery.
Flags:
| Flag | Description |
|---|---|
--from <u64> | First epoch in the batch |
--to <u64> | Last epoch in the batch (inclusive) |
cbss-client::cip7::pre_wrap_batch locally with the publisher’s stream_secret (held in ~/.cowboy/watchtower-secrets/<stream_id>.key), then submits a register_content_keys actor call to the Stream Key Manager. Batch size capped at MAX_REGISTER_CONTENT_KEYS_BATCH = 10000 per call.
cowboy watchtower feed <id> wrap-daemon
Long-running daemon: keeps the next N epochs pre-wrapped continuously by polling the chain for the current epoch and pre-wrapping ahead when the buffer drops below --depth / 2.
Flags:
| Flag | Description |
|---|---|
--depth <u64> | Target lookahead in epochs (default 100) |
cowboy watchtower feed <id> publish
Publish a new message to the feed.
Flags:
| Flag | Description |
|---|---|
--kind <s> | Message kind (news, price_batch, alert, etc.) |
--data <json> | Inline JSON payload. Max 16 KiB unencrypted; max 16,344 bytes plaintext for subscriber-paid. |
--tags <k=v,...> | Header tags for subscriber filter matching |
--content-type <mime> | Default application/json |
subscriber-paid feeds, the CLI derives the per-epoch content_key locally using the publisher’s stream_secret, encrypts the payload with XChaCha20-Poly1305 (PyNaCl), and submits the ciphertext envelope. The ed25519 signature over the canonical signing payload is also computed locally.
cowboy watchtower feed <id> rotate-publisher-key
Allocate a new signing_key_id and switch the active publisher signing key. Past messages remain verifiable via get-key-at-sequence.
cowboy watchtower feed <id> rewrap-epochs
Re-wrap a range of epochs (bumps each epoch’s generation counter). Invalidates threshold signatures previously aggregated against the prior generation — subscribers must re-acquire access after a re-wrap.
cowboy watchtower feed <id> set-policy
Set subscription policy: public (anyone can subscribe) or private-allowlist.
cowboy watchtower feed <id> allowlist add|remove <address>
Manage the allowlist when policy is private-allowlist.
Subscriber
cowboy watchtower feed <id> subscribe
Create or update a subscription.
Flags:
| Flag | Description |
|---|---|
--mode push|pull|push-fallback | Delivery mode |
--filter <json> | JSON filter DSL (max depth 4, ≤16 predicates) |
--start-cursor <u64> | Initial cursor (omitted = subscribe at current head) |
--account-key-id <u64> | Required for subscriber-paid feeds — selects which registered X25519 key receives CBSS deliveries |
cowboy watchtower feed <id> unsubscribe
Cancel the subscription. Status → CANCELLED. Re-subscription requires a new subscribe call.
cowboy watchtower feed <id> get-since
Pull messages with sequence > cursor.
Flags:
| Flag | Description |
|---|---|
--cursor <u64> | Last consumed sequence |
--limit <u32> | 1..=500 |
subscriber-paid feeds (decryption is client-side via cowboy watchtower feed <id> consume).
cowboy watchtower feed <id> get-head
Returns head_sequence, floor_sequence, and feed metadata.
cowboy watchtower feed <id> get-key-at-sequence
Returns the publisher signing key effective at the given sequence (for subscriber-side signature verification across publisher-key rotations).
Subscriber paid-mode
cowboy watchtower account register-key
Register an X25519 public key as a CBSS recipient identity. The private key is stashed in the local keystore (~/.cowboy/watchtower-keys/<key_id>.key, 0600 perms) and never leaves the host.
Flags:
| Flag | Description |
|---|---|
--scheme x25519 | Required (only scheme in v1) |
cowboy watchtower account list-keys
List registered keys with their account_key_id, registration block, and Active / Revoked status.
cowboy watchtower account revoke-key <key_id>
Revoke a previously registered key. In-flight SealRequests already on chain continue per CBSS rules; future acquire-access calls referencing this key_id fail with KEY_REVOKED.
cowboy watchtower feed <id> acquire-access
Purchase rolling stream access up through --to-epoch.
Flags:
| Flag | Description |
|---|---|
--to-epoch <u64> | Last epoch to cover |
--account-key-id <u64> | Which registered X25519 key receives committee deliveries |
--beneficiary <addr> | Defaults to caller. Stream access accrues here. |
--payer <addr> | Defaults to caller. CBY debit comes from here. Allows sponsored purchases. |
cowboy watchtower feed <id> fetch-keys
Block until CBSS committee delivers wrapped content keys for the listed epochs, then unwrap each to the local content-key cache.
Flags:
| Flag | Description |
|---|---|
--account-key-id <u64> | X25519 key used to unwrap |
--epochs <list> | Comma-separated epoch numbers or ranges (100-110,200,300-305) |
cowboy watchtower feed <id> consume
Fetch ciphertext from the feed and decrypt locally using cached content keys.
Flags:
| Flag | Description |
|---|---|
--account-key-id <u64> | X25519 key for content-key lookup |
--cursor <u64> | Last consumed sequence |
--limit <u32> | Max messages to fetch (1..=500) |
Discovery
cowboy watchtower list
List all feeds registered in WatchtowerRegistry.
cowboy watchtower feeds [--owner <addr>]
Alias for list, optionally filtered by owner.
cowboy watchtower feed <id> info
Show feed metadata: owner, access-mode, fee config (if paid), current head/floor sequence, key epoch info, and subscription policy.
cowboy watchtower feed <id> subscribers
List active subscribers.
Notes
- All write commands use key auto-discovery for the publisher private key.
- For paid-mode subscriber flows, the X25519 private key is stored in
~/.cowboy/watchtower-keys/<key_id>.key. Treat this as sensitive — compromise gives the holder access to every stream the account has acquired access to. - Publisher
stream_secretis stored at~/.cowboy/watchtower-secrets/<stream_id>.key. Loss of this secret breaks future re-wrapping (the publisher can rotate by generating a new secret + bumping each epoch’s generation viarewrap-epochs). - CBSS committee liveness is a hard dependency for paid-mode flows;
fetch-keysandacquire-accesswill block / fail-fast if the committee is unavailable.

