Cardano chain data REST API (FastAPI) for db-sync
- Fix #17: Body size middleware reads actual body stream (catches chunked/missing Content-Length) - Fix #17: Challenge flood prevention - per-address rate limit (5/min) + outstanding limit (10 max) - Fix #18: COSE algorithm validation (must be EdDSA/-8) - Fix #18: COSE element type validation (protected, sig must be bytes; key must be 32 bytes) - Fix #19: TRP refresh uses Redis Set + batched Postgres query (eliminates N+1) - Fix #20: Pagination page parameter capped at 10000 across all endpoints Bumped version to 2.3.0 |
||
|---|---|---|
| .gitignore | ||
| Dockerfile | ||
| main.py | ||
| README.md | ||
| requirements.txt | ||
Cardano Chain Data API
REST API for querying Cardano blockchain data via db-sync PostgreSQL database.
Stack
- FastAPI — async Python API framework
- asyncpg — async PostgreSQL driver
- Redis — rate limiting + response caching
Deployment
cd /opt/cardano/dbsync
sudo docker compose up -d --build
API runs on 127.0.0.1:8765 (localhost only, VPN access via future rebind to 192.168.254.105:8765).
Authentication
Rate Limits
- Anonymous (no key): 20 req/min per IP
- Standard API key: 100 req/min
- Elevated API key: 1000 req/min
- Master key: unlimited
Using API Keys
# Header (preferred)
curl -H "X-API-Key: capi_xxx" http://127.0.0.1:8765/v1/block/latest
# Query param
curl http://127.0.0.1:8765/v1/block/latest?api_key=capi_xxx
Endpoints
Sync Status
GET /v1/sync/status
Blocks
GET /v1/block/latest
GET /v1/block/{block_no}
Addresses
GET /v1/address/{address}/balance
GET /v1/address/{address}/tokens
GET /v1/address/{address}/transactions?page=1&limit=20&order=desc
Transactions
GET /v1/tx/{tx_hash}
Assets
GET /v1/asset/{policy_id}/info
GET /v1/asset/{policy_id}/{asset_name}/holders?limit=20
Pools
GET /v1/pool/{pool_id}/info
Admin (master key required)
POST /admin/keys — create API key
DELETE /admin/keys/{key} — revoke key
GET /admin/keys — list all keys
GET /admin/stats — usage stats
Known Policy IDs
- TRP:
9c4bd4a90cdb73d9ff681215ecf7dea9fb183d916d30487d17098e05 - MAP:
24bd9e7b9ae3a61df79eca72fd8355d0f7767e4c55a04a0d919c019c
Future: TRP Token Gating
Design for decentralized, permissionless API access based on TRP token holdings:
Tier Mapping
- 0 TRP → anonymous rate limits (20 req/min)
- 50+ TRP → standard tier (100 req/min)
- 500+ TRP → elevated tier (1000 req/min)
Implementation Plan
POST /admin/keys/verify-trpendpoint- Takes Cardano address, queries
/v1/address/{addr}/tokens - Checks TRP policy balance
- Auto-creates or upgrades API key based on holdings
- Stores
owner(address) andtrp_balancein key hash
Data Model (already in place)
API keys stored in Redis as:
apikey:<key> → {
tier: "standard"|"elevated",
label: "...",
owner: "addr1...", # Cardano address
trp_balance: 500, # Last verified TRP balance
created_at: "..."
}
Benefits
- Permissionless: Anyone can verify holdings and get access
- Decentralized: No manual approval needed
- Incentivized: Holding TRP = better API access
- Revocable: Re-verify periodically to maintain tier
Caching
Response TTLs:
- Balance/tokens: 60s
- Transactions: 30s
- Latest block: 10s
- TX details: 300s (immutable)
- Asset info: 120s
- Pool info: 120s
- Sync status: 5s
Environment Variables
DB_HOST=postgres-dbsync
DB_PORT=5432
DB_NAME=cexplorer
DB_USER=dbsync
DB_PASS=...
REDIS_HOST=redis-api
REDIS_PORT=6379
API_MASTER_KEY=capi_...