MartinOravecSvK/BlockBerg

★ 0Forks 0PythonGitHub ↗Compare

README

BlockBerg

A crypto Bloomberg terminal — real-time chain metrics dashboard, AI-powered VC sentiment tracking, and on-chain metric publishing with Flare verification.

30 supported chains across L1s, L2s, and EVM-compatible networks.

Supported Chains

Category Chains
L1 Majors Bitcoin (BTC), Ethereum (ETH), Solana (SOL), Cardano (ADA), Polkadot (DOT), Cosmos Hub (ATOM), NEAR (NEAR), Toncoin (TON), TRON (TRX), Aptos (APT), Hedera (HBAR), Internet Computer (ICP)
EVM L1s BNB Chain (BNB), Avalanche (AVAX), Fantom (FTM)
L2s & EVM-Adjacent Arbitrum One (ARB), Optimism (OP), Polygon PoS (POL), Sui (SUI), zkSync Era (ZK), Starknet (STRK), Mantle (MNT), Injective (INJ)
Classic L1s XRP Ledger (XRP), Dogecoin (DOGE), Litecoin (LTC), Filecoin (FIL)
Modular Celestia (TIA), Sei (SEI), Algorand (ALGO)

Quick Start

Prerequisites

  • Python 3.12+ with uv
  • Node.js 22+
  • (Optional) Docker & Docker Compose

1. Backend

cd backend
cp ../.env.example ../.env  # edit with your API keys

# Install dependencies and run
uv sync --extra dev
uv run python -m cli serve --reload

The API is live at http://localhost:8000. Docs at http://localhost:8000/docs.

2. Frontend

cd frontend
npm install
npm run dev

Open http://localhost:3000.

3. Docker Compose (both)

cp .env.example .env
docker compose up --build

Backend at :8000, frontend at :3000.

Run Tests

cd backend
uv run pytest

Linting

cd backend
uv run ruff check src/
uv run ruff format --check src/

Metrics Reference

Price Snapshot

Live price data from CoinGecko, refreshed every 60 seconds via batch API call.

Field Type Description
usd float Current price in USD
change_7d_pct float 7-day price change percentage
change_30d_pct float 30-day price change percentage
market_cap float Market capitalization in USD
total_volume float 24-hour trading volume in USD
ath float All-time high price in USD

If the live price is missing or zero (rate-limited), the system falls back to the most recent price from the 1-day history endpoint.

OHLC Candles

Server-side aggregated from price history ticks via _aggregate_ohlc(). Auto-selects candle interval based on the requested time range:

Time Range Candle Interval
1-2 days 1 hour
3-14 days 4 hours
15-90 days 1 day (24h)
91-180 days 3 days (72h)
181-365 days 1 week (168h)

Allowed explicit intervals: 1, 4, 24, 72, 168 (hours).

Price History

Raw price ticks from CoinGecko with granularity determined by the time range:

Range Granularity
1 day 5-minute intervals
2-90 days Hourly intervals
91-365 days Daily intervals

Includes singleflight deduplication — chains sharing the same CoinGecko ID (e.g., Base and Ethereum both use "ethereum") trigger only one API call. Larger cached tiers (90d, 365d) are sliced to serve shorter ranges without extra API calls.

Reputation Score (0-100)

Composite score computed from four equally-weighted factors (25 points each). Missing data scores 12.5 (neutral midpoint). Includes a confidence field (0.0-1.0) reflecting the fraction of factors with real data.

Factor Source Scoring Range
Price Stability CoinGecko 30d change 0% change = 25pts, >=50% change = 0pts 0-25
Dev Activity GitHub commits (30d) 0 commits = 0pts, >=100 commits = 25pts 0-25
Holder Decentralization Etherscan / BlockVision top-10 holder % 0% concentration = 25pts, 100% = 0pts 0-25
Funding Neutrality Binance perpetual funding rate 0 rate = 25pts, >=0.005 = 0pts 0-25

Labels: excellent (>=85), good (>=70), neutral (>=50), caution (>=30), poor (<30)

Contributing factors are returned as human-readable strings (e.g., "strong dev activity (+)", "high concentration (-)") when a factor scores above or below key thresholds.

Developer Activity

Pulled from the GitHub commits API for each chain's tracked repositories (30-day window by default).

