Running locally
Run the Watch Tower locally for development and testing.
Basic usage
Run the Watch Tower with the default configuration:
CLI commands
The Watch Tower CLI provides two main commands:
run
Start the Watch Tower in monitoring mode:
Available options:
-
—config-path (string, default:
./config.json)
Path to the chain configuration file.
Environment variable: CONFIG_PATH
-
—database-path (string, default:
./database)
Path to the LevelDB database directory.
Environment variable: DATABASE_PATH
-
—log-level (string, default:
INFO)
Set the logging level. Options: TRACE, DEBUG, INFO, WARN, ERROR.
Environment variable: LOG_LEVEL
-
—dry-run (boolean, default:
false)
Run without publishing orders to the OrderBook API. Useful for testing.
Environment variable: DRY_RUN
-
—one-shot (boolean, default:
false)
Run the Watch Tower once and exit instead of continuous monitoring.
Environment variable: ONE_SHOT
-
—api-port (number, default:
8080)
Port for the REST API server.
Environment variable: API_PORT
-
—disable-api (boolean, default:
false)
Disable the REST API server.
Environment variable: DISABLE_API
-
—silent (boolean, default:
false)
Disable notifications (local logging only, no Slack alerts).
Environment variable: DISABLE_NOTIFICATIONS
-
—slack-webhook (string)
Slack webhook URL for error notifications.
Environment variable:
SLACK_WEBHOOK
-
—only-owner (string[])
Monitor programmatic orders only from specific owner addresses (safes). Can be specified multiple times.
dump-db
Dump the database contents as JSON:
Example:
Expected output
When you start the Watch Tower, you should see output similar to:
What the Watch Tower does
When running, the Watch Tower continuously:
- Monitors blockchain events - Listens for
ConditionalOrderCreated and MerkleRootSet events
- Fetches programmatic orders - Retrieves order details from the blockchain
- Posts discrete orders - Submits orders to the CoW Protocol OrderBook API
- Updates registry - Maintains a local database of active programmatic orders
- Removes expired orders - Cleans up orders that have expired or been cancelled
Accessing the API server
By default, the Watch Tower starts a REST API server on port 8080 with the following endpoints:
Response:
Configuration
Response: Returns the current Watch Tower configuration (excluding sensitive data).
Database dump
Response: Returns the complete database state for chain ID 1 (mainnet) in JSON format.
Prometheus metrics
Response: Returns Prometheus-formatted metrics for monitoring.
Viewing logs
The Watch Tower uses a flexible logging system that can be controlled via the LOG_LEVEL environment variable.
Basic log levels
Set the global log level:
Available levels: TRACE, DEBUG, INFO, WARN, ERROR
Module-specific logging
Enable detailed logging for specific modules:
Advanced logging patterns
Use regex patterns to match specific logger names:
Running in development mode
-
Set up test configuration
Create a development configuration file for Sepolia testnet:
Edit to include only the Sepolia network with your test RPC endpoint.
-
Enable debug logging
Run with detailed logging to see all operations:
-
Use dry-run mode
Test without actually posting orders to the OrderBook API:
-
Test one-shot mode
Process current state once and exit:
Using environment variables
You can configure the Watch Tower entirely through environment variables:
Or use a .env file:
Then run:
Monitoring specific safes
To monitor programmatic orders from specific Safe addresses only:
Stopping the Watch Tower
To gracefully stop the Watch Tower, press Ctrl+C. The Watch Tower will:
- Stop processing new blocks
- Complete any in-progress operations
- Close the API server
- Close the database connection
- Exit cleanly
Troubleshooting
Database issues
If you encounter database errors, try removing the database and resyncing:
RPC connection issues
Enable debug logging to see RPC connection details:
Check that your RPC endpoint is accessible and has sufficient rate limits.
High RPC usage
Reduce RPC calls by:
- Increasing
processEveryNumBlocks to skip blocks
- Setting
pageSize appropriately for your RPC provider
- Using a dedicated RPC endpoint with higher rate limits
Next steps
After running locally:
Last modified on March 12, 2026