A TypeScript Node.js monitoring tool for RSK (Rootstock) blockchain nodes and Tropykus DeFi protocol markets. Continuously monitors block synchronization, market data consistency, and provider performance across multiple RPC endpoints.
- β Multi-Provider Monitoring - Tracks 4 providers: Public Node, Alchemy, Tropykus, Rabby
- β Block Number Sync - Detects when providers are out of sync
- β Market Data Validation - Compares 10 market metrics across all providers
- β Inconsistency Detection - Automatically flags when providers disagree
- β Performance Tracking - Records response times for every request
- β Database Integration - Stores all data in Supabase for historical analysis
- β Error Tracking - Captures and logs all provider failures
- β 24/7 Operation - Runs continuously with graceful shutdown handling
- Node.js 18+ installed
- Supabase account (free tier works)
- (Optional) Render account for cloud deployment
-
Clone and install
git clone <your-repo-url> cd node-load-monitor npm install
-
Set up Supabase
- Create project at https://app.supabase.com
- Run migration:
supabase/migrations/001_initial_schema.sql - Disable RLS:
DISABLE_RLS.sql
-
Configure environment
cp .env.example .env # Edit .env with your Supabase credentials -
Run locally
npm run dev # Development with auto-reload npm run build && npm start # Production build
-
Verify it works
- Check console for:
[Database] Created monitoring run: ... - Check Supabase tables for new rows every 30 seconds
- Check console for:
π Detailed Setup: See DATABASE_SETUP.md
Deploy to Render for 24/7 cloud monitoring:
# 1. Push to GitHub
git add .
git commit -m "Initial commit"
git push origin main
# 2. Follow deployment guideπ Full Deployment Guide: See RENDER_DEPLOYMENT.md
βββ src/
β βββ index.ts # Main monitoring logic
β βββ database.ts # Supabase client and helpers
β βββ constants.ts # RPC endpoints and configuration
β βββ types.ts # TypeScript type definitions
β βββ abis/ # Smart contract ABIs
βββ supabase/
β βββ migrations/ # Database schema
βββ dist/ # Compiled JavaScript (generated)
βββ render.yaml # Render deployment config
βββ .env # Environment variables (not committed)
βββ *.md # Documentation
Every 30 seconds, the monitor:
- Fetches block numbers from all 4 providers via
eth_blockNumber - Queries market data (10 metrics) from the first active market
- Compares results across providers to detect inconsistencies
- Records everything to Supabase database
- Logs to console with timestamps and status indicators
| Provider | Type | URL |
|---|---|---|
| Public Node | RSK Public RPC | https://public-node.rsk.co/ |
| Alchemy | Third-party RPC | https://rootstock-mainnet.g.alchemy.com/... |
| Tropykus | Tropykus-operated node | https://rsknode-4.tropykus.com/rsk |
| Rabby | Wallet API proxy | https://app-api.rabby.io/... |
For each market (cToken contract):
balanceOfUnderlying- User's underlying balanceborrowBalanceStored- User's borrow balancegetCash- Available liquiditydecimals- Token decimalsexchangeRateStored- Current exchange rateborrowRatePerBlock- Borrow APYsupplyRatePerBlock- Supply APYtotalBorrows- Total borrowedtotalSupply- Total suppliedtotalReserves- Protocol reserves
- monitoring_runs - Each 30-second cycle
- block_number_checks - Block number results per provider
- market_data_checks - Market data results per provider
- data_inconsistencies - When providers disagree
-- Provider uptime (last 24h)
SELECT provider,
COUNT(*) as total,
SUM(CASE WHEN success THEN 1 ELSE 0 END) as successes,
ROUND(100.0 * SUM(CASE WHEN success THEN 1 ELSE 0 END) / COUNT(*), 2) as uptime_percent
FROM block_number_checks
WHERE timestamp > NOW() - INTERVAL '24 hours'
GROUP BY provider;
-- Most common errors
SELECT provider, error_message, COUNT(*) as count
FROM market_data_checks
WHERE success = false
GROUP BY provider, error_message
ORDER BY count DESC
LIMIT 10;π More Queries: See DATABASE_SETUP.md
| Command | Description |
|---|---|
npm run dev |
Start with auto-reload (development) |
npm run build |
Compile TypeScript to JavaScript |
npm start |
Run compiled code (production) |
npm test |
Run tests (not yet implemented) |
| Variable | Required | Description |
|---|---|---|
SUPABASE_URL |
Optional | Supabase project URL |
SUPABASE_KEY |
Optional | Supabase anon key |
NODE_ENV |
Optional | production or development |
Note: The monitor works without Supabase, but won't persist data.
Edit src/index.ts:
setInterval(runMonitoring, 30000); // Change 30000 to desired millisecondsEdit src/index.ts:
const testMarket = activeMarkets[0]; // Change index or market addressEdit src/constants.ts to add new RPC endpoints, then update monitoring functions.
| Issue | Solution |
|---|---|
| "Database recording disabled" | Set SUPABASE_URL and SUPABASE_KEY in .env, run npm install |
| No data in Supabase | Run DISABLE_RLS.sql in Supabase SQL Editor |
| Build errors | Run npm install to ensure all dependencies installed |
| TypeScript errors | Delete dist/, node_modules/, run npm install && npm run build |
π Detailed Troubleshooting: See TROUBLESHOOTING.md
- π QUICK_START.md - 5-minute setup guide
- π DATABASE_SETUP.md - Complete Supabase setup
- π RENDER_DEPLOYMENT.md - Deploy to Render
- π TROUBLESHOOTING.md - Common issues and fixes
- π IMPLEMENTATION_SUMMARY.md - Technical details
- π CLAUDE.md - Architecture and AI context
- Language: TypeScript 5.9+
- Runtime: Node.js
- Blockchain: ethers.js v6 for RSK/Rootstock interactions
- HTTP: axios for JSON-RPC calls
- Database: Supabase (PostgreSQL)
- Deployment: Render (Background Worker)
# Development mode (auto-reloads on changes)
npm run dev
# Production mode
npm run build
npm start- Update contract ABIs in
src/abis/ - Add metric to
fetchMarketInfoFromNode()insrc/index.ts - Update database schema in
supabase/migrations/ - Add column to
market_data_checkstable
- Strict TypeScript configuration
- ESModuleInterop enabled
- Source maps for debugging
- Type declarations generated
Initialize
ββ> Fetch active markets from Unitroller
ββ> Filter deprecated markets
Every 30 seconds:
ββ> Create monitoring run (database)
ββ> Compare block numbers across all providers
β ββ> Record each result
β ββ> Detect inconsistencies
ββ> Test market info across all providers
β ββ> Fetch 10 metrics per provider
β ββ> Record each result
β ββ> Detect inconsistencies
ββ> Complete monitoring run with statistics
- Non-blocking database writes (won't crash monitor)
Promise.allSettled()for parallel provider checks- Graceful degradation if Supabase unavailable
- SIGINT/SIGTERM handlers for clean shutdown
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make changes and test locally
- Commit:
git commit -m "Add feature" - Push:
git push origin feature-name - Open a Pull Request
ISC
- Issues: Open an issue on GitHub
- Questions: Check TROUBLESHOOTING.md
- Deployment: See RENDER_DEPLOYMENT.md
- Add HTTP health check endpoint
- Implement alerting system (Slack/Discord webhooks)
- Dashboard for real-time monitoring
- Support for multiple markets simultaneously
- Configurable monitoring intervals via env vars
- Grafana integration for metrics visualization
- Rate limiting detection and tracking
- Built for Tropykus DeFi protocol monitoring
- Uses RSK (Rootstock) blockchain infrastructure
- Powered by Supabase for data persistence
- Deployed on Render for reliable 24/7 operation
Made with β€οΈ for reliable blockchain monitoring