Field Description
commits Total commit count across all tracked repos
active_devs Number of unique commit authors
repos List of owner/repo strings tracked
days Time window in days
data_source "github" when successful

Market Sentiment

Derivatives market data from Binance Futures perpetual contracts.

Field Description
funding_rate Current perpetual funding rate (positive = longs pay shorts)
funding_rate_7d_avg 7-day average funding rate
signal "bullish" / "bearish" / "neutral" based on rate direction
funding_source "binance" when available

Holder Concentration

Token holder distribution from on-chain data. Uses a representative token per chain (typically USDC for EVM chains, native token for non-EVM).

Field Description
top10_pct Percentage of token supply held by top 10 addresses
gini Gini coefficient (0 = perfectly equal, 1 = maximally concentrated)
asset_kind "erc20" or "sui_coin"
asset_symbol Token symbol (e.g., "USDC", "SUI")
asset_identifier Contract address (EVM) or coin type (Sui)
data_source "etherscan" / "blockvision" / "unavailable"

Flow Index (0-100)

AI-computed sentiment index from classified intel items. Uses sigmoid normalization on raw weighted scores.

Value Interpretation
50 Neutral — no signal
> 60 Bullish — positive VC/funding momentum
< 40 Bearish — negative signals
> 80 Strongly bullish
< 20 Strongly bearish

Computation: For each classified intel item, per-chain impact is scored as magnitude * confidence * direction_sign. Raw scores are aggregated and normalized via sigmoid: 100 / (1 + exp(-raw / 200)).

Windows: 1d (24h), 7d (7 days), 30d (30 days).


Data Providers

Provider Data Auth Rate Limit
CoinGecko (free tier) Prices, market cap, volume, ATH, price history, OHLC source data None ~10-30 req/min, 429 on exceeded
GitHub Commits, active developers per repo Optional PAT 60/hr unauthenticated, 5000/hr with token
Binance Futures Perpetual funding rate (current + 7d avg) None 500 req/5min
Etherscan (v2) EVM token holder concentration (top-10 %) API key (PRO for holder list) Standard Etherscan limits
BlockVision Sui coin holder concentration API key (x-api-key header) 300 CU/s free tier
EVM RPC Block number for EVM chains RPC URL Provider-dependent
Sui RPC Block number for Sui RPC URL Provider-dependent
OpenAI Intel item classification (gpt-4o-mini) API key Standard OpenAI limits
Flare FTSO (skeleton) Decentralized price feeds (behind feature flag) None N/A — CoinGecko is primary

API Reference

Base URL: http://localhost:8000

System

Method Path Description
GET /health Health check — returns {status, version}
GET /metrics Prometheus metrics (request count, latency, cache stats)
GET /docs OpenAPI Swagger UI (dev mode only)

Chain Metrics

Method Path Params Description
GET /chains — List all 30 supported chains (id, name, symbol, is_evm)
GET /chains/all — Full metrics for all chains in one request (30s timeout)
GET /chains/{chain_id} — Full metrics for one chain: price, sentiment, holders, dev, reputation, block_number
GET /chains/{chain_id}/history days (1-365, default 30) Price history as [{timestamp, price}] time series
GET /chains/{chain_id}/ohlc days (1-365), interval (1/4/24/72/168h) OHLC candlestick data, auto-interval if omitted
GET /chains/{chain_id}/dev-activity days (1-365, default 30) Developer activity: commits, active devs, repos
POST /query {"query": "...", "chain_id": "..."} Keyword search across chains, returns matching metrics
POST /admin/refresh Header: X-Admin-Token Force-refresh all chain metrics (invalidates price cache)

Intel

Method Path Params Description
GET /api/intel/sources — List all configured intel sources with item counts
GET /api/intel/items source, chain, since, limit (default 50) List intel items, filterable by source/chain/date
GET /api/intel/items/{url_hash} — Full item detail with raw text and parsed classification
GET /api/intel/vc/{slug} — VC source detail: metadata + items + impacted chains summary
GET /api/intel/chains/{chain}/impact window (1d/7d/30d, default 7d) Chain flow index with top contributing items
GET /api/intel/flow — Flow index table for all chains (1d/7d/30d columns)
POST /api/intel/refresh reclassify (bool) Trigger fetch/classify cycle. ?reclassify=true reprocesses all

