A lightweight crypto data API written in Go, focused on simplicity, performance, and clarity.
The API is read-only and does not require authentication.
This project aggregates crypto-related data (prices, chains, protocols) from external sources and exposes a clean, versioned HTTP API with in-memory caching and test coverage.
Built as part of Skeletor Labs to demonstrate backend engineering, API design, and Web3 infrastructure skills.
- 🚀 Fast HTTP API: Built with Go's standard library for maximum performance.
- 🧠 Generic Cache: Type-safe in-memory caching using Go Generics (Get[T]/Set[T]).
- 📈 Intelligence Engine: Derived metrics including BTC/M2 Valuation and Statistical Correlation.
- 🧪 Test Driven: High coverage for handlers, engines, and data sources.
- 🔢 API Versioning: Clean routing under /v1.
- 🧼 Standardized Responses: Consistent metadata envelope (meta.updatedAt, meta.cached).
- 🛡️ Multi-Provider Resilience: Price aggregation with automated fallback (Binance → Coinbase → Kraken → CoinGecko).
- 🔌 Unified Data Engine: Standardized HTTP fetching with generic JSON decoding and automated retries.
All endpoints are versioned under /v1.
Response Metadata
Most endpoints return a standard response envelope containing metadata.
{
"meta": {
"updatedAt": "2026-01-31T21:14:00Z",
"cached": false
},
"data": { ... }
}Health Check
GET /v1/health
Intentionally excluded from the standard response format.
Example:
curl http://localhost:8080/v1/health
Response:
{
"status": "ok"
}Status code:
200 OK
Token Price
GET /v1/price/<token>
tokenis case-insensitive, token identifier (e.g., bitcoin) or common ticker symbols (e.g., btc).- Resilient Sourcing: The API implements a prioritized fallback strategy: Binance → Coinbase → Kraken → CoinGecko.
- Internally normalized to lowercase.
- Returned token-name is always lowercase.
Example:
curl http://localhost:8080/v1/price/bitcoin
Response:
{
"meta": {
"updatedAt": "2026-01-31T21:14:00Z",
"cached": false
},
"token": "bitcoin",
"usd": 87723
}Chains
GET /v1/chains
Returns a list of supported chains with basic metrics.
Example:
curl http://localhost:8080/v1/chains
Response:
{
"meta": {
"updatedAt": "2026-01-31T21:14:00Z",
"cached": false
},
"data": [
{
"name": "Ethereum",
"tvl": 123456789,
"symbol": "ETH"
}
]
}Protocols
GET /v1/protocols
Optional query parameters:
chaincategory
Example:
curl "http://localhost:8080/v1/protocols?chain=Ethereum"
Response:
{
"meta": {
"updatedAt": "2026-01-31T21:14:00Z",
"cached": false
},
"data": [
{
"name": "Lido",
"slug": "lido",
"tvl": 123456,
"chain": "Ethereum",
"category": "Liquid Staking"
}
]
}Bitcoin Fees
GET /v1/bitcoin/fees
Returns recommended Bitcoin transaction fees based on current mempool conditions.
Example:
curl http://localhost:8080/v1/bitcoin/fees
Response:
{
"meta": {
"updatedAt": "2026-01-31T21:14:00Z",
"cached": false
},
"fastestFee": 42,
"halfHourFee": 28,
"hourFee": 18
}Bitcoin Network
GET /v1/bitcoin/network
Returns live network metrics, including Trend analysis and Halving projections.
Example:
curl http://localhost:8080/v1/bitcoin/network
Response:
{
"meta": {
"updatedAt": "2026-02-04T23:40:21Z",
"cached": false
},
"blockHeight": 935051,
"hashrateTHs": 920496599.65,
"difficulty": 141668107417558.2,
"avgBlockTimeSeconds": 719.77,
"trend": "Stable",
"halving": {
"currentBlock": 935051,
"nextHalvingBlock": 1050000,
"blocksRemaining": 114949,
"progressPercent": 45.26,
"estimatedDate": "2028-09-19T14:22:21Z"
}
}trend indicates short-term network behavior:
ImprovingStableWorsening
Bitcoin Mempool
GET /v1/bitcoin/mempool
Returns current Bitcoin mempool congestion metrics.
Example:
curl http://localhost:8080/v1/bitcoin/mempool
Response:
{
"meta": {
"updatedAt": "2026-01-31T21:14:00Z",
"cached": false
},
"count": 31468,
"vsize": 15577951,
"totalFee": 2587922
}Bitcoin Valuation
GET /v1/bitcoin/valuation
Analyzes Bitcoin price relative to global M2 money supply.
Example:
curl http://localhost:8080/v1/bitcoin/valuation
Response:
{
"meta": {
"updatedAt": "2026-02-08T10:30:00Z",
"cached": false
},
"btcPrice": 69133,
"m2SupplyBillions": 21050.5,
"ratio": 3.28,
"description": "Bitcoin is trading at 3.28x relative to M2 liquidity..."
}Bitcoin Correlation
GET /v1/bitcoin/correlation
Calculates the Pearson correlation coefficient between BTC and M2 liquidity over a historical window.
Example:
curl http://localhost:8080/v1/bitcoin/correlation
Response:
{
"meta": {
"updatedAt": "2026-02-08T10:30:00Z",
"cached": true
},
"coefficient": 0.87,
"sampleCount": 730,
"startDate": "2024-02-08T00:00:00Z",
"endDate": "2026-02-08T00:00:00Z"
}Notes:
- Data sourced from:
- mempool.space (Network)
- Binance, Coinbase, Kraken [High-priority] and CoinGecko [Fallback] (Prices)
- FRED - Federal Reserve Economic Data (Macro/M2)
- Results are managed via Type-safe Generic In-memory caching.
- Network metrics are aggregated from multiple endpoints:
- Block height
- Rolling hashrate (TH/s)
- Current difficulty
- Average block time
- Intelligence Layer provides advanced analytics (Valuation & Correlation).
├── internal
│ ├── cache # In-memory cache implementation
│ ├── engine # Domain-specific logic (Halving, Trend calculations)
│ │ └── bitcoin
│ │ ├── correlation # Pearson statistical correlation analysis
│ │ ├── valuation # Fair value metrics (M2/BTC ratio)
│ │ ├── halving # Scarcity and epoch projections
│ │ └── trend # Network behavior and sentiment analysis
│ ├── filters # Domain-level filtering logic
│ ├── httpx # HTTP handlers
│ ├── middleware # HTTP middleware
│ ├── models # API response models
│ └── sources # Upstream providers
│ ├── macro # FRED API (M2 Money Supply)
│ ├── market # Price aggregators (Binance, Coinbase, Kraken, Coingecko)
│ └── bitcoin # Mempool.space API (Fees, Blocks, Mempool)
Requirements
Go 1.21+Run the server
go run .
Server will start on:
http://localhost:8080
- Ensure you have a
.envfile with yourFRED_API_KEY. - Run using Docker Compose:
docker-compose up --buildRun all tests:
go test ./...
Run tests with gotestsum:
# Run tests with professional formatting (requires gotestsum)
gotestsum --format pkgname-and-test-fails- Handlers are kept small and focused
- External sources are isolated behind a
sourceslayer - Cache keys and API outputs are normalized for consistency
- API versioning is handled at the routing layer
- No frameworks, minimal dependencies
- Domain-Driven Engines: Complex business logic (like Halving projections and Trend analysis) is isolated in
internal/engine. This keeps handlers slim and makes the core logic easily testable without HTTP concerns. - Stateful Trends: Network trends are computed using a sliding window buffer, allowing - the API to detect sentiment changes rather than just showing raw snapshots.
- Type Safety: Leverage Go Generics in the cache layer to eliminate manual type assertions and runtime panics.
- Separation of Concerns: Analytics are decoupled from HTTP concerns via the engine layer, ensuring core logic is easily testable.
- Resilience: Upstream failures are handled gracefully with cached fallbacks and standardized error codes.
- Statistical Analysis: The correlation engine implements the Pearson Correlation Coefficient to measure the linear relationship between BTC price and M2 supply over a 730-day rolling window.
- Unified Fetching: Replaced redundant HTTP boilerplate with a centralized, generic FetchJSON[T] engine, reducing codebase size and ensuring consistent timeout/retry policies.
- Price Fallback Strategy: Implemented a prioritized provider loop that ensures price availability even if primary exchanges or aggregators face rate limits or downtime.
This project is actively used as an internal data layer and technical showcase.
Planned improvements:
- Derived data (Halving & Trends)
- Intelligence Engine (Valuation & Correlation)
- Type-safe Cache implementation
- Docker support
- Multi-provider price aggregation with automated fallback.
- Unified HTTP/JSON fetching engine.
- Persistence layer for historical snapshots
MIT