diff --git a/crates/brk_query/src/impl/block/info.rs b/crates/brk_query/src/impl/block/info.rs index c474807d0..cddd7d67e 100644 --- a/crates/brk_query/src/impl/block/info.rs +++ b/crates/brk_query/src/impl/block/info.rs @@ -7,7 +7,7 @@ use crate::Query; const DEFAULT_BLOCK_COUNT: u32 = 10; impl Query { - pub fn block(&self, hash: &str) -> Result { + pub fn block(&self, hash: &BlockHash) -> Result { let height = self.height_by_hash(hash)?; self.block_by_height(height) } @@ -58,11 +58,10 @@ impl Query { // === Helper methods === - pub fn height_by_hash(&self, hash: &str) -> Result { + pub fn height_by_hash(&self, hash: &BlockHash) -> Result { let indexer = self.indexer(); - let blockhash: BlockHash = hash.parse().map_err(|_| Error::Str("Invalid block hash"))?; - let prefix = BlockHashPrefix::from(&blockhash); + let prefix = BlockHashPrefix::from(hash); indexer .stores diff --git a/crates/brk_query/src/impl/block/raw.rs b/crates/brk_query/src/impl/block/raw.rs index d5aa62114..334f9e322 100644 --- a/crates/brk_query/src/impl/block/raw.rs +++ b/crates/brk_query/src/impl/block/raw.rs @@ -1,11 +1,11 @@ use brk_error::{Error, Result}; -use brk_types::Height; +use brk_types::{BlockHash, Height}; use vecdb::{AnyVec, GenericStoredVec}; use crate::Query; impl Query { - pub fn block_raw(&self, hash: &str) -> Result> { + pub fn block_raw(&self, hash: &BlockHash) -> Result> { let height = self.height_by_hash(hash)?; self.block_raw_by_height(height) } diff --git a/crates/brk_query/src/impl/block/status.rs b/crates/brk_query/src/impl/block/status.rs index a7bf631af..6bb3b126b 100644 --- a/crates/brk_query/src/impl/block/status.rs +++ b/crates/brk_query/src/impl/block/status.rs @@ -1,11 +1,11 @@ use brk_error::Result; -use brk_types::{BlockStatus, Height}; +use brk_types::{BlockHash, BlockStatus, Height}; use vecdb::{AnyVec, GenericStoredVec}; use crate::Query; impl Query { - pub fn block_status(&self, hash: &str) -> Result { + pub fn block_status(&self, hash: &BlockHash) -> Result { let height = self.height_by_hash(hash)?; self.block_status_by_height(height) } diff --git a/crates/brk_query/src/impl/block/txs.rs b/crates/brk_query/src/impl/block/txs.rs index 5591c73d3..1c2c37928 100644 --- a/crates/brk_query/src/impl/block/txs.rs +++ b/crates/brk_query/src/impl/block/txs.rs @@ -1,24 +1,24 @@ use brk_error::{Error, Result}; -use brk_types::{Height, Transaction, TxIndex, Txid}; +use brk_types::{BlockHash, Height, Transaction, TxIndex, Txid}; use vecdb::{AnyVec, GenericStoredVec, TypedVecIterator}; use super::BLOCK_TXS_PAGE_SIZE; use crate::Query; impl Query { - pub fn block_txids(&self, hash: &str) -> Result> { + pub fn block_txids(&self, hash: &BlockHash) -> Result> { let height = self.height_by_hash(hash)?; self.block_txids_by_height(height) } - pub fn block_txs(&self, hash: &str, start_index: usize) -> Result> { + pub fn block_txs(&self, hash: &BlockHash, start_index: TxIndex) -> Result> { let height = self.height_by_hash(hash)?; - self.block_txs_by_height(height, start_index) + self.block_txs_by_height(height, start_index.into()) } - pub fn block_txid_at_index(&self, hash: &str, index: usize) -> Result { + pub fn block_txid_at_index(&self, hash: &BlockHash, index: TxIndex) -> Result { let height = self.height_by_hash(hash)?; - self.block_txid_at_index_by_height(height, index) + self.block_txid_at_index_by_height(height, index.into()) } // === Helper methods === diff --git a/crates/brk_query/src/impl/transaction.rs b/crates/brk_query/src/impl/transaction.rs index c2a9e24da..302f324ca 100644 --- a/crates/brk_query/src/impl/transaction.rs +++ b/crates/brk_query/src/impl/transaction.rs @@ -1,9 +1,9 @@ -use std::{io::Cursor, str::FromStr}; +use std::io::Cursor; use bitcoin::{consensus::Decodable, hex::DisplayHex}; use brk_error::{Error, Result}; use brk_types::{ - Sats, Transaction, TxIn, TxInIndex, TxIndex, TxOut, TxOutspend, TxStatus, Txid, TxidPath, + Sats, Transaction, TxIn, TxInIndex, TxIndex, TxOut, TxOutspend, TxStatus, Txid, TxidParam, TxidPrefix, Vin, Vout, Weight, }; use vecdb::{GenericStoredVec, TypedVecIterator}; @@ -11,13 +11,7 @@ use vecdb::{GenericStoredVec, TypedVecIterator}; use crate::Query; impl Query { - pub fn transaction(&self, TxidPath { txid }: TxidPath) -> Result { - let Ok(txid) = bitcoin::Txid::from_str(&txid) else { - return Err(Error::InvalidTxid); - }; - - let txid = Txid::from(txid); - + pub fn transaction(&self, TxidParam { txid }: TxidParam) -> Result { // First check mempool for unconfirmed transactions if let Some(mempool) = self.mempool() && let Some(tx_with_hex) = mempool.get_txs().get(&txid) @@ -40,13 +34,7 @@ impl Query { self.transaction_by_index(txindex) } - pub fn transaction_status(&self, TxidPath { txid }: TxidPath) -> Result { - let Ok(txid) = bitcoin::Txid::from_str(&txid) else { - return Err(Error::InvalidTxid); - }; - - let txid = Txid::from(txid); - + pub fn transaction_status(&self, TxidParam { txid }: TxidParam) -> Result { // First check mempool for unconfirmed transactions if let Some(mempool) = self.mempool() && mempool.get_txs().contains_key(&txid) @@ -79,13 +67,7 @@ impl Query { }) } - pub fn transaction_hex(&self, TxidPath { txid }: TxidPath) -> Result { - let Ok(txid) = bitcoin::Txid::from_str(&txid) else { - return Err(Error::InvalidTxid); - }; - - let txid = Txid::from(txid); - + pub fn transaction_hex(&self, TxidParam { txid }: TxidParam) -> Result { // First check mempool for unconfirmed transactions if let Some(mempool) = self.mempool() && let Some(tx_with_hex) = mempool.get_txs().get(&txid) @@ -108,13 +90,7 @@ impl Query { self.transaction_hex_by_index(txindex) } - pub fn outspend(&self, TxidPath { txid }: TxidPath, vout: Vout) -> Result { - let Ok(txid) = bitcoin::Txid::from_str(&txid) else { - return Err(Error::InvalidTxid); - }; - - let txid = Txid::from(txid); - + pub fn outspend(&self, TxidParam { txid }: TxidParam, vout: Vout) -> Result { // Mempool outputs are unspent in on-chain terms if let Some(mempool) = self.mempool() && mempool.get_txs().contains_key(&txid) @@ -156,13 +132,7 @@ impl Query { self.outspend_details(txinindex) } - pub fn outspends(&self, TxidPath { txid }: TxidPath) -> Result> { - let Ok(txid) = bitcoin::Txid::from_str(&txid) else { - return Err(Error::InvalidTxid); - }; - - let txid = Txid::from(txid); - + pub fn outspends(&self, TxidParam { txid }: TxidParam) -> Result> { // Mempool outputs are unspent in on-chain terms if let Some(mempool) = self.mempool() && let Some(tx_with_hex) = mempool.get_txs().get(&txid) diff --git a/crates/brk_server/src/api/addresses/mod.rs b/crates/brk_server/src/api/addresses/mod.rs index be68c8ba9..04e886026 100644 --- a/crates/brk_server/src/api/addresses/mod.rs +++ b/crates/brk_server/src/api/addresses/mod.rs @@ -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 { "/api/address/{address}", get_with(async | headers: HeaderMap, - Path(address): Path
, + Path(path): Path, State(state): State | { - 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 { "/api/address/{address}/txs", get_with(async | headers: HeaderMap, - Path(address): Path
, + Path(path): Path, Query(params): Query, State(state): State | { - 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 { "/api/address/{address}/utxo", get_with(async | headers: HeaderMap, - Path(address): Path
, + Path(path): Path, State(state): State | { - 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 { "/api/address/{address}/txs/mempool", get_with(async | headers: HeaderMap, - Path(address): Path
, + Path(path): Path, State(state): State | { // 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 { "/api/address/{address}/txs/chain", get_with(async | headers: HeaderMap, - Path(address): Path
, + Path(path): Path, Query(params): Query, State(state): State | { - 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 { "/api/v1/validate-address/{address}", get_with(async | headers: HeaderMap, - Path(address): Path, + Path(path): Path, State(state): State | { - 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") diff --git a/crates/brk_server/src/api/blocks/mod.rs b/crates/brk_server/src/api/blocks/mod.rs index fc8cf368d..da0060eaf 100644 --- a/crates/brk_server/src/api/blocks/mod.rs +++ b/crates/brk_server/src/api/blocks/mod.rs @@ -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 { "/api/block/{hash}", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { state.cached_json(&headers, CacheStrategy::Height, move |q| q.block(&path.hash)).await }, @@ -52,7 +52,7 @@ impl BlockRoutes for ApiRouter { "/api/block/{hash}/status", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_status(&path.hash)).await }, @@ -74,10 +74,9 @@ impl BlockRoutes for ApiRouter { "/api/block-height/{height}", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { - 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 { "/api/blocks/{start_height}", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { - 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 { "/api/block/{hash}/txids", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_txids(&path.hash)).await }, @@ -141,7 +139,7 @@ impl BlockRoutes for ApiRouter { "/api/block/{hash}/txs/{start_index}", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { 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 { "/api/block/{hash}/txid/{index}", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { 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 { "/api/v1/mining/blocks/timestamp/{timestamp}", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_by_timestamp(path.timestamp)).await }, @@ -206,7 +204,7 @@ impl BlockRoutes for ApiRouter { "/api/block/{hash}/raw", get_with( async |headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State| { state.cached_bytes(&headers, CacheStrategy::Height, move |q| q.block_raw(&path.hash)).await }, diff --git a/crates/brk_server/src/api/metrics/mod.rs b/crates/brk_server/src/api/metrics/mod.rs index 23a69557f..27ebf6971 100644 --- a/crates/brk_server/src/api/metrics/mod.rs +++ b/crates/brk_server/src/api/metrics/mod.rs @@ -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 { async | headers: HeaderMap, State(state): State, - Path(metric): Path, - Query(limit): Query + Path(path): Path, + Query(query): Query | { - 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::() .summary("Search metrics") .description("Fuzzy search for metrics by name. Supports partial matches and typos.") .ok_response::>() @@ -129,13 +128,13 @@ impl ApiMetricsRoutes for ApiRouter { async | headers: HeaderMap, State(state): State, - Path(metric): Path + Path(path): Path | { 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 diff --git a/crates/brk_server/src/api/mining/mod.rs b/crates/brk_server/src/api/mining/mod.rs index f0e663ac9..ace7b9005 100644 --- a/crates/brk_server/src/api/mining/mod.rs +++ b/crates/brk_server/src/api/mining/mod.rs @@ -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 { .api_route( "/api/v1/mining/pools/{time_period}", get_with( - async |headers: HeaderMap, Path(time_period): Path, State(state): State| { - state.cached_json(&headers, CacheStrategy::height_with(format!("{:?}", time_period)), move |q| q.mining_pools(time_period)).await + async |headers: HeaderMap, Path(path): Path, State(state): State| { + 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 { .api_route( "/api/v1/mining/pool/{slug}", get_with( - async |headers: HeaderMap, Path(path): Path, State(state): State| { + async |headers: HeaderMap, Path(path): Path, State(state): State| { 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 { .api_route( "/api/v1/mining/hashrate/{time_period}", get_with( - async |headers: HeaderMap, Path(time_period): Path, State(state): State| { - 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, State(state): State| { + 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 { .api_route( "/api/v1/mining/difficulty-adjustments/{time_period}", get_with( - async |headers: HeaderMap, Path(time_period): Path, State(state): State| { - 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, State(state): State| { + 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 { .api_route( "/api/v1/mining/blocks/fees/{time_period}", get_with( - async |headers: HeaderMap, Path(time_period): Path, State(state): State| { - 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, State(state): State| { + 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 { .api_route( "/api/v1/mining/blocks/rewards/{time_period}", get_with( - async |headers: HeaderMap, Path(time_period): Path, State(state): State| { - 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, State(state): State| { + 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 { .api_route( "/api/v1/mining/blocks/fee-rates/{time_period}", get_with( - async |headers: HeaderMap, Path(time_period): Path, State(state): State| { - 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, State(state): State| { + 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 { .api_route( "/api/v1/mining/blocks/sizes-weights/{time_period}", get_with( - async |headers: HeaderMap, Path(time_period): Path, State(state): State| { - 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, State(state): State| { + 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 { .api_route( "/api/v1/mining/reward-stats/{block_count}", get_with( - async |headers: HeaderMap, Path(path): Path, State(state): State| { + async |headers: HeaderMap, Path(path): Path, State(state): State| { state.cached_json(&headers, CacheStrategy::height_with(format!("reward-stats-{}", path.block_count)), move |q| q.reward_stats(path.block_count)).await }, |op| { diff --git a/crates/brk_server/src/api/transactions/mod.rs b/crates/brk_server/src/api/transactions/mod.rs index 42fc36f4b..71684dfd5 100644 --- a/crates/brk_server/src/api/transactions/mod.rs +++ b/crates/brk_server/src/api/transactions/mod.rs @@ -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 { get_with( async | headers: HeaderMap, - Path(txid): Path, + Path(txid): Path, State(state): State | { state.cached_json(&headers, CacheStrategy::Height, move |q| q.transaction(txid)).await @@ -48,7 +48,7 @@ impl TxRoutes for ApiRouter { get_with( async | headers: HeaderMap, - Path(txid): Path, + Path(txid): Path, State(state): State | { state.cached_json(&headers, CacheStrategy::Height, move |q| q.transaction_status(txid)).await @@ -71,7 +71,7 @@ impl TxRoutes for ApiRouter { get_with( async | headers: HeaderMap, - Path(txid): Path, + Path(txid): Path, State(state): State | { state.cached_text(&headers, CacheStrategy::Height, move |q| q.transaction_hex(txid)).await @@ -94,10 +94,10 @@ impl TxRoutes for ApiRouter { get_with( async | headers: HeaderMap, - Path(path): Path, + Path(path): Path, State(state): State | { - 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 { get_with( async | headers: HeaderMap, - Path(txid): Path, + Path(txid): Path, State(state): State | { state.cached_json(&headers, CacheStrategy::Height, move |q| q.outspends(txid)).await diff --git a/crates/brk_types/src/address.rs b/crates/brk_types/src/address.rs index 1b1d3f1fe..cd8e90500 100644 --- a/crates/brk_types/src/address.rs +++ b/crates/brk_types/src/address.rs @@ -1,9 +1,9 @@ -use std::{borrow::Cow, fmt, str::FromStr}; +use std::{fmt, str::FromStr}; use bitcoin::ScriptBuf; use brk_error::Error; use derive_deref::Deref; -use schemars::{JsonSchema, Schema, SchemaGenerator, json_schema}; +use schemars::JsonSchema; use serde::{Deserialize, Serialize, Serializer}; use crate::AddressBytes; @@ -11,29 +11,15 @@ use crate::AddressBytes; use super::OutputType; /// Bitcoin address string -#[derive(Debug, Deref, Deserialize)] +#[derive(Debug, Deref, Deserialize, JsonSchema)] +#[serde(transparent)] +#[schemars( + example = &"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f", + example = &"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", + example = &"bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq" +)] pub struct Address(String); -impl JsonSchema for Address { - fn schema_name() -> Cow<'static, str> { - Cow::Borrowed("Address") - } - - fn json_schema(_: &mut SchemaGenerator) -> Schema { - json_schema!({ - "type": "object", - "required": ["address"], - "properties": { - "address": { - "type": "string", - "description": "Bitcoin address string", - "examples": ["04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"] - } - } - }) - } -} - impl fmt::Display for Address { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.0) diff --git a/crates/brk_types/src/addressparam.rs b/crates/brk_types/src/addressparam.rs new file mode 100644 index 000000000..8c0d74fea --- /dev/null +++ b/crates/brk_types/src/addressparam.rs @@ -0,0 +1,9 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::Address; + +#[derive(Deserialize, JsonSchema)] +pub struct AddressParam { + pub address: Address, +} diff --git a/crates/brk_types/src/blockcountpath.rs b/crates/brk_types/src/blockcountparam.rs similarity index 65% rename from crates/brk_types/src/blockcountpath.rs rename to crates/brk_types/src/blockcountparam.rs index c9a6102d2..de2989690 100644 --- a/crates/brk_types/src/blockcountpath.rs +++ b/crates/brk_types/src/blockcountparam.rs @@ -2,8 +2,8 @@ use schemars::JsonSchema; use serde::Deserialize; #[derive(Deserialize, JsonSchema)] -pub struct BlockCountPath { - /// Number of blocks to include in the stats +pub struct BlockCountParam { + /// Number of recent blocks to include #[schemars(example = 100)] pub block_count: usize, } diff --git a/crates/brk_types/src/blockhash.rs b/crates/brk_types/src/blockhash.rs index 5fd9b296b..4cae319b1 100644 --- a/crates/brk_types/src/blockhash.rs +++ b/crates/brk_types/src/blockhash.rs @@ -4,12 +4,17 @@ use bitcoin::hashes::Hash; use brk_error::Error; use derive_deref::Deref; use schemars::JsonSchema; -use serde::{Serialize, Serializer}; +use serde::{Deserialize, Serialize, Serializer, de}; use vecdb::{Bytes, Formattable}; /// Block hash #[derive(Debug, Deref, Clone, PartialEq, Eq, Bytes, JsonSchema)] #[repr(C)] +#[schemars( + transparent, + with = "String", + example = &"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" +)] pub struct BlockHash([u8; 32]); impl TryFrom<&str> for BlockHash { @@ -76,6 +81,16 @@ impl Serialize for BlockHash { } } +impl<'de> Deserialize<'de> for BlockHash { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + Self::from_str(&s).map_err(de::Error::custom) + } +} + impl Formattable for BlockHash { #[inline(always)] fn may_need_escaping() -> bool { diff --git a/crates/brk_types/src/blockhashparam.rs b/crates/brk_types/src/blockhashparam.rs new file mode 100644 index 000000000..10568d200 --- /dev/null +++ b/crates/brk_types/src/blockhashparam.rs @@ -0,0 +1,9 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::BlockHash; + +#[derive(Deserialize, JsonSchema)] +pub struct BlockHashParam { + pub hash: BlockHash, +} diff --git a/crates/brk_types/src/blockhashpath.rs b/crates/brk_types/src/blockhashpath.rs deleted file mode 100644 index 0de7a4630..000000000 --- a/crates/brk_types/src/blockhashpath.rs +++ /dev/null @@ -1,9 +0,0 @@ -use schemars::JsonSchema; -use serde::Deserialize; - -#[derive(Deserialize, JsonSchema)] -pub struct BlockHashPath { - /// Bitcoin block hash - #[schemars(example = &"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")] - pub hash: String, -} diff --git a/crates/brk_types/src/blockhashstartindex.rs b/crates/brk_types/src/blockhashstartindex.rs new file mode 100644 index 000000000..2f819452b --- /dev/null +++ b/crates/brk_types/src/blockhashstartindex.rs @@ -0,0 +1,14 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::{BlockHash, TxIndex}; + +#[derive(Deserialize, JsonSchema)] +pub struct BlockHashStartIndex { + /// Bitcoin block hash + pub hash: BlockHash, + + /// Starting transaction index within the block (0-based) + #[schemars(example = 0)] + pub start_index: TxIndex, +} diff --git a/crates/brk_types/src/blockhashstartindexpath.rs b/crates/brk_types/src/blockhashstartindexpath.rs deleted file mode 100644 index 8e74856f1..000000000 --- a/crates/brk_types/src/blockhashstartindexpath.rs +++ /dev/null @@ -1,13 +0,0 @@ -use schemars::JsonSchema; -use serde::Deserialize; - -#[derive(Deserialize, JsonSchema)] -pub struct BlockHashStartIndexPath { - /// Bitcoin block hash - #[schemars(example = &"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")] - pub hash: String, - - /// Starting transaction index (0-based) - #[schemars(example = 0)] - pub start_index: usize, -} diff --git a/crates/brk_types/src/blockhashtxindexpath.rs b/crates/brk_types/src/blockhashtxindex.rs similarity index 53% rename from crates/brk_types/src/blockhashtxindexpath.rs rename to crates/brk_types/src/blockhashtxindex.rs index cc64fd432..ae5f120b4 100644 --- a/crates/brk_types/src/blockhashtxindexpath.rs +++ b/crates/brk_types/src/blockhashtxindex.rs @@ -1,13 +1,14 @@ use schemars::JsonSchema; use serde::Deserialize; +use crate::{BlockHash, TxIndex}; + #[derive(Deserialize, JsonSchema)] -pub struct BlockHashTxIndexPath { +pub struct BlockHashTxIndex { /// Bitcoin block hash - #[schemars(example = &"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")] - pub hash: String, + pub hash: BlockHash, /// Transaction index within the block (0-based) #[schemars(example = 0)] - pub index: usize, + pub index: TxIndex, } diff --git a/crates/brk_types/src/height.rs b/crates/brk_types/src/height.rs index 19898d723..0352957e3 100644 --- a/crates/brk_types/src/height.rs +++ b/crates/brk_types/src/height.rs @@ -30,6 +30,7 @@ use super::StoredU64; JsonSchema, Hash, )] +#[schemars(example = 0, example = 210_000, example = 420_000, example = 840_000)] pub struct Height(u32); impl Height { diff --git a/crates/brk_types/src/heightparam.rs b/crates/brk_types/src/heightparam.rs new file mode 100644 index 000000000..5c7301795 --- /dev/null +++ b/crates/brk_types/src/heightparam.rs @@ -0,0 +1,9 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::Height; + +#[derive(Deserialize, JsonSchema)] +pub struct HeightParam { + pub height: Height, +} diff --git a/crates/brk_types/src/heightpath.rs b/crates/brk_types/src/heightpath.rs deleted file mode 100644 index 47a370169..000000000 --- a/crates/brk_types/src/heightpath.rs +++ /dev/null @@ -1,9 +0,0 @@ -use schemars::JsonSchema; -use serde::Deserialize; - -#[derive(Deserialize, JsonSchema)] -pub struct HeightPath { - /// Bitcoin block height - #[schemars(example = 0)] - pub height: u32, -} diff --git a/crates/brk_types/src/lib.rs b/crates/brk_types/src/lib.rs index 020606f18..7176051e4 100644 --- a/crates/brk_types/src/lib.rs +++ b/crates/brk_types/src/lib.rs @@ -9,6 +9,7 @@ mod addresshash; mod addressindexoutpoint; mod addressindextxindex; mod addressmempoolstats; +mod addressparam; mod addressstats; mod addresstxidsparam; mod addressvalidation; @@ -17,14 +18,14 @@ mod bitcoin; mod blkmetadata; mod blkposition; mod block; -mod blockcountpath; +mod blockcountparam; mod blockfeesentry; mod blockferatesentry; mod blockhash; -mod blockhashpath; +mod blockhashparam; mod blockhashprefix; -mod blockhashstartindexpath; -mod blockhashtxindexpath; +mod blockhashstartindex; +mod blockhashtxindex; mod blockinfo; mod blockrewardsentry; mod blocksizeentry; @@ -56,10 +57,11 @@ mod hashrateentry; mod hashratesummary; mod health; mod height; -mod heightpath; +mod heightparam; mod index; mod indexinfo; mod limit; +mod limitparam; mod loadedaddressdata; mod loadedaddressindex; mod mempoolblock; @@ -67,6 +69,7 @@ mod mempoolentryinfo; mod mempoolinfo; mod metric; mod metriccount; +mod metricparam; mod metricdata; mod metrics; mod metricselection; @@ -102,7 +105,7 @@ mod pooldetail; mod poolinfo; mod pools; mod poolslug; -mod poolslugpath; +mod poolslugparam; mod poolssummary; mod poolstats; mod quarterindex; @@ -111,7 +114,7 @@ mod recommendedfees; mod rewardstats; mod sats; mod semesterindex; -mod startheightpath; +mod startheightparam; mod stored_bool; mod stored_f32; mod stored_f64; @@ -122,15 +125,15 @@ mod stored_u32; mod stored_u64; mod stored_u8; mod timeperiod; -mod timeperiodpath; +mod timeperiodparam; mod timestamp; -mod timestamppath; +mod timestampparam; mod treenode; mod tx; mod txid; -mod txidpath; +mod txidparam; mod txidprefix; -mod txidvoutpath; +mod txidvout; mod txin; mod txindex; mod txinindex; @@ -144,6 +147,7 @@ mod typeindex; mod unit; mod unknownoutputindex; mod utxo; +mod validateaddressparam; mod vin; mod vout; mod vsize; @@ -158,6 +162,7 @@ pub use addresshash::*; pub use addressindexoutpoint::*; pub use addressindextxindex::*; pub use addressmempoolstats::*; +pub use addressparam::*; pub use addressstats::*; pub use addresstxidsparam::*; pub use addressvalidation::*; @@ -166,14 +171,14 @@ pub use bitcoin::*; pub use blkmetadata::*; pub use blkposition::*; pub use block::*; -pub use blockcountpath::*; +pub use blockcountparam::*; pub use blockfeesentry::*; pub use blockferatesentry::*; pub use blockhash::*; -pub use blockhashpath::*; +pub use blockhashparam::*; pub use blockhashprefix::*; -pub use blockhashstartindexpath::*; -pub use blockhashtxindexpath::*; +pub use blockhashstartindex::*; +pub use blockhashtxindex::*; pub use blockinfo::*; pub use blockrewardsentry::*; pub use blocksizeentry::*; @@ -205,10 +210,11 @@ pub use hashrateentry::*; pub use hashratesummary::*; pub use health::*; pub use height::*; -pub use heightpath::*; +pub use heightparam::*; pub use index::*; pub use indexinfo::*; pub use limit::*; +pub use limitparam::*; pub use loadedaddressdata::*; pub use loadedaddressindex::*; pub use mempoolblock::*; @@ -216,6 +222,7 @@ pub use mempoolentryinfo::*; pub use mempoolinfo::*; pub use metric::*; pub use metriccount::*; +pub use metricparam::*; pub use metricdata::*; pub use metrics::*; pub use metricselection::*; @@ -251,7 +258,7 @@ pub use pooldetail::*; pub use poolinfo::*; pub use pools::*; pub use poolslug::*; -pub use poolslugpath::*; +pub use poolslugparam::*; pub use poolssummary::*; pub use poolstats::*; pub use quarterindex::*; @@ -260,7 +267,7 @@ pub use recommendedfees::*; pub use rewardstats::*; pub use sats::*; pub use semesterindex::*; -pub use startheightpath::*; +pub use startheightparam::*; pub use stored_bool::*; pub use stored_f32::*; pub use stored_f64::*; @@ -271,15 +278,15 @@ pub use stored_u16::*; pub use stored_u32::*; pub use stored_u64::*; pub use timeperiod::*; -pub use timeperiodpath::*; +pub use timeperiodparam::*; pub use timestamp::*; -pub use timestamppath::*; +pub use timestampparam::*; pub use treenode::*; pub use tx::*; pub use txid::*; -pub use txidpath::*; +pub use txidparam::*; pub use txidprefix::*; -pub use txidvoutpath::*; +pub use txidvout::*; pub use txin::*; pub use txindex::*; pub use txinindex::*; @@ -293,6 +300,7 @@ pub use typeindex::*; pub use unit::*; pub use unknownoutputindex::*; pub use utxo::*; +pub use validateaddressparam::*; pub use vin::*; pub use vout::*; pub use vsize::*; diff --git a/crates/brk_types/src/limit.rs b/crates/brk_types/src/limit.rs index 631e3d4e8..9507cd32c 100644 --- a/crates/brk_types/src/limit.rs +++ b/crates/brk_types/src/limit.rs @@ -1,12 +1,11 @@ -use std::borrow::Cow; - use derive_deref::Deref; -use schemars::{JsonSchema, Schema, SchemaGenerator, json_schema}; +use schemars::JsonSchema; use serde::Deserialize; /// Maximum number of results to return. Defaults to 100 if not specified. -#[derive(Debug, Deref, Deserialize)] -#[serde(default = "default_search_limit")] +#[derive(Debug, Deref, Deserialize, JsonSchema)] +#[serde(transparent)] +#[schemars(default, example = 1, example = 10, example = 100)] pub struct Limit(usize); impl Limit { @@ -14,26 +13,8 @@ impl Limit { pub const DEFAULT: Self = Self(100); } -fn default_search_limit() -> Limit { - Limit::DEFAULT -} - -impl JsonSchema for Limit { - fn schema_name() -> Cow<'static, str> { - Cow::Borrowed("Limit") - } - - fn json_schema(_: &mut SchemaGenerator) -> Schema { - json_schema!({ - "type": "object", - "properties": { - "limit": { - "type": "integer", - "description": "Maximum number of results to return. Defaults to 100 if not specified.", - "default": 100, - "examples": [1, 10, 100, 1000, 10000, 100000] - } - } - }) +impl Default for Limit { + fn default() -> Self { + Self::DEFAULT } } diff --git a/crates/brk_types/src/limitparam.rs b/crates/brk_types/src/limitparam.rs new file mode 100644 index 000000000..0fdc74ced --- /dev/null +++ b/crates/brk_types/src/limitparam.rs @@ -0,0 +1,10 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::Limit; + +#[derive(Deserialize, JsonSchema)] +pub struct LimitParam { + #[serde(default)] + pub limit: Limit, +} diff --git a/crates/brk_types/src/metric.rs b/crates/brk_types/src/metric.rs index fb5d0de5d..58c1a1ff9 100644 --- a/crates/brk_types/src/metric.rs +++ b/crates/brk_types/src/metric.rs @@ -1,12 +1,18 @@ -use std::{borrow::Cow, fmt::Display}; +use std::fmt::Display; use derive_deref::Deref; -use schemars::{JsonSchema, Schema, SchemaGenerator, json_schema}; +use schemars::JsonSchema; use serde::Deserialize; /// Metric name -#[derive(Debug, Clone, Deref, Deserialize)] +#[derive(Debug, Clone, Deref, Deserialize, JsonSchema)] #[serde(transparent)] +#[schemars( + with = "String", + example = &"price_close", + example = &"market_cap", + example = &"realized_price" +)] pub struct Metric(String); impl From for Metric { @@ -28,17 +34,3 @@ impl Display for Metric { write!(f, "{}", self.0) } } - -impl JsonSchema for Metric { - fn schema_name() -> Cow<'static, str> { - Cow::Borrowed("Metric") - } - - fn json_schema(_: &mut SchemaGenerator) -> Schema { - json_schema!({ - "type": "string", - "description": "Metric name", - "examples": ["price_close", "market_cap", "realized_price"] - }) - } -} diff --git a/crates/brk_types/src/metricparam.rs b/crates/brk_types/src/metricparam.rs new file mode 100644 index 000000000..2ea7dcd0c --- /dev/null +++ b/crates/brk_types/src/metricparam.rs @@ -0,0 +1,9 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::Metric; + +#[derive(Deserialize, JsonSchema)] +pub struct MetricParam { + pub metric: Metric, +} diff --git a/crates/brk_types/src/metrics.rs b/crates/brk_types/src/metrics.rs index a13b50177..86cc87fc5 100644 --- a/crates/brk_types/src/metrics.rs +++ b/crates/brk_types/src/metrics.rs @@ -6,9 +6,14 @@ use serde::Deserialize; use super::Metric; -/// A list of metrics +/// Comma-separated list of metric names #[derive(Debug, Deref, JsonSchema)] -#[schemars(transparent)] +#[schemars( + with = "String", + example = &"price_close", + example = &"price_close,market_cap", + example = &"realized_price,nvt_ratio,mvrv" +)] pub struct Metrics(Vec); const MAX_VECS: usize = 32; diff --git a/crates/brk_types/src/metricwithindex.rs b/crates/brk_types/src/metricwithindex.rs index 461a4e524..dfa7ad825 100644 --- a/crates/brk_types/src/metricwithindex.rs +++ b/crates/brk_types/src/metricwithindex.rs @@ -5,6 +5,9 @@ use crate::{Index, Metric}; #[derive(Deserialize, JsonSchema)] pub struct MetricWithIndex { + /// Metric name pub metric: Metric, + + /// Aggregation index pub index: Index, } diff --git a/crates/brk_types/src/pagination.rs b/crates/brk_types/src/pagination.rs index b10e32986..f60d62be9 100644 --- a/crates/brk_types/src/pagination.rs +++ b/crates/brk_types/src/pagination.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; pub struct Pagination { /// Pagination index #[serde(default, alias = "p")] + #[schemars(example = 0, example = 1, example = 2)] pub page: Option, } diff --git a/crates/brk_types/src/poolslugpath.rs b/crates/brk_types/src/poolslugparam.rs similarity index 50% rename from crates/brk_types/src/poolslugpath.rs rename to crates/brk_types/src/poolslugparam.rs index 0d08d2e35..2c09e26ef 100644 --- a/crates/brk_types/src/poolslugpath.rs +++ b/crates/brk_types/src/poolslugparam.rs @@ -3,9 +3,7 @@ use serde::Deserialize; use super::PoolSlug; -/// Path parameter for pool detail endpoint #[derive(Deserialize, JsonSchema)] -pub struct PoolSlugPath { - /// Pool slug (e.g., "foundryusa", "f2pool", "antpool") +pub struct PoolSlugParam { pub slug: PoolSlug, } diff --git a/crates/brk_types/src/startheightpath.rs b/crates/brk_types/src/startheightparam.rs similarity index 67% rename from crates/brk_types/src/startheightpath.rs rename to crates/brk_types/src/startheightparam.rs index 8217aa124..b09e222ab 100644 --- a/crates/brk_types/src/startheightpath.rs +++ b/crates/brk_types/src/startheightparam.rs @@ -1,9 +1,11 @@ use schemars::JsonSchema; use serde::Deserialize; +use crate::Height; + #[derive(Deserialize, JsonSchema)] -pub struct StartHeightPath { +pub struct StartHeightParam { /// Starting block height (optional, defaults to latest) #[schemars(example = 800000)] - pub start_height: Option, + pub start_height: Option, } diff --git a/crates/brk_types/src/timeperiodparam.rs b/crates/brk_types/src/timeperiodparam.rs new file mode 100644 index 000000000..e50113c61 --- /dev/null +++ b/crates/brk_types/src/timeperiodparam.rs @@ -0,0 +1,9 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use super::TimePeriod; + +#[derive(Deserialize, JsonSchema)] +pub struct TimePeriodParam { + pub time_period: TimePeriod, +} diff --git a/crates/brk_types/src/timeperiodpath.rs b/crates/brk_types/src/timeperiodpath.rs deleted file mode 100644 index 5f99d4247..000000000 --- a/crates/brk_types/src/timeperiodpath.rs +++ /dev/null @@ -1,12 +0,0 @@ -use schemars::JsonSchema; -use serde::Deserialize; - -use super::TimePeriod; - -/// Path parameter for mining pool statistics time period -#[derive(Deserialize, JsonSchema)] -pub struct TimePeriodPath { - /// Time period for statistics. - /// Valid values: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y - pub time_period: TimePeriod, -} diff --git a/crates/brk_types/src/timestamp.rs b/crates/brk_types/src/timestamp.rs index 321797957..c302155a4 100644 --- a/crates/brk_types/src/timestamp.rs +++ b/crates/brk_types/src/timestamp.rs @@ -8,7 +8,7 @@ use vecdb::{CheckedSub, Formattable, Pco}; use super::Date; -/// Timestamp +/// UNIX timestamp in seconds #[derive( Debug, Default, @@ -24,6 +24,7 @@ use super::Date; Pco, JsonSchema, )] +#[schemars(example = 1672531200)] pub struct Timestamp(u32); pub const ONE_HOUR_IN_SEC: u32 = 60 * 60; diff --git a/crates/brk_types/src/timestamppath.rs b/crates/brk_types/src/timestampparam.rs similarity index 58% rename from crates/brk_types/src/timestamppath.rs rename to crates/brk_types/src/timestampparam.rs index 1a5140fc2..2c50ee57f 100644 --- a/crates/brk_types/src/timestamppath.rs +++ b/crates/brk_types/src/timestampparam.rs @@ -4,8 +4,6 @@ use serde::Deserialize; use crate::Timestamp; #[derive(Deserialize, JsonSchema)] -pub struct TimestampPath { - /// UNIX timestamp in seconds - #[schemars(example = 1672531200)] +pub struct TimestampParam { pub timestamp: Timestamp, } diff --git a/crates/brk_types/src/txidparam.rs b/crates/brk_types/src/txidparam.rs new file mode 100644 index 000000000..90696a47d --- /dev/null +++ b/crates/brk_types/src/txidparam.rs @@ -0,0 +1,9 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::Txid; + +#[derive(Deserialize, JsonSchema)] +pub struct TxidParam { + pub txid: Txid, +} diff --git a/crates/brk_types/src/txidpath.rs b/crates/brk_types/src/txidpath.rs deleted file mode 100644 index ecd78fb4c..000000000 --- a/crates/brk_types/src/txidpath.rs +++ /dev/null @@ -1,9 +0,0 @@ -use schemars::JsonSchema; -use serde::Deserialize; - -#[derive(Deserialize, JsonSchema)] -pub struct TxidPath { - /// Bitcoin transaction id - #[schemars(example = &"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")] - pub txid: String, -} diff --git a/crates/brk_types/src/txidvout.rs b/crates/brk_types/src/txidvout.rs new file mode 100644 index 000000000..c8c343c13 --- /dev/null +++ b/crates/brk_types/src/txidvout.rs @@ -0,0 +1,10 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::{Txid, Vout}; + +#[derive(Deserialize, JsonSchema)] +pub struct TxidVout { + pub txid: Txid, + pub vout: Vout, +} diff --git a/crates/brk_types/src/txidvoutpath.rs b/crates/brk_types/src/txidvoutpath.rs deleted file mode 100644 index ffa156ce2..000000000 --- a/crates/brk_types/src/txidvoutpath.rs +++ /dev/null @@ -1,15 +0,0 @@ -use schemars::JsonSchema; -use serde::Deserialize; - -use crate::Vout; - -#[derive(Deserialize, JsonSchema)] -pub struct TxidVoutPath { - /// Bitcoin transaction id - #[schemars(example = &"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")] - pub txid: String, - - /// Output index - #[schemars(example = 0)] - pub vout: Vout, -} diff --git a/crates/brk_types/src/txindex.rs b/crates/brk_types/src/txindex.rs index 665aafeda..f486783fc 100644 --- a/crates/brk_types/src/txindex.rs +++ b/crates/brk_types/src/txindex.rs @@ -3,7 +3,7 @@ use std::ops::{Add, AddAssign}; use byteview::ByteView; use derive_deref::{Deref, DerefMut}; use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use vecdb::{CheckedSub, Formattable, Pco, PrintableIndex}; use super::StoredU32; @@ -20,6 +20,7 @@ use super::StoredU32; DerefMut, Default, Serialize, + Deserialize, Pco, JsonSchema, Hash, diff --git a/crates/brk_types/src/validateaddressparam.rs b/crates/brk_types/src/validateaddressparam.rs new file mode 100644 index 000000000..490456dea --- /dev/null +++ b/crates/brk_types/src/validateaddressparam.rs @@ -0,0 +1,8 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +#[derive(Deserialize, JsonSchema)] +pub struct ValidateAddressParam { + /// Bitcoin address to validate (can be any string) + pub address: String, +} diff --git a/crates/brk_types/src/vin.rs b/crates/brk_types/src/vin.rs index 60e42e13c..3b7f287e5 100644 --- a/crates/brk_types/src/vin.rs +++ b/crates/brk_types/src/vin.rs @@ -4,6 +4,7 @@ use serde::Serialize; /// Input index in the spending transaction #[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, JsonSchema)] +#[schemars(example = 0)] pub struct Vin(u16); impl Vin { diff --git a/crates/brk_types/src/vout.rs b/crates/brk_types/src/vout.rs index c3cb06a89..3da35f9f1 100644 --- a/crates/brk_types/src/vout.rs +++ b/crates/brk_types/src/vout.rs @@ -20,6 +20,7 @@ use vecdb::{Bytes, Formattable}; Bytes, Hash, )] +#[schemars(example = 0)] pub struct Vout(u16); impl Vout {