Onchain Publishing

Method Path Params Description
POST /api/onchain/publish {chain, metric_type, value, target} Publish a metric on-chain. value=0 auto-resolves from current data
GET /api/onchain/status chain, metric_type, limit (default 50) List publish records with Flare enabled flag
GET /api/onchain/latest/{chain} — Latest publish records for a specific chain
POST /api/onchain/attest/{item_url_hash} — Request FDC attestation for an intel item
GET /api/onchain/attest/{item_url_hash} — Get attestation status for an intel item

Valid metric types: flow_1d, flow_7d, flow_30d, risk

Valid targets: evm, flare, auto (prefers Flare if enabled, falls back to EVM, then simulated)

Publish modes: real (EVM), flare_direct (Flare), flare_attested (Flare + FDC proof), simulated (SQLite-only)

Example curl Commands

# Health check
curl http://localhost:8000/health

# List all chains
curl http://localhost:8000/chains

# Get Ethereum metrics (price, sentiment, holders, dev, reputation)
curl http://localhost:8000/chains/ethereum

# Get 90-day OHLC candles with 1-day interval
curl "http://localhost:8000/chains/bitcoin/ohlc?days=90&interval=24"

# Get 7-day price history for Solana
curl "http://localhost:8000/chains/solana/history?days=7"

# Get 60-day dev activity for Sui
curl "http://localhost:8000/chains/sui/dev-activity?days=60"

# Keyword query
curl -X POST http://localhost:8000/query \
  -H 'Content-Type: application/json' \
  -d '{"query": "polygon"}'

# Flow index table (all chains)
curl http://localhost:8000/api/intel/flow

# Publish Ethereum 7-day flow index on-chain
curl -X POST http://localhost:8000/api/onchain/publish \
  -H 'Content-Type: application/json' \
  -d '{"chain": "ethereum", "metric_type": "flow_7d", "value": 0, "target": "auto"}'

# Force refresh (admin)
curl -X POST http://localhost:8000/admin/refresh \
  -H 'X-Admin-Token: your-token-here'

Terminal Commands

BlockBerg features a Bloomberg-style command bar (/ or Ctrl+K to focus). All commands are case-insensitive.

Navigation

Command Action
CHAINS Go to chain overview (home page)
SCREENER Screener + strategy page
COMPARE Jump to multi-chain comparison charts
WATCHLIST View watched chains
HELP or ? Show command reference
LAST Show command history
GRAB Screenshot current screen to PNG

Chain Navigation

Command Action
BTC / ETH / SOL / ... Go to chain detail dashboard
<SYM> GP Price graph (area chart)
<SYM> HVG Historical volatility graph
<SYM> DEV Developer activity chart
<SYM> SENT Sentiment / funding rate chart
<SYM> VOL Scroll to volume section
<SYM> HOLD Scroll to holders section

Symbols: BTC, ETH, SOL, ARB, OP, POL/MATIC, SUI, AVAX, BNB, ADA, DOT, ATOM, NEAR, TON, TRX, APT, FTM, ALGO, TIA, SEI, HBAR, ICP, STRK, ZK, MNT, INJ, XRP, DOGE, LTC, FIL

Data Commands

Command Action
WATCH <SYM> Toggle chain in watchlist
REFRESH ALL Force-refresh all chain data
REFRESH <SYM> Force-refresh one chain

Intel Commands

Command Action
VC List all VC intel sources
VC <slug> View VC source detail + classified items
FLOW Chain flow index table (1d/7d/30d)

Onchain Commands

Command Action
PUBLISH <SYM> FLOW 7D Publish 7-day flow index on-chain
PUBLISH <SYM> FLOW 1D Publish 1-day flow index on-chain
PUBLISH <SYM> FLOW 30D Publish 30-day flow index on-chain
PUBLISH <SYM> RISK Publish reputation/risk score on-chain

Keyboard Shortcuts

Key Action
/ or Ctrl+K Focus command bar
? Open help modal
Esc Clear input / close modals
Tab Autocomplete command
Up / Down Command history
Enter Execute command
D Toggle compact density mode

Intel Module

AI-powered VC and crypto funding sentiment tracker.

