mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-08 14:11:56 -07:00
227 lines
8.8 KiB
Rust
227 lines
8.8 KiB
Rust
//
|
|
// https://docs.rs/schemars/latest/schemars/derive.JsonSchema.html
|
|
//
|
|
// Scalar:
|
|
// - Documentation: https://guides.scalar.com/scalar/scalar-api-references
|
|
// - Configuration: https://guides.scalar.com/scalar/scalar-api-references/configuration
|
|
// - Examples:
|
|
// - https://docs.machines.dev/
|
|
// - https://tailscale.com/api
|
|
// - https://api.supabase.com/api/v1
|
|
//
|
|
|
|
mod compact;
|
|
mod full;
|
|
|
|
pub use compact::ApiJson;
|
|
pub use full::OpenApiJson;
|
|
|
|
use aide::openapi::{Contact, Info, License, OpenApi, Tag};
|
|
|
|
use crate::VERSION;
|
|
|
|
pub fn create_openapi() -> OpenApi {
|
|
let info = Info {
|
|
title: "Bitcoin Research Kit".to_string(),
|
|
description: Some(
|
|
r#"API for querying Bitcoin blockchain data, mempool state, and on-chain series.
|
|
|
|
### Features
|
|
|
|
- **[Mempool.space](https://mempool.space/docs/api/rest) compatible**: Blocks, transactions, addresses, mining, fees, and mempool endpoints match the mempool.space REST API
|
|
- **Series**: Thousands of on-chain time-series across multiple indexes (date, block height, etc.)
|
|
- **Multiple formats**: JSON and CSV output
|
|
- **LLM-optimized**: [`/llms.txt`](/llms.txt) for discovery, [`/api.json`](/api.json) compact OpenAPI spec for tool use (full spec at [`/openapi.json`](/openapi.json))
|
|
|
|
### Quick start
|
|
|
|
```bash
|
|
curl -s https://bitview.space/api/blocks/tip/height
|
|
curl -s https://bitview.space/api/v1/fees/recommended
|
|
curl -s https://bitview.space/api/mempool
|
|
curl -s https://bitview.space/api/series/search?q=price
|
|
```
|
|
|
|
### Errors
|
|
|
|
All errors return structured JSON with a consistent format:
|
|
|
|
```json
|
|
{
|
|
"error": {
|
|
"type": "not_found",
|
|
"code": "series_not_found",
|
|
"message": "'foo' not found, did you mean 'bar'?",
|
|
"doc_url": "/api"
|
|
}
|
|
}
|
|
```
|
|
|
|
- **`type`**: Error category — `invalid_request` (400), `forbidden` (403), `not_found` (404), `unavailable` (503), or `internal` (500)
|
|
- **`code`**: Machine-readable error code (e.g. `invalid_address`, `series_not_found`, `weight_exceeded`)
|
|
- **`message`**: Human-readable description
|
|
- **`doc_url`**: Link to API documentation
|
|
|
|
### Client Libraries
|
|
|
|
- [JavaScript](https://www.npmjs.com/package/brk-client)
|
|
- [Python](https://pypi.org/project/brk-client/)
|
|
- [Rust](https://crates.io/crates/brk_client)
|
|
|
|
### Links
|
|
|
|
- [GitHub](https://github.com/bitcoinresearchkit/brk)
|
|
- [Bitview](https://bitview.space) - Web app built on this API"#
|
|
.to_string(),
|
|
),
|
|
version: format!("v{VERSION}"),
|
|
contact: Some(Contact {
|
|
name: Some("Bitcoin Research Kit".to_string()),
|
|
url: Some("https://github.com/bitcoinresearchkit/brk".to_string()),
|
|
email: Some("hello@bitcoinresearchkit.org".to_string()),
|
|
..Contact::default()
|
|
}),
|
|
license: Some(License {
|
|
name: "MIT".to_string(),
|
|
url: Some(
|
|
"https://github.com/bitcoinresearchkit/brk/blob/main/docs/LICENSE.md".to_string(),
|
|
),
|
|
..License::default()
|
|
}),
|
|
..Info::default()
|
|
};
|
|
|
|
let tags = vec compatible.*"
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "Addresses".to_string(),
|
|
description: Some(
|
|
"Query Bitcoin address data including balances, transaction history, and UTXOs. \
|
|
Supports all address types: P2PKH, P2SH, P2WPKH, P2WSH, and P2TR.\n\n\
|
|
*[Mempool.space](https://mempool.space/docs/api/rest) compatible.*"
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "Blocks".to_string(),
|
|
description: Some(
|
|
"Retrieve block data by hash or height. Access block headers, transaction lists, \
|
|
and raw block bytes.\n\n\
|
|
*[Mempool.space](https://mempool.space/docs/api/rest) compatible.*"
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "Mining".to_string(),
|
|
description: Some(
|
|
"Mining statistics including pool distribution, hashrate, difficulty adjustments, \
|
|
block rewards, and fee rates across configurable time periods.\n\n\
|
|
*[Mempool.space](https://mempool.space/docs/api/rest) compatible.*"
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "Fees".to_string(),
|
|
description: Some(
|
|
"Fee estimation and projected mempool blocks.\n\n\
|
|
*[Mempool.space](https://mempool.space/docs/api/rest) compatible.*"
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "Mempool".to_string(),
|
|
description: Some(
|
|
"Monitor unconfirmed transactions. Get mempool statistics, \
|
|
transaction IDs, fee histogram, and recent transactions.\n\n\
|
|
*[Mempool.space](https://mempool.space/docs/api/rest) compatible.*"
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "Transactions".to_string(),
|
|
description: Some(
|
|
"Retrieve transaction data by txid. Access full transaction details, confirmation \
|
|
status, raw hex, merkle proofs, and output spend information.\n\n\
|
|
*[Mempool.space](https://mempool.space/docs/api/rest) compatible.*"
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "Oracle".to_string(),
|
|
description: Some(
|
|
"On-chain BTC/USD price derived purely from round-dollar payment patterns in \
|
|
transaction outputs, with no external price feed. Payment activity is binned on a \
|
|
log scale, and a smoothed EMA over recent blocks locates the price.\n\n\
|
|
Histograms come in two flavors, each available at the live tip (mempool-blended) \
|
|
or at any confirmed height: `raw` bins every output by value with no filtering, \
|
|
while `ema` is the smoothed round-dollar window the price is read from. The live \
|
|
price is also at `/api/mempool/price`. Confirmed per-height price history is at \
|
|
`/api/vecs/height-to-price`."
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "URPD".to_string(),
|
|
description: Some(
|
|
"UTXO Realized Price Distribution. For each (cohort, date) pair, supply is \
|
|
grouped by the close price at which each UTXO was last moved. One snapshot is \
|
|
emitted per UTC day.\n\n\
|
|
Each bucket carries `supply` (BTC), `realized_cap` (USD, = `price_floor * supply`), \
|
|
and `unrealized_pnl` (USD, = `(close - price_floor) * supply`, can be negative).\n\n\
|
|
Aggregate with the `agg` query parameter (alias `bucket`):\n\
|
|
- `raw`: one bucket per rounded price (default).\n\
|
|
- `lin200` / `lin500` / `lin1000`: linear buckets, $200 / $500 / $1000 wide.\n\
|
|
- `log10` / `log50` / `log100` / `log200`: logarithmic buckets, N bins per price decade.\n\n\
|
|
Discovery flow: `GET /api/urpd` (cohorts), `GET /api/urpd/{cohort}` (latest), \
|
|
`GET /api/urpd/{cohort}/dates` (history), `GET /api/urpd/{cohort}/{date}` (specific)."
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
},
|
|
Tag {
|
|
name: "Metrics".to_string(),
|
|
description: Some("Deprecated - use Series".to_string()),
|
|
extensions: [("deprecated".to_string(), serde_json::Value::Bool(true))].into(),
|
|
..Default::default()
|
|
},
|
|
];
|
|
|
|
OpenApi {
|
|
info,
|
|
tags,
|
|
..OpenApi::default()
|
|
}
|
|
}
|