A Golang tool that monitors multiple blockchain networks simultaneously for RootSubmitted
events and sends notifications to Slack.
- π Multi-Network Support: Monitors 11+ blockchain networks simultaneously
- π Real-time Event Monitoring: Tracks
RootSubmitted
events from your smart contracts - π’ Rich Slack Notifications: Network-specific notifications with emojis and detailed information
- βοΈ Flexible Configuration: YAML config or environment variables
- π‘οΈ Robust: Handles network failures, reconnections, and graceful shutdowns
- π Production Ready: Concurrent monitoring with proper resource management
The tool supports monitoring on the following blockchain networks:
Network | Chain ID | Emoji | Environment Variable |
---|---|---|---|
Ethereum | 1 | πΉ | ETH_NODE_URL |
Polygon | 137 | π£ | POLYGON_NODE_URL |
BSC | 56 | π‘ | BSC_NODE_URL |
Arbitrum | 42161 | π΅ | ARBITRUM_NODE_URL |
Avalanche | 43114 | π΄ | AVAX_NODE_URL |
Base | 8453 | π· | BASE_NODE_URL |
Berachain | 80094 | π» | BERA_NODE_URL |
Mantle | 5000 | π€ | MANTLE_NODE_URL |
Optimism | 10 | πΈ | OPTIMISM_NODE_URL |
Sonic | 146 | π« | SONIC_NODE_URL |
Unichain | 1301 | π¦ | UNICHAIN_NODE_URL |
The tool monitors the following Solidity event across all networks:
event RootSubmitted(bytes32 indexed campaignId, bytes32 pendingRoot, uint256 effectiveTimestamp);
- Go 1.21 or later
- Ethereum node access (Infura, Alchemy, or your own node)
- Slack Bot Token with appropriate permissions
- Clone or create the project directory:
mkdir distributor-monitor
cd distributor-monitor
- Initialize the Go module:
go mod init distributor-monitor
- Install dependencies:
go mod tidy
- Copy the example environment file:
cp env.example .env
- Update
.env
with your settings:
# Global contract address (if same across all networks)
CONTRACT_ADDRESS=0x1234567890123456789012345678901234567890
# Network-specific RPC URLs
ETH_NODE_URL=https://mainnet.infura.io/v3/YOUR_PROJECT_ID
POLYGON_NODE_URL=https://polygon-mainnet.infura.io/v3/YOUR_PROJECT_ID
# ... (add only the networks you want to monitor)
# Slack configuration
SLACK_TOKEN=xoxb-your-slack-bot-token
SLACK_CHANNEL=#distributor-alerts
- Update
config.yaml
to specify networks directly:
networks:
- name: "ethereum"
chain_id: 1
rpc_url: "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
contract_address: "0x1234567890123456789012345678901234567890"
start_block: 0
- name: "polygon"
chain_id: 137
rpc_url: "https://polygon-mainnet.infura.io/v3/YOUR_PROJECT_ID"
contract_address: "0x1234567890123456789012345678901234567890"
start_block: 0
- Network-specific contract addresses: Set
{NETWORK}_CONTRACT_ADDRESS
if contracts differ per network - Global contract address: Set
CONTRACT_ADDRESS
if all networks use the same contract - Selective monitoring: Only configure RPC URLs for networks you want to monitor
- Custom start blocks: Set different starting blocks per network if needed
- Go to Slack API Apps
- Create a new app
- Add the following OAuth scopes:
chat:write
chat:write.public
- Install the app to your workspace
- Copy the Bot User OAuth Token (starts with
xoxb-
) - Invite the bot to your desired channel
- Development:
go run main.go
- Production Build:
go build -o distributor-monitor main.go
./distributor-monitor
- With Custom Config:
./distributor-monitor -config custom-config.yaml
When a RootSubmitted
event is detected, you'll receive a network-specific Slack message like:
πΉ RootSubmitted Event Detected - ethereum
Network: πΉ ethereum (Chain ID: 1)
Contract Address: 0x1234...567890
Campaign ID: 0x1234...abcd
Pending Root: 0x5678...efgh
Effective Timestamp: 2024-01-15 14:30:25 UTC
Block Number: 18956789
Transaction Hash: 0x9abc...def0
Block Timestamp: 2024-01-15 14:30:23 UTC
Each network has its own emoji for easy identification in your Slack channel!
Create a Dockerfile
:
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o distributor-monitor main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/distributor-monitor .
COPY --from=builder /app/config.yaml .
CMD ["./distributor-monitor"]
Build and run:
docker build -t distributor-monitor .
docker run -d --name distributor-monitor distributor-monitor
Create /etc/systemd/system/distributor-monitor.service
:
[Unit]
Description=Distributor Monitor
After=network.target
[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/distributor-monitor
ExecStart=/path/to/distributor-monitor/distributor-monitor
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable distributor-monitor
sudo systemctl start distributor-monitor
The application provides structured logging with configurable levels:
debug
: Detailed information for debugginginfo
: General information about operationswarn
: Warning messages for potential issueserror
: Error messages for failures
View logs in real-time:
./distributor-monitor 2>&1 | tee monitor.log
-
Connection Failed:
- Verify your RPC URLs are correct for each network
- Check if your node providers are accessible
- Ensure you have sufficient API rate limits
- The tool will skip networks with invalid configurations
-
No Networks Monitored:
- Check that at least one
{NETWORK}_NODE_URL
environment variable is set - Verify contract addresses are configured
- Check logs for "Skipping network" messages
- Check that at least one
-
Slack Messages Not Sending:
- Verify your bot token is correct
- Check if the bot is invited to the channel
- Ensure the bot has
chat:write
permissions
-
Events Not Detected:
- Verify contract addresses are correct for each network
- Check if contracts have emitted any events
- Monitor logs for network-specific error messages
- Use different starting blocks if needed
-
High Resource Usage:
- Increase
poll_interval
to reduce API calls - Decrease
batch_size
for slower networks - Monitor only essential networks
- Increase
- Adjust
poll_interval
based on your needs (lower = more responsive, higher = less load) - Set appropriate
batch_size
to handle high-volume contracts - Use WebSocket connection for real-time monitoring (if supported by your provider)
distributor-monitor/
βββ main.go # Main application entry point
βββ internal/
β βββ config/ # Configuration management
β βββ config.go # Main config struct and loading
β βββ networks.go # Network definitions and utilities
β βββ README.md # Config package documentation
βββ config.yaml # Configuration template
βββ env.example # Environment variables template
βββ Dockerfile # Container configuration
βββ Makefile # Build and deployment commands
βββ README.md # This file
go test ./...
To add support for a new blockchain network:
-
Edit
internal/config/networks.go
:- Add network to
LoadNetworksFromEnv
function - Add emoji in
GetNetworkEmoji
function - Add to
SupportedNetworks
function
- Add network to
-
Update environment variable template in
env.example
-
Update documentation in relevant README files
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
For issues and questions:
- Check the troubleshooting section
- Review the logs for error messages
- Create an issue in the repository