Pipeline

  1. Sources: Configured in backend/config/intel_sources.yaml — RSS feeds and HTML scraping from major crypto VCs and news outlets
  2. Fetch: Background scheduler fetches all sources every 30 minutes (configurable via INTEL_FETCH_INTERVAL_SECONDS)
  3. Classify: Each item is sent to OpenAI (gpt-4o-mini by default) for structured JSON classification:
    • Item type: funding_round, portfolio_update, grant, partnership, blog_post, other
    • Entity extraction: companies (name, website, confidence) and people (name, role, confidence)
    • Funding info: round type, amount in USD, investors list
    • Per-chain impact: chain name, direction (positive/negative/neutral), magnitude (0-100), confidence (0-1), rationale
  4. Flow Index: Computed per chain per window (1d/7d/30d) from classified items using sigmoid normalization

Preconfigured Sources

Source Type Tags
a16z Crypto RSS (Substack) vc, crypto, web3
Multicoin Capital RSS vc, crypto, web3
Variant Fund RSS vc, crypto, web3
Hack VC RSS vc, crypto, ai
Dragonfly Capital RSS (Medium) vc, crypto, defi
Pantera Capital RSS (Medium) vc, crypto, blockchain
Paradigm HTML scrape vc, crypto, defi
CoinDesk RSS news, crypto
The Block RSS news, crypto
Blockworks RSS news, crypto

Adding Sources

Edit backend/config/intel_sources.yaml:

sources:
  - slug: my-vc
    name: My VC Firm
    kind: rss          # or "html"
    url: https://myvc.com/feed/
    tags: [crypto]

Onchain Publisher

Publish computed metrics (flow index, reputation score) to EVM-compatible blockchains with a two-tier fallback:

  • Tier A (Real): Send transactions via JSON-RPC to any EVM chain or Flare network
  • Tier B (Simulated): Store publish records in SQLite with deterministic fake tx hashes (0xSIM... for EVM, 0xFLR... for Flare)

No web3.py dependency — uses raw httpx JSON-RPC calls for minimal footprint.

Publish Targets

Target Behavior
auto Prefers Flare (if enabled + configured), falls back to EVM, then simulated
evm Generic EVM publish via ONCHAIN_RPC_URL + ONCHAIN_PRIVATE_KEY
flare Flare-specific publish via FLARE_RPC_URL + FLARE_PRIVATE_KEY

Smart Contract

Reference Solidity contract at backend/contracts/MetricStore.sol:

  • publishMetric(string chain, string metricType, uint256 value) — standard metric publish, emits MetricPublished event
  • setMetricWithAttestation(string chain, string metricType, uint256 value, bytes32 attestationProof) — FDC-verified publish, emits MetricPublishedWithAttestation event
  • getLatest(string chain, string metricType) — view function returning latest value, timestamp, and publisher address
  • Metric values are scaled by 1e4 (4 decimal places). A flow index of 65.5 is stored as 655000.

Flare BONUS Track

BlockBerg integrates with the Flare blockchain for verifiable metric publishing and external data attestation.

Integration Points

  1. Flare Publisher (backend/src/blockberg/onchain/flare_publisher.py): Dedicated publisher targeting Flare/Coston2 RPC. Supports direct metric publishing (mode=flare_direct) and FDC-attested updates (mode=flare_attested) via setMetricWithAttestation().

  2. FDC Attestation (backend/src/blockberg/onchain/fdc.py): Flare Data Connector integration for verifying intel items. Builds AddressValidity attestation payloads, computes deterministic SHA-256 payload hashes, and tracks verification status: requested -> verified -> on-chain.

  3. FTSO Price Provider (backend/src/blockberg/providers/flare_ftso.py): Skeleton provider for reading prices from Flare Time Series Oracle. Maps 16 CoinGecko IDs to FTSO symbols. Behind FLARE_ENABLED feature flag — CoinGecko remains the default price source.

  4. Smart Contract (backend/contracts/MetricStore.sol): Reference Solidity contract with publishMetric() for standard updates and setMetricWithAttestation(bytes32 attestationProof) for FDC-verified updates.

  5. Frontend: Flare mode badges (FLARE DIRECT / FLARE ATTESTED / SIMULATED) on publish records, and VERIFY buttons on intel items for requesting FDC attestation.

