A high-performance, standalone blockchain monitoring service written in Go. Supports Ethereum, Binance Smart Chain, TRON, Bitcoin, and Litecoin with native coin monitoring plus configurable token contracts such as USDT and USDC.
- High Performance: Built in Go with concurrent processing and optimized RPC handling
- Circuit Breakers: Automatic failover between RPC providers with health monitoring
- Loose Coupling: Pluggable messaging system (RabbitMQ, webhooks)
- Extensible: Clean architecture for adding new blockchain networks
- Production Ready: Docker support, comprehensive logging, metrics
- Real-time: WebSocket connections with polling fallback
The architecture is organized into several core components:
- HTTP API: Exposes endpoints for health checks, wallet management, and statistics.
- Tracker Manager: Coordinates the tracking of blockchain activity using a shared base tracker for common logic.
- Blockchain Processors: Specialized modules for each supported blockchain (e.g., Ethereum, Bitcoin), responsible for RPC client management, transaction parsing, and block fetching.
- Messaging: Pluggable system for publishing events, supporting RabbitMQ, webhooks, and other integrations.
- Storage: Utilizes Redis and in-memory caching for fast access and persistence.
This composition-based approach allows most logic to be shared across blockchains, with only the processor modules needing customization for each network.
- β Block processing orchestration
- β Concurrency management
- β Health monitoring & metrics
- β Event publishing
- β Catchup logic & confirmations
- β Graceful shutdown
- π§ RPC client management
- π§ Transaction parsing
- π§ Block fetching
- π§ Address validation
- Go 1.24+
- Docker & Docker Compose
- Redis
- RabbitMQ
# Clone and start all services
git clone <repo>
cd bloop
make docker-run- Start infrastructure services:
make infra-up- Build and run the monitor:
make build
./bin/bloop-monitor- Start the test listener (in another terminal):
make test-listener- Add wallets to watch:
# Watch an Ethereum wallet
curl -X POST http://localhost:8080/api/v1/wallets/watch \
-H "Content-Type: application/json" \
-d '{"network": "ETH", "address": "0x742d35Cc6634C0532925a3b8D400E4C0d5C7c6B4", "wallet_id": "user-123"}'
# Watch a Litecoin wallet
curl -X POST http://localhost:8080/api/v1/wallets/watch \
-H "Content-Type: application/json" \
-d '{"network": "LTC", "address": "ltc1qexampleaddress", "wallet_id": "user-456"}'- Redis (port 6379)
- RabbitMQ (port 5672, management UI on 15672)
- Bloop Monitor (port 8080)
# Start dependencies
make dev-setup
docker-compose up -d redis rabbitmq
# Run the monitor
make runConfiguration via config/config.yaml or environment variables:
ethereum:
rpc_urls:
- "https://eth.llamarpc.com"
- "https://rpc.ankr.com/eth"
ws_url: "wss://eth.llamarpc.com"
tokens:
- currency: "USDT"
contract: "0xdAC17F958D2ee523a2206206994597C13D831ec7"
decimals: 6
- currency: "USDC"
contract: "<usdc-contract-address>"
decimals: 6
confirmations: 5
batch_size: 50
max_concurrent_blocks: 5
utxo:
- network: "BTC"
native_currency: "BTC"
api_urls:
- "https://mempool.space/testnet/api"
- "https://blockstream.info/testnet/api"
confirmations: 1
batch_size: 10
max_concurrent_blocks: 5
- network: "LTC"
native_currency: "LTC"
api_urls:
- "https://litecoinspace.org/api"
confirmations: 6
batch_size: 10
max_concurrent_blocks: 5
redis:
url: "redis://localhost:6379"
pool_size: 100
rabbitmq:
url: "amqp://bloop:bloop123@localhost:5672/"
exchange: "blockchain.events"ETH_RPC_URLS="https://eth.llamarpc.com,https://rpc.ankr.com/eth"
ETH_WS_URL="wss://eth.llamarpc.com"
REDIS_URL="redis://localhost:6379"
RABBITMQ_URL="amqp://bloop:bloop123@localhost:5672/"
LOG_LEVEL="info"curl http://localhost:8080/healthcurl http://localhost:9090/metricsKey tracker metrics exposed per network label:
bloop_tracker_block_gapbloop_tracker_last_processed_blockbloop_tracker_safe_headbloop_tracker_current_block_heightbloop_tracker_block_queue_lenbloop_tracker_error_count_totalbloop_tracker_skipped_channel_full_totalbloop_tracker_skipped_processed_total
curl -X POST http://localhost:8080/api/v1/wallets/watch \
-H "Content-Type: application/json" \
-d '{
"network": "ETH",
"address": "0x742d35Cc6634C0532925a3b8D400E4C0d5C7c6B4",
"wallet_id": "user-123"
}'curl -X DELETE http://localhost:8080/api/v1/wallets/unwatch \
-H "Content-Type: application/json" \
-d '{
"network": "ETH",
"address": "0x742d35Cc6634C0532925a3b8D400E4C0d5C7c6B4"
}'curl http://localhost:8080/api/v1/trackers/statscurl http://localhost:8080/api/v1/networksBy default, EVM trackers use block_fetch_mode: full, which calls eth_getBlockByNumber with full transactions on the regular RPC pool. The processor scans the returned transaction objects first, then fetches receipts only for transactions that can matter:
- Plain native transfers where
toorfromis watched. - Direct calls to configured token contracts.
Use block_fetch_mode: light only if a provider cannot serve full block payloads reliably. In light mode, the tracker fetches transaction hashes first and then fetches each transaction individually.
omini_rpc_urls are optional fallback RPCs for full block fetch failures. Regular RPCs are tried first.
# Get all watched wallets for all networks
curl http://localhost:8080/api/v1/wallets
# Get watched wallets for specific network
curl http://localhost:8080/api/v1/wallets?network=ETHThe project includes a test listener that connects to RabbitMQ and logs deposit events in real-time:
# Build and run the test listener
make test-listener
# Or run it directly
./bin/test-listenerThe test listener will:
- π§ Connect to RabbitMQ and listen for deposit events
- π° Log detailed deposit information when transactions are detected
- π Display colorful, formatted output for easy monitoring
- π Show network, amount, wallet ID, transaction hash, and more
π° DEPOSIT DETECTED!
================================================================================
π¨ DEPOSIT ALERT π¨
================================================================================
π Network: ETH
π Currency: ETH
π° Amount: 1.5
π Address: 0x742d35Cc6634C0532925a3b8D400E4C0d5C7c6B4
π€ Wallet ID: user-123
π Tx Hash: 0xabc123...
π¦ Block: 18500000
β° Time: 2023-12-01 14:30:25
β½ Gas Used: 21000
πΈ Gas Price: 20.5 gwei
================================================================================
When deposits are detected, events are published to RabbitMQ:
{
"type": "wallet.deposit",
"payload": {
"tx_hash": "0x...",
"wallet_id": "user-123",
"wallet_address": "0x742d35Cc6634C0532925a3b8D400E4C0d5C7c6B4",
"from_address": "0x...",
"amount": "1.5",
"currency": "ETH",
"network": "ETH",
"block_number": 18500000,
"confirmations": 5,
"timestamp": "2023-11-15T10:30:00Z",
"network_fee": "0.001",
"status": "CONFIRMED"
},
"timestamp": "2023-11-15T10:30:00Z",
"source": "ETH"
}- Concurrent Processing: Goroutines for parallel block/transaction processing
- Circuit Breakers: Automatic RPC provider failover
- Batch Operations: Redis pipelining and RPC batching
- Smart Caching: Multi-level caching with TTL
- Rate Limiting: Configurable RPC rate limits
- Connection Pooling: Optimized Redis and RPC connections
The architecture is designed for easy extension:
- Implement Tracker Interface:
type Tracker interface {
Start(ctx context.Context) error
Stop() error
AddWatchedWallet(ctx context.Context, address, walletID string) error
RemoveWatchedWallet(ctx context.Context, address string) error
GetNetwork() types.BlockchainType
IsRunning() bool
GetStats() TrackerStats
}- Add to Factory:
func (f *DefaultTrackerFactory) CreateTracker(network types.BlockchainType) (Tracker, error) {
switch network {
case types.Ethereum:
return f.createEthereumTracker()
case types.Bitcoin:
return f.createBitcoinTracker() // Your implementation
}
}- Update Configuration:
bitcoin:
rpc_url: "https://bitcoin-rpc.com"
confirmations: 6
utxo:
- network: "LTC"
native_currency: "LTC"
api_urls:
- "https://litecoinspace.org/api"
confirmations: 6bloop/
βββ cmd/monitor/ # Main application
βββ internal/
β βββ api/ # HTTP API handlers
β βββ blockchain/ # Blockchain trackers
β β βββ ethereum/ # Ethereum implementation
β βββ config/ # Configuration management
β βββ messaging/ # RabbitMQ/webhook publishers
β βββ storage/ # Redis storage layer
β βββ types/ # Shared types
βββ config/ # Configuration files
βββ docker-compose.yml # Development environment
make build # Build binary
make test # Run tests
make lint # Run linter
make fmt # Format code
make docker-run # Run with Docker
make dev # Development modeStructured JSON logging with configurable levels:
{
"level": "info",
"msg": "ETH deposit detected",
"tx_hash": "0x...",
"wallet_id": "user-123",
"amount": "1.5",
"currency": "ETH",
"block_number": 18500000,
"time": "2023-11-15T10:30:00Z"
}- Blocks processed per second
- Transaction processing latency
- RPC provider health
- Memory/CPU usage
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Run
make lintandmake test - Submit a pull request
MIT License - see LICENSE file for details.