Internal packages in the nostr-watch monorepo are shared infrastructure that sits at the base of the dependency graph. They are not published to npm and are not intended for standalone use outside the monorepo. Every consuming package adds them as a pnpm workspace dependency. The strict layering rule is that internal packages have no dependencies onDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/sandwichfarm/nostr-watch/llms.txt
Use this file to discover all available pages before exploring further.
libraries/ or apps/ packages — only the reverse direction is permitted.
@nostrwatch/logger
Structured, level-gated logging. Winston wrapper with browser fallback and per-namespace labeling.
@nostrwatch/utils
Shared utility functions — key conversion, array helpers, URL parsing, signing, and runtime detection.
@nostrwatch/controlflow
BullMQ-backed job queues and exponential-backoff retry management for relay check workers.
@nostrwatch/seed
Bootstrap relay lists from config, static files, databases, REST APIs, or Nostr events.
@nostrwatch/publisher
Build and publish NIP-66 relay status and monitor registration events. See publishing events.
@nostrwatch/announce
Publish the three monitor announcement events (kind 0, 10002, 10166) on every boot.
@nostrwatch/logger
@nostrwatch/logger wraps Winston to provide structured, level-gated logging for both Node.js and browser environments. On Node.js it uses Winston with colorized, timestamped output; in the browser it falls back to the native console. Every consuming package instantiates Logger with a namespace string, giving each log line a [label] prefix that identifies which module produced it.
Logger class
| Parameter | Type | Default | Description |
|---|---|---|---|
name | string | — | Label printed with every log line |
log_level | string | 'INFO' | Minimum level to emit: FATAL, ERROR, WARN, INFO, DEBUG |
split_logs | boolean | false | Reserved for future use |
debug level also checks whether the debug npm package’s namespace is enabled via the DEBUG environment variable, allowing selective per-namespace debug output:
@nostrwatch/utils
@nostrwatch/utils provides roughly 15 utility modules shared across the monorepo. Each module is independently importable — import only what you need. The package builds for both Node.js and browser environments.
Key exports
Keys (keys.ts)
nsec1… bech32 strings or 64-char hex. nsecToBytes and nsecToHex throw on invalid input; tryNsecToHex returns an empty string — use it when reading from environment variables.
Signing (signing.ts)
EventSigner from an nsec or hex private key. The returned signer holds the derived public key and can sign any unsigned Nostr event. Wraps nostr-tools/pure internally.
Arrays (array.ts)
shuffleArray shuffles in place using Fisher-Yates. chunkArray shuffles the array first, then splits it into chunks of the given size.
URL (url.ts)
parseUrl returns null on invalid input instead of throwing. normalizeUrl returns the canonical URL string, or the original input if parsing fails.
Browser detection (browser.ts)
true when running in a browser or Web Worker context. Safe to call in any environment.
@nostrwatch/controlflow
@nostrwatch/controlflow provides BullMQ-backed job queues and a cache-based retry manager for the relay check pipeline. It solves two recurring problems: distributing relay-check work across workers with guaranteed delivery, and backing off automatically when a relay consistently fails to respond.
Prerequisites: A running Redis instance. Set REDIS_HOST, REDIS_PORT, and REDIS_PASSWORD (if applicable) in the consuming application’s environment.
Queue factories
All queue factory functions return a{ $Queue, $QueueEvents, Worker } triple. Calls with the same name return the same cached singleton.
| Factory | Description |
|---|---|
TrawlQueue(qopts?) | Singleton queue for relay trawling jobs |
NocapdQueue(name?, qopts?) | Queue for nocap relay-check jobs; defaults to 'NocapdQueue' |
PersistQueue(name?, qopts?) | Queue for database persistence jobs; defaults to 'PersistQueue' |
QueueInit(key, qopts?) | Low-level factory for creating a named queue not covered by the above |
BullMQ | Re-exports raw BullMQ Queue, QueueEvents, and Worker classes |
RetryManager
RetryManager tracks per-relay retry counts in cache and maps them to exponential delay intervals. Use it to decide how long to wait before re-queuing a relay that has failed:
setRetries(url, true) to reset a relay’s counter after a successful check, or setRetries(url, false) to increment it. Call getExpiry(url) to get the current backoff delay in milliseconds.
Default retry escalation ladder:
| Retries | Delay |
|---|---|
| 1–3 | 1 hour |
| 4–6 | 24 hours |
| 7–13 | 7 days |
| 14–17 | 28 days |
| 18–29 | 90 days |
@nostrwatch/seed
@nostrwatch/seed collects relay URLs from multiple discovery sources to bootstrap the relay monitoring pipeline. Results are deduplicated, sanitized, and filtered by network type before being handed off to the monitor.
Supported source types
| Source | Description |
|---|---|
config | Relay URLs passed directly as an array in options.config |
static | Relay URLs read from a YAML or JSON file at options.static.path |
db | Relay URLs queried from a SQLite database (filters by allowedNetworks) |
api | Relay URLs fetched from a REST API at options.api.rest_api/online |
events | Relay URLs extracted from NIP-66 kind 30166 events by specified pubkeys |
cache | Relay URLs queried from the local @nostrwatch/db relay status table |
allowedNetworks to ['clearnet'], ['tor'], ['i2p'], or any combination. Defaults to ['clearnet'] if omitted.
@nostrwatch/announce
@nostrwatch/announce generates and publishes three Nostr events each time a monitor starts: a kind 10166 monitor registration event, a kind 10002 relay list event, and a kind 0 profile event. Together these events allow other clients and monitors to discover this monitor’s identity and capabilities automatically.
For full usage details, see publishing events.
Deprecated packages
Two internal packages are deprecated and maintained as stubs for migration guidance:| Package | Replacement |
|---|---|
internal/nwcache | Direct cache integrations in consuming packages |
apps/nocapd | apps/relaymon |