Flare Configuration

FLARE_ENABLED=true
FLARE_RPC_URL=https://coston2-api.flare.network/ext/C/rpc
FLARE_PRIVATE_KEY=0x...  # NEVER commit
FLARE_CONTRACT_ADDRESS=0x...
FLARE_NETWORK_NAME=flare-coston2

How It Works

Intel Item -> AI Classification -> Flow Index Computation
                                        |
                          PUBLISH ETH FLOW 7D (command)
                                        |
                          target=auto -> FlarePublisher
                                        |
                          publishMetric() on Flare Coston2
                                        |
                          MetricPublished event emitted
                                        |
                          Record stored in SQLite + shown in UI

Intel Item -> VERIFY button -> FDC Attestation Request
                                        |
                          Build payload -> hash -> store
                                        |
                          FDC verifier (when available)
                                        |
                          Merkle proof -> setMetricWithAttestation()

Frontend Pages

Route Page Description
/ Home Chain overview grid — prices, sparklines, reputation badges for all 30 chains
/chains/{chainId} Chain Detail Full dashboard: price chart, OHLC candles, volume, sentiment, holders, dev activity, reputation, on-chain publishes
/screener Screener Multi-chain comparison charts and strategy tools
/intel/vc VC List All configured VC intel sources with item counts
/intel/vc/{slug} VC Detail Source metadata, classified items, per-chain impact breakdown
/intel/flow Flow Table Flow index for all chains across 1d/7d/30d windows
/intel/news News Feed AI-classified intel items from all sources, with FDC VERIFY buttons
/intel/news/{hash} News Detail Full item detail with raw classification, entity extraction, funding info

Environment Variables

Backend Core

Variable Required Default Description
BLOCKBERG_ENV No development Environment: development or production
BLOCKBERG_LOG_LEVEL No INFO Log level (DEBUG, INFO, WARNING, ERROR)
BLOCKBERG_HOST No 0.0.0.0 Server bind host
BLOCKBERG_PORT No 8000 Server bind port
BLOCKBERG_ADMIN_TOKEN No — Admin auth token for /admin/refresh. Empty = open in dev
BLOCKBERG_CORS_ORIGINS No — Comma-separated allowed CORS origins for production

Rate Limiting & Cache

Variable Required Default Description
BLOCKBERG_RATE_LIMIT_RPS No 20 Token-bucket refill rate (requests/second)
BLOCKBERG_RATE_LIMIT_BURST No 40 Maximum burst size per IP
BLOCKBERG_CACHE_TTL_SECONDS No 60 Default in-memory cache TTL
BLOCKBERG_REDIS_URL No — Redis URL (empty = in-memory only)

RPC Endpoints

Variable Required Default Description
BLOCKBERG_ETH_RPC_URL No — Ethereum JSON-RPC (e.g., Alchemy)
BLOCKBERG_ARBITRUM_RPC_URL No — Arbitrum One JSON-RPC
BLOCKBERG_OPTIMISM_RPC_URL No — Optimism JSON-RPC
BLOCKBERG_BASE_RPC_URL No — Base JSON-RPC
BLOCKBERG_POLYGON_RPC_URL No — Polygon PoS JSON-RPC
BLOCKBERG_SUI_RPC_URL No https://fullnode.mainnet.sui.io:443 Sui full node RPC

External API Keys

Variable Required Default Description
BLOCKBERG_GITHUB_TOKEN No — GitHub PAT for 5000/hr rate limit (vs 60/hr)
BLOCKBERG_ETHERSCAN_API_KEY No — Etherscan API key for EVM holder data (PRO for holder list)
BLOCKBERG_BLOCKVISION_API_KEY No — BlockVision API key for Sui holder data
BLOCKBERG_BINANCE_FUTURES_BASE_URL No https://fapi.binance.com Binance Futures base URL

Intel Module

