Backend services for M-OBS (Mantle Observability Stack) - includes API and Worker services.
GitHub: https://github.com/hackonteam/m-obs-backend
Main Repository: https://github.com/hackonteam/m-obs
The backend consists of two main services:
- REST API with 11 endpoints
- Read-only operations (no RPC interaction)
- Serves data to frontend
- Auto-generated OpenAPI docs
- 4 background pipelines:
- Provider Probe (30s) - RPC health monitoring
- Block Scanner (2s) - Transaction ingestion with reorg detection
- Metrics Rollup (60s) - Per-minute metric aggregation
- Alert Evaluator (30s) - Alert rule evaluation
┌──────────────┐
│ FastAPI │───► Supabase PostgreSQL
│ API │
└──────────────┘
▲
│
┌──────┴──────────┐
│ Worker │───► Supabase PostgreSQL
│ (4 Pipelines) │
└─────────────────┘
▲
│
┌──────┴──────────┐
│ Mantle Mainnet │
│ RPC Providers │
└─────────────────┘
- Language: Python 3.11+
- API Framework: FastAPI
- Async Runtime: asyncio
- Database Client: asyncpg
- RPC Client: aiohttp
- Configuration: pydantic-settings
- Python 3.11 or higher
- pip or uv package manager
- Supabase PostgreSQL database (with migrations applied)
- Mantle RPC endpoint(s)
Create .env file in the backend directory:
# Database
DATABASE_URL=postgresql://user:password@host:port/database
# Mantle RPC Endpoints (comma-separated)
MANTLE_RPC_ENDPOINTS=https://rpc.mantle.xyz,https://mantle.publicnode.com
# API Configuration
API_HOST=0.0.0.0
API_PORT=8000
CORS_ORIGINS=http://localhost:5173,https://yourdomain.com
# Worker Configuration
WORKER_ENABLED_PIPELINES=provider_probe,block_scanner,metrics_rollup,alert_evaluator
# Optional: Sentry for error tracking
SENTRY_DSN=https://your-sentry-dsncd api
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -e .
# Run API
uvicorn src.main:app --reload --host 0.0.0.0 --port 8000
# API will be available at:
# - http://localhost:8000
# - OpenAPI docs: http://localhost:8000/docscd worker
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -e .
# Run worker
python -m src.main
# Worker will start all 4 pipelines# API tests
cd api
pytest
# Worker tests
cd worker
pytest- Supabase Database: Set up and apply migrations from the main repository
- GitHub Account: Connected to Render
- Render Account: Sign up at https://render.com
-
Click "New +" → "Web Service"
-
Connect your repository:
https://github.com/hackonteam/m-obs-backend -
Configure:
- Name:
m-obs-api - Region: Choose closest to your users
- Branch:
main - Root Directory:
api - Runtime:
Python 3 - Build Command:
pip install -e . - Start Command:
uvicorn src.main:app --host 0.0.0.0 --port $PORT - Instance Type: Start with
Starter($7/month)
- Name:
-
Add Environment Variables:
DATABASE_URL=postgresql://user:password@host:port/database MANTLE_RPC_ENDPOINTS=https://rpc.mantle.xyz,https://mantle.publicnode.com API_HOST=0.0.0.0 CORS_ORIGINS=https://your-frontend-domain.vercel.app SENTRY_DSN=your-sentry-dsn (optional) -
Click "Create Web Service"
-
Wait for deployment (2-3 minutes)
-
Note the API URL:
https://m-obs-api.onrender.com
-
Click "New +" → "Background Worker"
-
Connect same repository:
https://github.com/hackonteam/m-obs-backend -
Configure:
- Name:
m-obs-worker - Region: Same as API
- Branch:
main - Root Directory:
worker - Runtime:
Python 3 - Build Command:
pip install -e . - Start Command:
python -m src.main - Instance Type:
Starter($7/month) or higher for better performance
- Name:
-
Add Environment Variables:
DATABASE_URL=postgresql://user:password@host:port/database MANTLE_RPC_ENDPOINTS=https://rpc.mantle.xyz,https://mantle.publicnode.com WORKER_ENABLED_PIPELINES=provider_probe,block_scanner,metrics_rollup,alert_evaluator SENTRY_DSN=your-sentry-dsn (optional) -
Click "Create Background Worker"
-
Worker will start processing immediately
curl https://m-obs-api.onrender.com/health
# Expected: {"status": "ok", "timestamp": "..."}Visit: https://m-obs-api.onrender.com/docs
- Go to Render Dashboard
- Click on
m-obs-worker - View "Logs" tab
- Look for pipeline startup messages:
Starting provider_probe pipeline... Starting block_scanner pipeline... Starting metrics_rollup pipeline... Starting alert_evaluator pipeline...
Connect to your Supabase database and verify:
-- Check if worker is running
SELECT * FROM worker_state WHERE worker_name = 'block_scanner';
-- Check recent transactions
SELECT COUNT(*) FROM txs WHERE created_at > NOW() - INTERVAL '5 minutes';
-- Check provider health samples
SELECT * FROM rpc_health_samples ORDER BY sampled_at DESC LIMIT 10;Render automatically deploys when you push to the main branch.
- Go to service → "Environment" tab
- Update variables
- Service will automatically restart
- API Service: Can scale horizontally (multiple instances)
- Worker Service: Run single instance to avoid duplicate processing
- Consider upgrading instance types if experiencing performance issues
- Use Render's built-in Metrics and Logs
- Optional: Add Sentry for error tracking
- Monitor database performance in Supabase dashboard
Render automatically monitors API health via HTTP checks.
Configure in service settings:
- Health Check Path:
/health - Health Check Interval: 60 seconds
- API Service: $7/month (Starter) or $25/month (Standard)
- Worker Service: $7/month (Starter) or $25/month (Standard)
- Total: ~$14/month minimum
Render offers free tier with limitations:
- Services spin down after 15 minutes of inactivity
- 750 hours/month shared across services
- Not recommended for production
- Check build logs for dependency errors
- Verify
DATABASE_URLis correct - Ensure port binding uses
$PORTenvironment variable
- Check worker logs for connection errors
- Verify RPC endpoints are accessible
- Check
WORKER_ENABLED_PIPELINESconfiguration - Verify database migrations are applied
- Whitelist Render's IP ranges in Supabase (if restricted)
- Check connection string format
- Verify SSL mode if required
- Worker processes large batches - consider upgrading instance
- API should be lightweight - check for memory leaks
GET /health- Service health check
GET /metrics/overview- Dashboard metrics (time-series)
GET /providers/health- RPC provider health status
GET /txs- List transactions (filtered, paginated)GET /txs/{hash}- Transaction details
GET /contracts- List watched contractsPOST /contracts- Add contract to watchlist
GET /alerts- List alert rulesPOST /alerts- Create alert rulePATCH /alerts/{id}- Update alert ruleDELETE /alerts/{id}- Delete alert rule
- Monitors RPC endpoint health
- Calculates performance scores
- Detects trace API support
- Updates
rpc_health_samplestable
- Scans new blocks from Mantle
- Ingests transaction data
- Handles chain reorganizations
- Updates
txsandtx_tracestables
- Aggregates per-minute metrics
- Calculates failure rates, gas statistics
- Tracks top errors
- Updates
metrics_minutetable
- Evaluates alert rules
- Detects threshold violations
- Creates alert events with cooldown
- Updates
alert_eventstable
backend/
├── api/
│ ├── src/
│ │ ├── main.py # FastAPI app
│ │ ├── config.py # Configuration
│ │ ├── database.py # DB connection
│ │ ├── models/ # Pydantic schemas
│ │ └── routes/ # API endpoints
│ ├── pyproject.toml
│ └── README.md
└── worker/
├── src/
│ ├── main.py # Worker entry point
│ ├── config.py # Configuration
│ ├── database.py # DB connection
│ ├── pipelines/ # 4 background pipelines
│ ├── providers/ # RPC client & manager
│ ├── decoders/ # Error decoding
│ └── state/ # State management
├── pyproject.toml
└── README.md
# api/src/routes/your_route.py
from fastapi import APIRouter, Depends
from ..database import get_db
router = APIRouter()
@router.get("/your-endpoint")
async def your_endpoint(db = Depends(get_db)):
# Your logic here
return {"data": "response"}# worker/src/pipelines/your_pipeline.py
import asyncio
from ..database import get_db_pool
async def your_pipeline():
pool = await get_db_pool()
while True:
try:
# Your pipeline logic
await asyncio.sleep(30) # Interval
except Exception as e:
print(f"Error: {e}")
await asyncio.sleep(5)- Fork the repository
- Create feature branch:
git checkout -b feature/your-feature - Make changes and test locally
- Commit:
git commit -m "feat: your feature" - Push:
git push origin feature/your-feature - Create Pull Request
HackOn Team Vietnam
- Bernie Nguyen - Founder/Leader/Full-stack/Main developer
- Thien Vo - Front-end developer intern
- Canh Trinh - Researcher, Back-end developer intern
- Sharkyz Duong Pham - Business developer lead
- Hieu Tran - Business developer
Collaboration: Phu Nhuan Builder
Contact:
- Email: work.hackonteam@gmail.com
- Telegram: https://t.me/hackonteam
MIT License - see LICENSE file in main repository
- Main Repository: https://github.com/hackonteam/m-obs
- Backend Repository: https://github.com/hackonteam/m-obs-backend
- Frontend Repository: https://github.com/hackonteam/m-obs-frontend
- Supabase: Your Supabase project URL
- API Deployment: https://m-obs-api.onrender.com (your URL)