mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-28 16:49:58 -07:00
server: openapi fixes
This commit is contained in:
@@ -5,7 +5,10 @@ use axum::{
|
||||
response::Redirect,
|
||||
routing::get,
|
||||
};
|
||||
use brk_types::{Address, AddressStats, AddressTxidsParam, AddressValidation, Txid, Utxo};
|
||||
use brk_types::{
|
||||
AddressParam, AddressStats, AddressTxidsParam, AddressValidation, Txid, Utxo,
|
||||
ValidateAddressParam,
|
||||
};
|
||||
|
||||
use crate::{CacheStrategy, extended::TransformResponseExtended};
|
||||
|
||||
@@ -24,10 +27,10 @@ impl AddressRoutes for ApiRouter<AppState> {
|
||||
"/api/address/{address}",
|
||||
get_with(async |
|
||||
headers: HeaderMap,
|
||||
Path(address): Path<Address>,
|
||||
Path(path): Path<AddressParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address(address)).await
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address(path.address)).await
|
||||
}, |op| op
|
||||
.addresses_tag()
|
||||
.summary("Address information")
|
||||
@@ -43,11 +46,11 @@ impl AddressRoutes for ApiRouter<AppState> {
|
||||
"/api/address/{address}/txs",
|
||||
get_with(async |
|
||||
headers: HeaderMap,
|
||||
Path(address): Path<Address>,
|
||||
Path(path): Path<AddressParam>,
|
||||
Query(params): Query<AddressTxidsParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_txids(address, params.after_txid, params.limit)).await
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_txids(path.address, params.after_txid, params.limit)).await
|
||||
}, |op| op
|
||||
.addresses_tag()
|
||||
.summary("Address transaction IDs")
|
||||
@@ -63,10 +66,10 @@ impl AddressRoutes for ApiRouter<AppState> {
|
||||
"/api/address/{address}/utxo",
|
||||
get_with(async |
|
||||
headers: HeaderMap,
|
||||
Path(address): Path<Address>,
|
||||
Path(path): Path<AddressParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_utxos(address)).await
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_utxos(path.address)).await
|
||||
}, |op| op
|
||||
.addresses_tag()
|
||||
.summary("Address UTXOs")
|
||||
@@ -82,11 +85,11 @@ impl AddressRoutes for ApiRouter<AppState> {
|
||||
"/api/address/{address}/txs/mempool",
|
||||
get_with(async |
|
||||
headers: HeaderMap,
|
||||
Path(address): Path<Address>,
|
||||
Path(path): Path<AddressParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
// Mempool txs for an address - use MaxAge since it's volatile
|
||||
state.cached_json(&headers, CacheStrategy::MaxAge(5), move |q| q.address_mempool_txids(address)).await
|
||||
state.cached_json(&headers, CacheStrategy::MaxAge(5), move |q| q.address_mempool_txids(path.address)).await
|
||||
}, |op| op
|
||||
.addresses_tag()
|
||||
.summary("Address mempool transactions")
|
||||
@@ -101,11 +104,11 @@ impl AddressRoutes for ApiRouter<AppState> {
|
||||
"/api/address/{address}/txs/chain",
|
||||
get_with(async |
|
||||
headers: HeaderMap,
|
||||
Path(address): Path<Address>,
|
||||
Path(path): Path<AddressParam>,
|
||||
Query(params): Query<AddressTxidsParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_txids(address, params.after_txid, 25)).await
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_txids(path.address, params.after_txid, 25)).await
|
||||
}, |op| op
|
||||
.addresses_tag()
|
||||
.summary("Address confirmed transactions")
|
||||
@@ -121,10 +124,10 @@ impl AddressRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/validate-address/{address}",
|
||||
get_with(async |
|
||||
headers: HeaderMap,
|
||||
Path(address): Path<String>,
|
||||
Path(path): Path<ValidateAddressParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Static, move |_q| Ok(AddressValidation::from_address(&address))).await
|
||||
state.cached_json(&headers, CacheStrategy::Static, move |_q| Ok(AddressValidation::from_address(&path.address))).await
|
||||
}, |op| op
|
||||
.addresses_tag()
|
||||
.summary("Validate address")
|
||||
|
||||
@@ -7,8 +7,8 @@ use axum::{
|
||||
};
|
||||
use brk_query::BLOCK_TXS_PAGE_SIZE;
|
||||
use brk_types::{
|
||||
BlockHashPath, BlockHashStartIndexPath, BlockHashTxIndexPath, BlockInfo, BlockStatus,
|
||||
BlockTimestamp, Height, HeightPath, StartHeightPath, TimestampPath, Transaction, Txid,
|
||||
BlockHashParam, BlockHashStartIndex, BlockHashTxIndex, BlockInfo, BlockStatus, BlockTimestamp,
|
||||
HeightParam, StartHeightParam, TimestampParam, Transaction, Txid,
|
||||
};
|
||||
|
||||
use crate::{CacheStrategy, extended::TransformResponseExtended};
|
||||
@@ -30,7 +30,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/block/{hash}",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<BlockHashPath>,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block(&path.hash)).await
|
||||
},
|
||||
@@ -52,7 +52,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/block/{hash}/status",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<BlockHashPath>,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_status(&path.hash)).await
|
||||
},
|
||||
@@ -74,10 +74,9 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/block-height/{height}",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<HeightPath>,
|
||||
Path(path): Path<HeightParam>,
|
||||
State(state): State<AppState>| {
|
||||
let height = Height::from(path.height);
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_by_height(height)).await
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_by_height(path.height)).await
|
||||
},
|
||||
|op| {
|
||||
op.blocks_tag()
|
||||
@@ -97,10 +96,9 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/blocks/{start_height}",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<StartHeightPath>,
|
||||
Path(path): Path<StartHeightParam>,
|
||||
State(state): State<AppState>| {
|
||||
let start_height = path.start_height.map(Height::from);
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.blocks(start_height)).await
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.blocks(path.start_height)).await
|
||||
},
|
||||
|op| {
|
||||
op.blocks_tag()
|
||||
@@ -119,7 +117,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/block/{hash}/txids",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<BlockHashPath>,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_txids(&path.hash)).await
|
||||
},
|
||||
@@ -141,7 +139,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/block/{hash}/txs/{start_index}",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<BlockHashStartIndexPath>,
|
||||
Path(path): Path<BlockHashStartIndex>,
|
||||
State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_txs(&path.hash, path.start_index)).await
|
||||
},
|
||||
@@ -164,7 +162,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/block/{hash}/txid/{index}",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<BlockHashTxIndexPath>,
|
||||
Path(path): Path<BlockHashTxIndex>,
|
||||
State(state): State<AppState>| {
|
||||
state.cached_text(&headers, CacheStrategy::Height, move |q| q.block_txid_at_index(&path.hash, path.index).map(|t| t.to_string())).await
|
||||
},
|
||||
@@ -186,7 +184,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/blocks/timestamp/{timestamp}",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<TimestampPath>,
|
||||
Path(path): Path<TimestampParam>,
|
||||
State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_by_timestamp(path.timestamp)).await
|
||||
},
|
||||
@@ -206,7 +204,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/block/{hash}/raw",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Path(path): Path<BlockHashPath>,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
State(state): State<AppState>| {
|
||||
state.cached_bytes(&headers, CacheStrategy::Height, move |q| q.block_raw(&path.hash)).await
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@ use brk_query::{
|
||||
};
|
||||
use brk_traversable::TreeNode;
|
||||
use brk_types::{
|
||||
Index, IndexInfo, Limit, Metric, MetricCount, MetricData, MetricWithIndex, Metrics,
|
||||
Index, IndexInfo, LimitParam, MetricCount, MetricData, MetricParam, MetricWithIndex, Metrics,
|
||||
};
|
||||
|
||||
use crate::{CacheStrategy, extended::TransformResponseExtended};
|
||||
@@ -109,14 +109,13 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
|
||||
async |
|
||||
headers: HeaderMap,
|
||||
State(state): State<AppState>,
|
||||
Path(metric): Path<Metric>,
|
||||
Query(limit): Query<Limit>
|
||||
Path(path): Path<MetricParam>,
|
||||
Query(query): Query<LimitParam>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Static, move |q| Ok(q.match_metric(&metric, limit))).await
|
||||
state.cached_json(&headers, CacheStrategy::Static, move |q| Ok(q.match_metric(&path.metric, query.limit))).await
|
||||
},
|
||||
|op| op
|
||||
.metrics_tag()
|
||||
// .path_param::<Metric>()
|
||||
.summary("Search metrics")
|
||||
.description("Fuzzy search for metrics by name. Supports partial matches and typos.")
|
||||
.ok_response::<Vec<String>>()
|
||||
@@ -129,13 +128,13 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
|
||||
async |
|
||||
headers: HeaderMap,
|
||||
State(state): State<AppState>,
|
||||
Path(metric): Path<Metric>
|
||||
Path(path): Path<MetricParam>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Static, move |q| {
|
||||
if let Some(indexes) = q.metric_to_indexes(metric.clone()) {
|
||||
if let Some(indexes) = q.metric_to_indexes(path.metric.clone()) {
|
||||
return Ok(indexes.clone())
|
||||
}
|
||||
Err(q.metric_not_found_error(&metric))
|
||||
Err(q.metric_not_found_error(&path.metric))
|
||||
}).await
|
||||
},
|
||||
|op| op
|
||||
|
||||
@@ -6,9 +6,9 @@ use axum::{
|
||||
routing::get,
|
||||
};
|
||||
use brk_types::{
|
||||
BlockCountPath, BlockFeeRatesEntry, BlockFeesEntry, BlockRewardsEntry, BlockSizesWeights,
|
||||
BlockCountParam, BlockFeeRatesEntry, BlockFeesEntry, BlockRewardsEntry, BlockSizesWeights,
|
||||
DifficultyAdjustment, DifficultyAdjustmentEntry, HashrateSummary, PoolDetail, PoolInfo,
|
||||
PoolSlugPath, PoolsSummary, RewardStats, TimePeriod,
|
||||
PoolSlugParam, PoolsSummary, RewardStats, TimePeriodParam,
|
||||
};
|
||||
|
||||
use crate::{CacheStrategy, extended::TransformResponseExtended};
|
||||
@@ -61,8 +61,8 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/pools/{time_period}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("{:?}", time_period)), move |q| q.mining_pools(time_period)).await
|
||||
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("{:?}", path.time_period)), move |q| q.mining_pools(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.mining_tag()
|
||||
@@ -77,7 +77,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/pool/{slug}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(path): Path<PoolSlugPath>, State(state): State<AppState>| {
|
||||
async |headers: HeaderMap, Path(path): Path<PoolSlugParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(path.slug), move |q| q.pool_detail(path.slug)).await
|
||||
},
|
||||
|op| {
|
||||
@@ -110,8 +110,8 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/hashrate/{time_period}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("hashrate-{:?}", time_period)), move |q| q.hashrate(Some(time_period))).await
|
||||
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("hashrate-{:?}", path.time_period)), move |q| q.hashrate(Some(path.time_period))).await
|
||||
},
|
||||
|op| {
|
||||
op.mining_tag()
|
||||
@@ -142,8 +142,8 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/difficulty-adjustments/{time_period}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("diff-adj-{:?}", time_period)), move |q| q.difficulty_adjustments(Some(time_period))).await
|
||||
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("diff-adj-{:?}", path.time_period)), move |q| q.difficulty_adjustments(Some(path.time_period))).await
|
||||
},
|
||||
|op| {
|
||||
op.mining_tag()
|
||||
@@ -158,8 +158,8 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/blocks/fees/{time_period}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("fees-{:?}", time_period)), move |q| q.block_fees(time_period)).await
|
||||
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("fees-{:?}", path.time_period)), move |q| q.block_fees(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.mining_tag()
|
||||
@@ -174,8 +174,8 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/blocks/rewards/{time_period}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("rewards-{:?}", time_period)), move |q| q.block_rewards(time_period)).await
|
||||
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("rewards-{:?}", path.time_period)), move |q| q.block_rewards(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.mining_tag()
|
||||
@@ -190,8 +190,8 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/blocks/fee-rates/{time_period}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("feerates-{:?}", time_period)), move |q| q.block_fee_rates(time_period)).await
|
||||
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("feerates-{:?}", path.time_period)), move |q| q.block_fee_rates(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.mining_tag()
|
||||
@@ -206,8 +206,8 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/blocks/sizes-weights/{time_period}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("sizes-{:?}", time_period)), move |q| q.block_sizes_weights(time_period)).await
|
||||
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("sizes-{:?}", path.time_period)), move |q| q.block_sizes_weights(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.mining_tag()
|
||||
@@ -222,7 +222,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/v1/mining/reward-stats/{block_count}",
|
||||
get_with(
|
||||
async |headers: HeaderMap, Path(path): Path<BlockCountPath>, State(state): State<AppState>| {
|
||||
async |headers: HeaderMap, Path(path): Path<BlockCountParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::height_with(format!("reward-stats-{}", path.block_count)), move |q| q.reward_stats(path.block_count)).await
|
||||
},
|
||||
|op| {
|
||||
|
||||
@@ -5,7 +5,7 @@ use axum::{
|
||||
response::Redirect,
|
||||
routing::get,
|
||||
};
|
||||
use brk_types::{Transaction, TxOutspend, TxStatus, TxidPath, TxidVoutPath};
|
||||
use brk_types::{Transaction, TxOutspend, TxStatus, TxidParam, TxidVout};
|
||||
|
||||
use crate::{CacheStrategy, extended::TransformResponseExtended};
|
||||
|
||||
@@ -25,7 +25,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |
|
||||
headers: HeaderMap,
|
||||
Path(txid): Path<TxidPath>,
|
||||
Path(txid): Path<TxidParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.transaction(txid)).await
|
||||
@@ -48,7 +48,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |
|
||||
headers: HeaderMap,
|
||||
Path(txid): Path<TxidPath>,
|
||||
Path(txid): Path<TxidParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.transaction_status(txid)).await
|
||||
@@ -71,7 +71,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |
|
||||
headers: HeaderMap,
|
||||
Path(txid): Path<TxidPath>,
|
||||
Path(txid): Path<TxidParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_text(&headers, CacheStrategy::Height, move |q| q.transaction_hex(txid)).await
|
||||
@@ -94,10 +94,10 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<TxidVoutPath>,
|
||||
Path(path): Path<TxidVout>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let txid = TxidPath { txid: path.txid };
|
||||
let txid = TxidParam { txid: path.txid };
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.outspend(txid, path.vout)).await
|
||||
},
|
||||
|op| op
|
||||
@@ -118,7 +118,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |
|
||||
headers: HeaderMap,
|
||||
Path(txid): Path<TxidPath>,
|
||||
Path(txid): Path<TxidParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Height, move |q| q.outspends(txid)).await
|
||||
|
||||
Reference in New Issue
Block a user