Variable Required Default Description
CHATGPT_KEY For intel — OpenAI API key for LLM classification
GITHUB_KEY No — GitHub PAT for dev activity (intel-specific)
INTEL_DB_PATH No ./data/intel.sqlite SQLite database path for intel data
INTEL_FETCH_INTERVAL_SECONDS No 1800 Background fetch cycle interval (seconds)
INTEL_USER_AGENT No BlockBergIntel/0.1 User-Agent for source fetching
INTEL_MAX_ITEMS_PER_SOURCE No 20 Max items to ingest per source per cycle
OPENAI_MODEL No gpt-4o-mini OpenAI model for classification
INTEL_ALLOWED_DOMAINS No — Comma-separated allowlist of fetch domains

Onchain Publishing

Variable Required Default Description
ONCHAIN_ENABLED No true Enable onchain publishing (uses simulated if no RPC)
ONCHAIN_NETWORK No sepolia Target network name (informational)
ONCHAIN_RPC_URL No — EVM RPC URL for real publishing (empty = simulated)
ONCHAIN_PRIVATE_KEY No — Private key for signing transactions (never commit)
ONCHAIN_CONTRACT_ADDRESS No — Deployed MetricStore contract address
ONCHAIN_DB_PATH No ./data/onchain.sqlite SQLite database for publish records

Flare BONUS Track

Variable Required Default Description
FLARE_ENABLED No false Enable Flare as a publish target
FLARE_RPC_URL No — Flare / Coston2 testnet RPC URL
FLARE_PRIVATE_KEY No — Private key for Flare transactions (never commit)
FLARE_CONTRACT_ADDRESS No — MetricStore contract address on Flare
FLARE_NETWORK_NAME No flare-coston2 Network name: flare or flare-coston2

Frontend

Variable Required Default Description
NEXT_PUBLIC_API_URL No http://localhost:8000 Backend API URL

Project Structure

BlockBerg/
├── backend/
│   ├── src/
│   │   ├── cli.py                      # CLI entry point (serve, etc.)
│   │   ├── blockberg/
│   │   │   ├── api/
│   │   │   │   ├── app.py              # FastAPI factory + lifespan
│   │   │   │   ├── routes.py           # Core chain/query/admin endpoints
│   │   │   │   ├── middleware.py        # Rate limiting, CORS, Prometheus instrumentation
│   │   │   │   └── deps.py             # FastAPI dependency injection
│   │   │   ├── core/
│   │   │   │   ├── config.py           # Pydantic Settings (env vars)
│   │   │   │   ├── cache.py            # In-memory TTL cache
│   │   │   │   ├── chains.py           # 30 chain definitions (ChainId, ChainInfo)
│   │   │   │   ├── rate_limiter.py     # Token-bucket per-IP rate limiter
│   │   │   │   ├── logging.py          # structlog JSON logging setup
│   │   │   │   └── metrics.py          # Prometheus counters and gauges
│   │   │   ├── models/
│   │   │   │   └── chains.py           # Pydantic v2 response schemas
│   │   │   ├── providers/
│   │   │   │   ├── base.py             # Abstract provider interfaces
│   │   │   │   ├── coingecko.py        # CoinGecko price/history provider
│   │   │   │   ├── github.py           # GitHub dev activity provider
│   │   │   │   ├── binance.py          # Binance funding rate provider
│   │   │   │   ├── etherscan.py        # EVM holder concentration provider
│   │   │   │   ├── blockvision.py      # Sui holder concentration provider
│   │   │   │   ├── evm_rpc.py          # EVM JSON-RPC (block number)
│   │   │   │   ├── sui_rpc.py          # Sui JSON-RPC (block number)
│   │   │   │   └── flare_ftso.py       # Flare FTSO price provider (skeleton)
│   │   │   ├── services/
│   │   │   │   ├── metrics_service.py  # Orchestrates providers + caching
│   │   │   │   ├── reputation.py       # Reputation score computation
│   │   │   │   └── scheduler.py        # Background refresh tasks
│   │   │   ├── intel/
│   │   │   │   ├── config.py           # Intel env var configuration
│   │   │   │   ├── db.py              # SQLite async database (aiosqlite)
│   │   │   │   ├── fetcher.py         # RSS/HTML source fetcher
│   │   │   │   ├── flow.py            # Flow index computation
│   │   │   │   ├── llm.py            # OpenAI classification provider
│   │   │   │   ├── models.py         # Pydantic v2 intel schemas
│   │   │   │   ├── routes.py         # Intel API endpoints
│   │   │   │   └── service.py        # Intel service orchestrator
│   │   │   └── onchain/
│   │   │       ├── config.py          # Onchain + Flare env var config
│   │   │       ├── db.py             # SQLite for publishes + attestations
│   │   │       ├── models.py         # Pydantic v2 onchain schemas
│   │   │       ├── publisher.py      # Publisher factory (create_publisher)
│   │   │       ├── evm_publisher.py  # EVM JSON-RPC publisher
│   │   │       ├── sim_publisher.py  # Simulated publisher (SQLite only)
│   │   │       ├── flare_publisher.py # Flare-specific publisher
│   │   │       ├── fdc.py            # FDC attestation builder
│   │   │       ├── service.py        # Onchain service orchestrator
│   │   │       └── routes.py         # Onchain API endpoints
│   │   └── blockberg_tests/           # pytest tests (87 tests)
│   ├── config/
│   │   └── intel_sources.yaml         # VC/news source definitions
│   ├── contracts/
│   │   └── MetricStore.sol            # Reference Solidity contract
│   ├── deployments/
│   ├── Dockerfile
│   └── pyproject.toml
├── frontend/
│   ├── src/
│   │   ├── app/                       # Next.js 15 App Router
│   │   │   ├── page.tsx               # Home — chain overview grid
│   │   │   ├── chains/[chainId]/      # Chain detail dashboard
│   │   │   ├── screener/              # Screener + comparison charts
│   │   │   └── intel/                 # VC list, detail, flow, news
│   │   ├── components/                # React components (command bar, help modal, charts)
│   │   └── lib/
│   │       ├── api.ts                 # Typed API client
│   │       ├── hooks.ts               # TanStack Query hooks
│   │       └── commands.ts            # Command parser + autocomplete
│   ├── deployments/
│   ├── Dockerfile
│   └── package.json
├── libs/                              # Shared libraries (scaffolding)
├── docker-compose.yml
└── .env.example

