Cardano chain data REST API (FastAPI) for db-sync
Find a file
Kayos dac26ea1ba Security hardening: fix 10 vulnerabilities
CRITICAL:
- Fix #1: Atomic nonce GETDEL to prevent race conditions in verify_auth()

HIGH:
- Fix #2: X-Forwarded-For only trusted from TRUSTED_PROXIES set
- Fix #3: TRP tier refresh every 10min (was 60min) + 48h key expiry
- Fix #4: SHA-256 hashed key storage in Redis (raw key never stored)

MEDIUM:
- Fix #5: Generic error messages - no internal detail leakage
- Fix #6: Auth refresh is self-service only (documented)
- Fix #7: CBOR validation before tx submit
- Fix #8: Input validation regex for addresses, tx hashes, policy IDs

LOW:
- Fix #9: Correct tx hash calculation (blake2b of tx body, not full tx)
- Fix #10: Enforce key expiry globally in get_api_key_info

Version bumped to 2.1.0
2026-03-21 09:47:58 -07:00
.gitignore Initial commit: Cardano chain data REST API 2026-03-18 11:43:46 -07:00
Dockerfile fix: Enforce strict tier-based access control for node endpoints 2026-03-21 09:15:40 -07:00
main.py Security hardening: fix 10 vulnerabilities 2026-03-21 09:47:58 -07:00
README.md Initial commit: Cardano chain data REST API 2026-03-18 11:43:46 -07:00
requirements.txt feat: Add node integration, TRP-gated auth, CIP-8 verification 2026-03-21 08:52:46 -07:00

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

  1. POST /admin/keys/verify-trp endpoint
  2. Takes Cardano address, queries /v1/address/{addr}/tokens
  3. Checks TRP policy balance
  4. Auto-creates or upgrades API key based on holdings
  5. Stores owner (address) and trp_balance in 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_...