Architecture

Performance

  • FastAPI + uvicorn + uvloop for async request handling
  • ORJSONResponse for fast JSON serialization
  • In-memory TTL cache with per-key expiration and periodic eviction (every 5 min)
  • Batch price fetching: single CoinGecko API call pre-warms prices for all 30 chains
  • Singleflight deduplication: concurrent requests for the same price history share one in-flight API call
  • Cache tier slicing: larger cached ranges (90d, 365d) are sliced to serve shorter ranges without extra calls
  • Per-provider timeout: 15s timeout per provider prevents one slow source from blocking all metrics
  • Route-level timeout: 30s timeout on all API endpoints, returns 504 on timeout

Rate Limiting

Token-bucket algorithm per client IP (in-memory). Default: 20 tokens/sec, burst of 40. Auto-cleanup at >10,000 entries to prevent memory leaks. Extensible to Redis via Lua script for multi-process deployments.

Background Scheduler

Pure asyncio task scheduler — no Celery dependency:

Task Interval Description
Metrics refresh cache_ttl_seconds (min 30s) Pre-warms cache for all chains on startup, then periodic refresh
Cache eviction 5 minutes Evicts expired entries to bound memory
Intel fetch INTEL_FETCH_INTERVAL_SECONDS (default 1800) Fetches sources, classifies items, computes flow indices

Persistence

  • Intel data: SQLite via aiosqlite (intel_sources, intel_items, intel_classifications, chain_flow_snapshots)
  • Publish records: SQLite via aiosqlite (onchain_publishes, attestation_requests)
  • No Redis required — in-memory cache handles all caching needs for single-process deployment

Observability

  • structlog JSON logging with configurable log level
  • Prometheus metrics: blockberg_request_count, blockberg_request_latency, blockberg_cache_hits, blockberg_cache_misses, blockberg_app_info
  • Path normalization prevents unbounded Prometheus label cardinality

Type Safety

  • Backend: Pydantic v2 validation on all models, mypy strict mode
  • Frontend: TypeScript strict, typed API client, TanStack Query with generic types

Provider Abstraction

Abstract base classes (PriceProvider, DevActivityProvider, SentimentProvider, HolderProvider, RPCProvider) enable swapping data sources without changing business logic. CoinGecko can be replaced by Flare FTSO via feature flag.

Contributors

MartinOravecSvK

Issues