mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
@@ -69,16 +69,32 @@ pub fn generate_api_methods(output: &mut String, endpoints: &[Endpoint]) {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
writeln!(
|
||||
output,
|
||||
" * @param {{{{ signal?: AbortSignal, onUpdate?: (value: {}) => void }}}} [options]",
|
||||
return_type
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " * @returns {{Promise<{}>}}", return_type).unwrap();
|
||||
writeln!(output, " */").unwrap();
|
||||
|
||||
let params = build_method_params(endpoint);
|
||||
writeln!(output, " async {}({}) {{", method_name, params).unwrap();
|
||||
let params_with_opts = if params.is_empty() {
|
||||
"{ signal, onUpdate } = {}".to_string()
|
||||
} else {
|
||||
format!("{}, {{ signal, onUpdate }} = {{}}", params)
|
||||
};
|
||||
writeln!(output, " async {}({}) {{", method_name, params_with_opts).unwrap();
|
||||
|
||||
let path = build_path_template(&endpoint.path, &endpoint.path_params);
|
||||
|
||||
if endpoint.query_params.is_empty() {
|
||||
writeln!(output, " return this.getJson(`{}`);", path).unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" return this.getJson(`{}`, {{ signal, onUpdate }});",
|
||||
path
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
writeln!(output, " const params = new URLSearchParams();").unwrap();
|
||||
for param in &endpoint.query_params {
|
||||
@@ -109,11 +125,11 @@ pub fn generate_api_methods(output: &mut String, endpoints: &[Endpoint]) {
|
||||
|
||||
if endpoint.supports_csv {
|
||||
writeln!(output, " if (format === 'csv') {{").unwrap();
|
||||
writeln!(output, " return this.getText(path);").unwrap();
|
||||
writeln!(output, " return this.getText(path, {{ signal }});").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, " return this.getJson(path);").unwrap();
|
||||
writeln!(output, " return this.getJson(path, {{ signal, onUpdate }});").unwrap();
|
||||
} else {
|
||||
writeln!(output, " return this.getJson(path);").unwrap();
|
||||
writeln!(output, " return this.getJson(path, {{ signal, onUpdate }});").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -404,11 +404,14 @@ class BrkClientBase {{
|
||||
|
||||
/**
|
||||
* @param {{string}} path
|
||||
* @param {{{{ signal?: AbortSignal }}}} [options]
|
||||
* @returns {{Promise<Response>}}
|
||||
*/
|
||||
async get(path) {{
|
||||
async get(path, {{ signal }} = {{}}) {{
|
||||
const url = `${{this.baseUrl}}${{path}}`;
|
||||
const res = await fetch(url, {{ signal: AbortSignal.timeout(this.timeout) }});
|
||||
const signals = [AbortSignal.timeout(this.timeout)];
|
||||
if (signal) signals.push(signal);
|
||||
const res = await fetch(url, {{ signal: AbortSignal.any(signals) }});
|
||||
if (!res.ok) throw new BrkError(`HTTP ${{res.status}}: ${{url}}`, res.status);
|
||||
return res;
|
||||
}}
|
||||
@@ -417,10 +420,10 @@ class BrkClientBase {{
|
||||
* Make a GET request - races cache vs network, first to resolve calls onUpdate
|
||||
* @template T
|
||||
* @param {{string}} path
|
||||
* @param {{(value: T) => void}} [onUpdate] - Called when data is available (may be called twice: cache then network)
|
||||
* @param {{{{ onUpdate?: (value: T) => void, signal?: AbortSignal }}}} [options]
|
||||
* @returns {{Promise<T>}}
|
||||
*/
|
||||
async getJson(path, onUpdate) {{
|
||||
async getJson(path, {{ onUpdate, signal }} = {{}}) {{
|
||||
const url = `${{this.baseUrl}}${{path}}`;
|
||||
const cache = this._cache ?? await this._cachePromise;
|
||||
|
||||
@@ -440,7 +443,7 @@ class BrkClientBase {{
|
||||
return json;
|
||||
}});
|
||||
|
||||
const networkPromise = this.get(path).then(async (res) => {{
|
||||
const networkPromise = this.get(path, {{ signal }}).then(async (res) => {{
|
||||
const cloned = res.clone();
|
||||
const json = _addCamelGetters(await res.json());
|
||||
// Skip update if ETag matches and cache already delivered
|
||||
@@ -472,10 +475,11 @@ class BrkClientBase {{
|
||||
/**
|
||||
* Make a GET request and return raw text (for CSV responses)
|
||||
* @param {{string}} path
|
||||
* @param {{{{ signal?: AbortSignal }}}} [options]
|
||||
* @returns {{Promise<string>}}
|
||||
*/
|
||||
async getText(path) {{
|
||||
const res = await this.get(path);
|
||||
async getText(path, {{ signal }} = {{}}) {{
|
||||
const res = await this.get(path, {{ signal }});
|
||||
return res.text();
|
||||
}}
|
||||
|
||||
@@ -488,7 +492,7 @@ class BrkClientBase {{
|
||||
*/
|
||||
async _fetchSeriesData(path, onUpdate) {{
|
||||
const wrappedOnUpdate = onUpdate ? (/** @type {{SeriesData<T>}} */ raw) => onUpdate(_wrapSeriesData(raw)) : undefined;
|
||||
const raw = await this.getJson(path, wrappedOnUpdate);
|
||||
const raw = await this.getJson(path, {{ onUpdate: wrappedOnUpdate }});
|
||||
return _wrapSeriesData(raw);
|
||||
}}
|
||||
}}
|
||||
|
||||
@@ -8348,7 +8348,7 @@ impl BrkClient {
|
||||
|
||||
/// Block header
|
||||
///
|
||||
/// Returns the hex-encoded block header.
|
||||
/// Returns the hex-encoded 80-byte block header.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-header)*
|
||||
///
|
||||
@@ -8839,7 +8839,7 @@ impl BrkClient {
|
||||
|
||||
/// CPFP info
|
||||
///
|
||||
/// Returns ancestors and descendants for a CPFP transaction.
|
||||
/// Returns ancestors and descendants for a CPFP (Child Pays For Parent) transaction, including the effective fee rate of the package.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-children-pay-for-parent)*
|
||||
///
|
||||
@@ -8909,7 +8909,7 @@ impl BrkClient {
|
||||
|
||||
/// Block fee rates
|
||||
///
|
||||
/// Get block fee rate percentiles (min, 10th, 25th, median, 75th, 90th, max) for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y
|
||||
/// Get block fee rate percentiles (min, 10th, 25th, median, 75th, 90th, max) for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-feerates)*
|
||||
///
|
||||
@@ -8920,7 +8920,7 @@ impl BrkClient {
|
||||
|
||||
/// Block fees
|
||||
///
|
||||
/// Get average block fees for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y
|
||||
/// Get average total fees per block for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-fees)*
|
||||
///
|
||||
@@ -8931,7 +8931,7 @@ impl BrkClient {
|
||||
|
||||
/// Block rewards
|
||||
///
|
||||
/// Get average block rewards (coinbase = subsidy + fees) for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y
|
||||
/// Get average coinbase reward (subsidy + fees) per block for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-rewards)*
|
||||
///
|
||||
@@ -8942,7 +8942,7 @@ impl BrkClient {
|
||||
|
||||
/// Block sizes and weights
|
||||
///
|
||||
/// Get average block sizes and weights for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y
|
||||
/// Get average block sizes and weights for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-sizes-weights)*
|
||||
///
|
||||
@@ -8975,7 +8975,7 @@ impl BrkClient {
|
||||
|
||||
/// Difficulty adjustments
|
||||
///
|
||||
/// Get historical difficulty adjustments for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y.
|
||||
/// Get historical difficulty adjustments for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-difficulty-adjustments)*
|
||||
///
|
||||
@@ -9008,7 +9008,7 @@ impl BrkClient {
|
||||
|
||||
/// All pools hashrate
|
||||
///
|
||||
/// Get hashrate data for all mining pools for a time period. Valid periods: 1m, 3m, 6m, 1y, 2y, 3y
|
||||
/// Get hashrate data for all mining pools for a time period. Valid periods: `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-mining-pool-hashrates)*
|
||||
///
|
||||
@@ -9019,7 +9019,7 @@ impl BrkClient {
|
||||
|
||||
/// Network hashrate
|
||||
///
|
||||
/// Get network hashrate and difficulty data for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y
|
||||
/// Get network hashrate and difficulty data for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-hashrate)*
|
||||
///
|
||||
@@ -9085,7 +9085,7 @@ impl BrkClient {
|
||||
|
||||
/// Mining pool statistics
|
||||
///
|
||||
/// Get mining pool statistics for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y
|
||||
/// Get mining pool statistics for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-mining-pools)*
|
||||
///
|
||||
@@ -9129,7 +9129,7 @@ impl BrkClient {
|
||||
|
||||
/// Validate address
|
||||
///
|
||||
/// Validate a Bitcoin address and get information about its type and scriptPubKey.
|
||||
/// Validate a Bitcoin address and get information about its type and scriptPubKey. Returns `isvalid: false` with an error message for invalid addresses.
|
||||
///
|
||||
/// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-address-validate)*
|
||||
///
|
||||
|
||||
@@ -4,8 +4,8 @@ use bitcoin::{Network, PublicKey, ScriptBuf};
|
||||
use brk_error::{Error, Result};
|
||||
use brk_types::{
|
||||
Addr, AddrBytes, AddrChainStats, AddrHash, AddrIndexOutPoint, AddrIndexTxIndex, AddrStats,
|
||||
AnyAddrDataIndexEnum, BlockHash, Height, OutputType, Timestamp, Transaction, TxIndex, TxStatus,
|
||||
Txid, TypeIndex, Unit, Utxo, Vout,
|
||||
AnyAddrDataIndexEnum, BlockHash, Dollars, Height, OutputType, Timestamp, Transaction, TxIndex,
|
||||
TxStatus, Txid, TypeIndex, Unit, Utxo, Vout,
|
||||
};
|
||||
use vecdb::{ReadableVec, VecIndex};
|
||||
|
||||
@@ -69,8 +69,14 @@ impl Query {
|
||||
.into(),
|
||||
};
|
||||
|
||||
let realized_price = match &any_addr_index.to_enum() {
|
||||
AnyAddrDataIndexEnum::Funded(_) => addr_data.realized_price().to_dollars(),
|
||||
AnyAddrDataIndexEnum::Empty(_) => Dollars::default(),
|
||||
};
|
||||
|
||||
Ok(AddrStats {
|
||||
addr,
|
||||
addr_type,
|
||||
chain_stats: AddrChainStats {
|
||||
type_index,
|
||||
funded_txo_count: addr_data.funded_txo_count,
|
||||
@@ -78,6 +84,7 @@ impl Query {
|
||||
spent_txo_count: addr_data.spent_txo_count,
|
||||
spent_txo_sum: addr_data.sent,
|
||||
tx_count: addr_data.tx_count,
|
||||
realized_price,
|
||||
},
|
||||
mempool_stats: self.mempool().map(|mempool| {
|
||||
mempool
|
||||
|
||||
@@ -35,7 +35,7 @@ impl Query {
|
||||
let h4 = Hour4::from_timestamp(target);
|
||||
let cents = self.computer().prices.spot.cents.hour4.collect_one(h4);
|
||||
Ok(vec![HistoricalPriceEntry {
|
||||
time: usize::from(h4.to_timestamp()) as u64,
|
||||
time: h4.to_timestamp(),
|
||||
usd: Dollars::from(cents.flatten().unwrap_or_default()),
|
||||
}])
|
||||
}
|
||||
@@ -52,7 +52,7 @@ impl Query {
|
||||
.enumerate()
|
||||
.filter_map(|(i, cents)| {
|
||||
Some(HistoricalPriceEntry {
|
||||
time: usize::from(Hour4::from(i).to_timestamp()) as u64,
|
||||
time: Hour4::from(i).to_timestamp(),
|
||||
usd: Dollars::from(cents?),
|
||||
})
|
||||
})
|
||||
|
||||
@@ -147,9 +147,10 @@ impl AddrRoutes for ApiRouter<AppState> {
|
||||
.id("validate_address")
|
||||
.addrs_tag()
|
||||
.summary("Validate address")
|
||||
.description("Validate a Bitcoin address and get information about its type and scriptPubKey.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-address-validate)*")
|
||||
.description("Validate a Bitcoin address and get information about its type and scriptPubKey. Returns `isvalid: false` with an error message for invalid addresses.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-address-validate)*")
|
||||
.json_response::<AddrValidation>()
|
||||
.not_modified()
|
||||
.server_error()
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
.description("Returns block details with extras by hash.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-v1)*")
|
||||
.json_response::<BlockInfoV1>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.not_found()
|
||||
.server_error()
|
||||
},
|
||||
@@ -78,9 +79,10 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
op.id("get_block_header")
|
||||
.blocks_tag()
|
||||
.summary("Block header")
|
||||
.description("Returns the hex-encoded block header.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-header)*")
|
||||
.description("Returns the hex-encoded 80-byte block header.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-header)*")
|
||||
.text_response()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.not_found()
|
||||
.server_error()
|
||||
},
|
||||
|
||||
@@ -55,9 +55,10 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
op.id("get_pool_stats")
|
||||
.mining_tag()
|
||||
.summary("Mining pool statistics")
|
||||
.description("Get mining pool statistics for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-mining-pools)*")
|
||||
.description("Get mining pool statistics for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-mining-pools)*")
|
||||
.json_response::<PoolsSummary>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
@@ -107,9 +108,10 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
op.id("get_pools_hashrate_by_period")
|
||||
.mining_tag()
|
||||
.summary("All pools hashrate")
|
||||
.description("Get hashrate data for all mining pools for a time period. Valid periods: 1m, 3m, 6m, 1y, 2y, 3y\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-mining-pool-hashrates)*")
|
||||
.description("Get hashrate data for all mining pools for a time period. Valid periods: `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-mining-pool-hashrates)*")
|
||||
.json_response::<Vec<PoolHashrateEntry>>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
@@ -195,9 +197,10 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
op.id("get_hashrate_by_period")
|
||||
.mining_tag()
|
||||
.summary("Network hashrate")
|
||||
.description("Get network hashrate and difficulty data for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-hashrate)*")
|
||||
.description("Get network hashrate and difficulty data for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-hashrate)*")
|
||||
.json_response::<HashrateSummary>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
@@ -229,9 +232,10 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
op.id("get_difficulty_adjustments_by_period")
|
||||
.mining_tag()
|
||||
.summary("Difficulty adjustments")
|
||||
.description("Get historical difficulty adjustments for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-difficulty-adjustments)*")
|
||||
.description("Get historical difficulty adjustments for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-difficulty-adjustments)*")
|
||||
.json_response::<Vec<DifficultyAdjustmentEntry>>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
@@ -249,6 +253,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
.description("Get mining reward statistics for the last N blocks including total rewards, fees, and transaction count.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-reward-stats)*")
|
||||
.json_response::<RewardStats>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
@@ -263,9 +268,10 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
op.id("get_block_fees")
|
||||
.mining_tag()
|
||||
.summary("Block fees")
|
||||
.description("Get average block fees for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-fees)*")
|
||||
.description("Get average total fees per block for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-fees)*")
|
||||
.json_response::<Vec<BlockFeesEntry>>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
@@ -280,9 +286,10 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
op.id("get_block_rewards")
|
||||
.mining_tag()
|
||||
.summary("Block rewards")
|
||||
.description("Get average block rewards (coinbase = subsidy + fees) for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-rewards)*")
|
||||
.description("Get average coinbase reward (subsidy + fees) per block for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-rewards)*")
|
||||
.json_response::<Vec<BlockRewardsEntry>>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
@@ -297,9 +304,10 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
op.id("get_block_fee_rates")
|
||||
.mining_tag()
|
||||
.summary("Block fee rates")
|
||||
.description("Get block fee rate percentiles (min, 10th, 25th, median, 75th, 90th, max) for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-feerates)*")
|
||||
.description("Get block fee rate percentiles (min, 10th, 25th, median, 75th, 90th, max) for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-block-feerates)*")
|
||||
.json_response::<Vec<BlockFeeRatesEntry>>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
@@ -314,9 +322,10 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
op.id("get_block_sizes_weights")
|
||||
.mining_tag()
|
||||
.summary("Block sizes and weights")
|
||||
.description("Get average block sizes and weights for a time period. Valid periods: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-sizes-weights)*")
|
||||
.description("Get average block sizes and weights for a time period. Valid periods: `24h`, `3d`, `1w`, `1m`, `3m`, `6m`, `1y`, `2y`, `3y`.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-sizes-weights)*")
|
||||
.json_response::<BlockSizesWeights>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.server_error()
|
||||
},
|
||||
),
|
||||
|
||||
@@ -32,9 +32,10 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
.id("get_cpfp")
|
||||
.transactions_tag()
|
||||
.summary("CPFP info")
|
||||
.description("Returns ancestors and descendants for a CPFP transaction.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-children-pay-for-parent)*")
|
||||
.description("Returns ancestors and descendants for a CPFP (Child Pays For Parent) transaction, including the effective fee rate of the package.\n\n*[Mempool.space docs](https://mempool.space/docs/api/rest#get-children-pay-for-parent)*")
|
||||
.json_response::<CpfpInfo>()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.not_found()
|
||||
.server_error(),
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::Addr;
|
||||
|
||||
/// Bitcoin address path parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct AddrParam {
|
||||
#[serde(rename = "address")]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Block count path parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct BlockCountParam {
|
||||
/// Number of recent blocks to include
|
||||
|
||||
@@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::BlockHash;
|
||||
|
||||
/// Block hash path parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct BlockHashParam {
|
||||
pub hash: BlockHash,
|
||||
|
||||
@@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::{BlockHash, TxIndex};
|
||||
|
||||
/// Block hash + starting transaction index path parameters
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct BlockHashStartIndex {
|
||||
/// Bitcoin block hash
|
||||
|
||||
@@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::{BlockHash, TxIndex};
|
||||
|
||||
/// Block hash + transaction index path parameters
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct BlockHashTxIndex {
|
||||
/// Bitcoin block hash
|
||||
|
||||
@@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::Height;
|
||||
|
||||
/// Block height path parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct HeightParam {
|
||||
pub height: Height,
|
||||
|
||||
@@ -3,11 +3,13 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::{Height, PoolSlug};
|
||||
|
||||
/// Mining pool slug path parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct PoolSlugParam {
|
||||
pub slug: PoolSlug,
|
||||
}
|
||||
|
||||
/// Mining pool slug + block height path parameters
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct PoolSlugAndHeightParam {
|
||||
pub slug: PoolSlug,
|
||||
|
||||
@@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::TimePeriod;
|
||||
|
||||
/// Time period path parameter (24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y)
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct TimePeriodParam {
|
||||
#[schemars(example = &"24h")]
|
||||
|
||||
@@ -3,11 +3,13 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::Timestamp;
|
||||
|
||||
/// UNIX timestamp path parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct TimestampParam {
|
||||
pub timestamp: Timestamp,
|
||||
}
|
||||
|
||||
/// Optional UNIX timestamp query parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct OptionalTimestampParam {
|
||||
pub timestamp: Option<Timestamp>,
|
||||
|
||||
@@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
|
||||
use brk_types::Txid;
|
||||
|
||||
/// Transaction ID path parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct TxidParam {
|
||||
pub txid: Txid,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::{Sats, TypeIndex};
|
||||
use crate::{Dollars, Sats, TypeIndex};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Address statistics on the blockchain (confirmed transactions only)
|
||||
///
|
||||
/// Based on mempool.space's format with type_index extension.
|
||||
#[derive(Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct AddrChainStats {
|
||||
/// Total number of transaction outputs that funded this address
|
||||
#[schemars(example = 5)]
|
||||
@@ -30,4 +30,7 @@ pub struct AddrChainStats {
|
||||
/// Index of this address within its type on the blockchain
|
||||
#[schemars(example = TypeIndex::new(0))]
|
||||
pub type_index: TypeIndex,
|
||||
|
||||
/// Realized price (average cost basis) in USD
|
||||
pub realized_price: Dollars,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{Addr, AddrChainStats, AddrMempoolStats};
|
||||
use crate::{Addr, AddrChainStats, AddrMempoolStats, OutputType};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -12,6 +12,9 @@ pub struct AddrStats {
|
||||
#[serde(rename = "address")]
|
||||
pub addr: Addr,
|
||||
|
||||
/// Address type (p2pkh, p2sh, v0_p2wpkh, v0_p2wsh, v1_p2tr, etc.)
|
||||
pub addr_type: OutputType,
|
||||
|
||||
/// Statistics for confirmed transactions on the blockchain
|
||||
pub chain_stats: AddrChainStats,
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::{AddrBytes, OutputType};
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct AddrValidation {
|
||||
/// Whether the address is valid
|
||||
#[schemars(example = true)]
|
||||
pub isvalid: bool,
|
||||
|
||||
/// The validated address
|
||||
|
||||
@@ -54,14 +54,17 @@ pub struct BlockExtras {
|
||||
|
||||
/// Average transaction size in bytes
|
||||
#[serde(rename = "avgTxSize")]
|
||||
#[schemars(example = 534.5)]
|
||||
pub avg_tx_size: f64,
|
||||
|
||||
/// Total number of inputs (excluding coinbase)
|
||||
#[serde(rename = "totalInputs")]
|
||||
#[schemars(example = 5000)]
|
||||
pub total_inputs: u64,
|
||||
|
||||
/// Total number of outputs
|
||||
#[serde(rename = "totalOutputs")]
|
||||
#[schemars(example = 7500)]
|
||||
pub total_outputs: u64,
|
||||
|
||||
/// Total output amount in satoshis
|
||||
@@ -78,10 +81,12 @@ pub struct BlockExtras {
|
||||
|
||||
/// Number of segwit transactions
|
||||
#[serde(rename = "segwitTotalTxs")]
|
||||
#[schemars(example = 2000)]
|
||||
pub segwit_total_txs: u32,
|
||||
|
||||
/// Total size of segwit transactions in bytes
|
||||
#[serde(rename = "segwitTotalSize")]
|
||||
#[schemars(example = 1200000)]
|
||||
pub segwit_total_size: u64,
|
||||
|
||||
/// Total weight of segwit transactions
|
||||
@@ -95,10 +100,12 @@ pub struct BlockExtras {
|
||||
/// Note: intentionally differs from utxo_set_size diff which excludes unspendable outputs.
|
||||
/// Matches mempool.space/bitcoin-cli behavior.
|
||||
#[serde(rename = "utxoSetChange")]
|
||||
#[schemars(example = 2500)]
|
||||
pub utxo_set_change: i64,
|
||||
|
||||
/// Total spendable UTXO set size at this height (excludes OP_RETURN and other unspendable outputs)
|
||||
#[serde(rename = "utxoSetSize")]
|
||||
#[schemars(example = 170_000_000)]
|
||||
pub utxo_set_size: u64,
|
||||
|
||||
/// Total input amount in satoshis
|
||||
@@ -107,6 +114,7 @@ pub struct BlockExtras {
|
||||
|
||||
/// Virtual size in vbytes
|
||||
#[serde(rename = "virtualSize")]
|
||||
#[schemars(example = 998000.25)]
|
||||
pub virtual_size: f64,
|
||||
|
||||
/// Timestamp when the block was first seen (always null, not yet supported)
|
||||
|
||||
@@ -11,20 +11,29 @@ pub struct BlockInfo {
|
||||
/// Block height
|
||||
pub height: Height,
|
||||
/// Block version
|
||||
#[schemars(example = 536870912)]
|
||||
pub version: u32,
|
||||
/// Block timestamp (Unix time)
|
||||
pub timestamp: Timestamp,
|
||||
/// Compact target (bits)
|
||||
#[schemars(example = 386089497)]
|
||||
pub bits: u32,
|
||||
/// Nonce
|
||||
#[schemars(example = 2083236893)]
|
||||
pub nonce: u32,
|
||||
/// Block difficulty
|
||||
#[schemars(example = 110_451_832_649_830.94)]
|
||||
pub difficulty: f64,
|
||||
/// Merkle root of the transaction tree
|
||||
#[schemars(
|
||||
example = &"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
||||
)]
|
||||
pub merkle_root: String,
|
||||
/// Number of transactions
|
||||
#[schemars(example = 2500)]
|
||||
pub tx_count: u32,
|
||||
/// Block size in bytes
|
||||
#[schemars(example = 1580000)]
|
||||
pub size: u64,
|
||||
/// Block weight in weight units
|
||||
pub weight: Weight,
|
||||
|
||||
@@ -8,9 +8,11 @@ use crate::PoolSlug;
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BlockPool {
|
||||
/// Unique pool identifier
|
||||
#[schemars(example = 44)]
|
||||
pub id: u8,
|
||||
|
||||
/// Pool name
|
||||
#[schemars(example = &"Foundry USA")]
|
||||
pub name: String,
|
||||
|
||||
/// URL-friendly pool identifier
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::{BlockHash, Height};
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct BlockStatus {
|
||||
/// Whether this block is in the best chain
|
||||
#[schemars(example = true)]
|
||||
pub in_best_chain: bool,
|
||||
|
||||
/// Block height (only if in best chain)
|
||||
|
||||
@@ -13,5 +13,6 @@ pub struct BlockTimestamp {
|
||||
pub hash: BlockHash,
|
||||
|
||||
/// Block timestamp in ISO 8601 format
|
||||
#[schemars(example = &"2024-04-20T00:00:00.000Z")]
|
||||
pub timestamp: String,
|
||||
}
|
||||
|
||||
@@ -13,8 +13,10 @@ pub struct DifficultyAdjustmentEntry {
|
||||
/// Block height of the adjustment
|
||||
pub height: Height,
|
||||
/// Difficulty value
|
||||
#[schemars(example = 110_451_832_649_830.94)]
|
||||
pub difficulty: f64,
|
||||
/// Adjustment ratio (new/previous, e.g. 1.068 = +6.8%)
|
||||
#[schemars(example = 1.068)]
|
||||
pub change_percent: f64,
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,9 @@ pub struct DifficultyEntry {
|
||||
/// Block height of the adjustment
|
||||
pub height: Height,
|
||||
/// Difficulty value
|
||||
#[schemars(example = 110_451_832_649_830.94)]
|
||||
pub difficulty: f64,
|
||||
/// Adjustment ratio (new/previous, e.g. 1.068 = +6.8%)
|
||||
#[schemars(example = 1.068)]
|
||||
pub adjustment: f64,
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@ use crate::{Cents, Low, Open};
|
||||
|
||||
use super::{Bitcoin, CentsSigned, Close, High, Sats, StoredF32, StoredF64};
|
||||
|
||||
/// US Dollar amount as floating point
|
||||
/// US Dollar amount
|
||||
#[derive(Debug, Default, Clone, Copy, Deref, Serialize, Deserialize, Pco, JsonSchema)]
|
||||
#[schemars(example = 0.0, example = 100.50, example = 30_000.0, example = 69_000.0, example = 84_342.12)]
|
||||
pub struct Dollars(f64);
|
||||
|
||||
impl Hash for Dollars {
|
||||
|
||||
@@ -9,8 +9,9 @@ use vecdb::{CheckedSub, Formattable, Pco};
|
||||
|
||||
use super::{Sats, VSize, Weight};
|
||||
|
||||
/// Fee rate in sats/vB
|
||||
/// Fee rate in sat/vB
|
||||
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Pco, JsonSchema)]
|
||||
#[schemars(example = 1.0, example = 2.5, example = 10.14, example = 25.0, example = 302.11)]
|
||||
pub struct FeeRate(f64);
|
||||
|
||||
impl FeeRate {
|
||||
|
||||
@@ -6,18 +6,25 @@ use super::FeeRate;
|
||||
/// Fee rate percentiles (min, 10%, 25%, 50%, 75%, 90%, max).
|
||||
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct FeeRatePercentiles {
|
||||
/// Minimum fee rate (sat/vB)
|
||||
#[serde(rename = "avgFee_0")]
|
||||
pub min: FeeRate,
|
||||
/// 10th percentile fee rate (sat/vB)
|
||||
#[serde(rename = "avgFee_10")]
|
||||
pub pct10: FeeRate,
|
||||
/// 25th percentile fee rate (sat/vB)
|
||||
#[serde(rename = "avgFee_25")]
|
||||
pub pct25: FeeRate,
|
||||
/// Median fee rate (sat/vB)
|
||||
#[serde(rename = "avgFee_50")]
|
||||
pub median: FeeRate,
|
||||
/// 75th percentile fee rate (sat/vB)
|
||||
#[serde(rename = "avgFee_75")]
|
||||
pub pct75: FeeRate,
|
||||
/// 90th percentile fee rate (sat/vB)
|
||||
#[serde(rename = "avgFee_90")]
|
||||
pub pct90: FeeRate,
|
||||
/// Maximum fee rate (sat/vB)
|
||||
#[serde(rename = "avgFee_100")]
|
||||
pub max: FeeRate,
|
||||
}
|
||||
|
||||
@@ -6,9 +6,10 @@ use super::Timestamp;
|
||||
/// A single hashrate data point.
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct HashrateEntry {
|
||||
/// Unix timestamp.
|
||||
/// Unix timestamp
|
||||
pub timestamp: Timestamp,
|
||||
/// Average hashrate (H/s).
|
||||
/// Average hashrate (H/s)
|
||||
#[serde(rename = "avgHashrate")]
|
||||
#[schemars(example = 700_000_000_000_000_000_000_u128)]
|
||||
pub avg_hashrate: u128,
|
||||
}
|
||||
|
||||
@@ -6,14 +6,16 @@ use super::{DifficultyEntry, HashrateEntry};
|
||||
/// Summary of network hashrate and difficulty data.
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct HashrateSummary {
|
||||
/// Historical hashrate data points.
|
||||
/// Historical hashrate data points
|
||||
pub hashrates: Vec<HashrateEntry>,
|
||||
/// Historical difficulty adjustments.
|
||||
/// Historical difficulty adjustments
|
||||
pub difficulty: Vec<DifficultyEntry>,
|
||||
/// Current network hashrate (H/s).
|
||||
/// Current network hashrate (H/s)
|
||||
#[serde(rename = "currentHashrate")]
|
||||
#[schemars(example = 700_000_000_000_000_000_000_u128)]
|
||||
pub current_hashrate: u128,
|
||||
/// Current network difficulty.
|
||||
/// Current network difficulty
|
||||
#[serde(rename = "currentDifficulty")]
|
||||
#[schemars(example = 110_451_832_649_830.94)]
|
||||
pub current_difficulty: f64,
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ pub struct HistoricalPrice {
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct HistoricalPriceEntry {
|
||||
/// Unix timestamp
|
||||
pub time: u64,
|
||||
pub time: Timestamp,
|
||||
/// BTC/USD price
|
||||
#[serde(rename = "USD")]
|
||||
pub usd: Dollars,
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::{FeeRate, Sats, Transaction, VSize};
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct MempoolInfo {
|
||||
/// Number of transactions in the mempool
|
||||
#[schemars(example = 5000)]
|
||||
pub count: usize,
|
||||
/// Total virtual size of all transactions in the mempool (vbytes)
|
||||
pub vsize: VSize,
|
||||
|
||||
@@ -10,6 +10,7 @@ pub struct MerkleProof {
|
||||
pub block_height: Height,
|
||||
/// Merkle proof path (hex-encoded hashes)
|
||||
pub merkle: Vec<String>,
|
||||
/// Transaction position in the block
|
||||
/// Transaction position in the block (0-indexed)
|
||||
#[schemars(example = 42)]
|
||||
pub pos: usize,
|
||||
}
|
||||
|
||||
@@ -19,11 +19,12 @@ pub struct PoolDetail {
|
||||
#[serde(rename = "blockShare")]
|
||||
pub block_share: PoolBlockShares,
|
||||
|
||||
/// Estimated hashrate based on blocks mined
|
||||
/// Estimated hashrate based on blocks mined (H/s)
|
||||
#[serde(rename = "estimatedHashrate")]
|
||||
#[schemars(example = 200_000_000_000_000_000_000_u128)]
|
||||
pub estimated_hashrate: u128,
|
||||
|
||||
/// Self-reported hashrate (if available)
|
||||
/// Self-reported hashrate (if available, H/s)
|
||||
#[serde(rename = "reportedHashrate")]
|
||||
pub reported_hashrate: Option<u128>,
|
||||
|
||||
@@ -36,12 +37,15 @@ pub struct PoolDetail {
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct PoolDetailInfo {
|
||||
/// Pool identifier
|
||||
#[schemars(example = 111)]
|
||||
pub id: u8,
|
||||
|
||||
/// Pool name
|
||||
#[schemars(example = &"Foundry USA")]
|
||||
pub name: Cow<'static, str>,
|
||||
|
||||
/// Pool website URL
|
||||
#[schemars(example = &"https://foundrydigital.com/")]
|
||||
pub link: Cow<'static, str>,
|
||||
|
||||
/// Known payout addresses
|
||||
@@ -54,6 +58,7 @@ pub struct PoolDetailInfo {
|
||||
pub slug: PoolSlug,
|
||||
|
||||
/// Unique pool identifier
|
||||
#[schemars(example = 44)]
|
||||
pub unique_id: u8,
|
||||
}
|
||||
|
||||
@@ -75,14 +80,17 @@ impl From<&'static Pool> for PoolDetailInfo {
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct PoolBlockCounts {
|
||||
/// Total blocks mined (all time)
|
||||
#[schemars(example = 75000)]
|
||||
pub all: u64,
|
||||
|
||||
/// Blocks mined in last 24 hours
|
||||
#[serde(rename = "24h")]
|
||||
#[schemars(example = 42)]
|
||||
pub day: u64,
|
||||
|
||||
/// Blocks mined in last week
|
||||
#[serde(rename = "1w")]
|
||||
#[schemars(example = 280)]
|
||||
pub week: u64,
|
||||
}
|
||||
|
||||
@@ -90,13 +98,16 @@ pub struct PoolBlockCounts {
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct PoolBlockShares {
|
||||
/// Share of all blocks (0.0 - 1.0)
|
||||
#[schemars(example = 0.28)]
|
||||
pub all: f64,
|
||||
|
||||
/// Share of blocks in last 24 hours
|
||||
/// Share of blocks in last 24 hours (0.0 - 1.0)
|
||||
#[serde(rename = "24h")]
|
||||
#[schemars(example = 0.30)]
|
||||
pub day: f64,
|
||||
|
||||
/// Share of blocks in last week
|
||||
/// Share of blocks in last week (0.0 - 1.0)
|
||||
#[serde(rename = "1w")]
|
||||
#[schemars(example = 0.29)]
|
||||
pub week: f64,
|
||||
}
|
||||
|
||||
@@ -6,14 +6,17 @@ use super::Timestamp;
|
||||
/// A single pool hashrate data point.
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct PoolHashrateEntry {
|
||||
/// Unix timestamp.
|
||||
/// Unix timestamp
|
||||
pub timestamp: Timestamp,
|
||||
/// Average hashrate (H/s).
|
||||
/// Average hashrate (H/s)
|
||||
#[serde(rename = "avgHashrate")]
|
||||
#[schemars(example = 200_000_000_000_000_000_000_u128)]
|
||||
pub avg_hashrate: u128,
|
||||
/// Pool's share of total network hashrate.
|
||||
/// Pool's share of total network hashrate (0.0 - 1.0)
|
||||
#[schemars(example = 0.30)]
|
||||
pub share: f64,
|
||||
/// Pool name.
|
||||
/// Pool name
|
||||
#[serde(rename = "poolName")]
|
||||
#[schemars(example = &"Foundry USA")]
|
||||
pub pool_name: String,
|
||||
}
|
||||
|
||||
@@ -9,12 +9,14 @@ use crate::{Pool, PoolSlug};
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct PoolInfo {
|
||||
/// Pool name
|
||||
#[schemars(example = &"Foundry USA")]
|
||||
pub name: Cow<'static, str>,
|
||||
|
||||
/// URL-friendly pool identifier
|
||||
pub slug: PoolSlug,
|
||||
|
||||
/// Unique numeric pool identifier
|
||||
#[schemars(example = 44)]
|
||||
pub unique_id: u8,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
||||
use strum::Display;
|
||||
use vecdb::{Bytes, Formattable};
|
||||
|
||||
// Slug of a mining pool
|
||||
/// URL-friendly mining pool identifier
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(
|
||||
Default,
|
||||
|
||||
@@ -10,33 +10,41 @@ use crate::{Pool, PoolSlug};
|
||||
pub struct PoolStats {
|
||||
/// Unique pool identifier
|
||||
#[serde(rename = "poolId")]
|
||||
#[schemars(example = 111)]
|
||||
pub pool_id: u8,
|
||||
|
||||
/// Pool name
|
||||
#[schemars(example = &"Foundry USA")]
|
||||
pub name: Cow<'static, str>,
|
||||
|
||||
/// Pool website URL
|
||||
#[schemars(example = &"https://foundrydigital.com/")]
|
||||
pub link: Cow<'static, str>,
|
||||
|
||||
/// Number of blocks mined in the time period
|
||||
#[serde(rename = "blockCount")]
|
||||
#[schemars(example = 42)]
|
||||
pub block_count: u64,
|
||||
|
||||
/// Pool ranking by block count (1 = most blocks)
|
||||
#[schemars(example = 1)]
|
||||
pub rank: u32,
|
||||
|
||||
/// Number of empty blocks mined
|
||||
#[serde(rename = "emptyBlocks")]
|
||||
#[schemars(example = 0)]
|
||||
pub empty_blocks: u64,
|
||||
|
||||
/// URL-friendly pool identifier
|
||||
pub slug: PoolSlug,
|
||||
|
||||
/// Pool's share of total blocks (0.0 - 1.0)
|
||||
#[schemars(example = 0.30)]
|
||||
pub share: f64,
|
||||
|
||||
/// Unique pool identifier
|
||||
#[serde(rename = "poolUniqueId")]
|
||||
#[schemars(example = 44)]
|
||||
pub pool_unique_id: u8,
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,15 @@ pub struct PoolsSummary {
|
||||
/// List of pools sorted by block count descending
|
||||
pub pools: Vec<PoolStats>,
|
||||
/// Total blocks in the time period
|
||||
#[schemars(example = 144)]
|
||||
pub block_count: u64,
|
||||
/// Estimated network hashrate (hashes per second)
|
||||
/// Estimated network hashrate (H/s)
|
||||
#[schemars(example = 700_000_000_000_000_000_000_u128)]
|
||||
pub last_estimated_hashrate: u128,
|
||||
/// Estimated network hashrate over last 3 days
|
||||
/// Estimated network hashrate over last 3 days (H/s)
|
||||
#[schemars(example = 700_000_000_000_000_000_000_u128)]
|
||||
pub last_estimated_hashrate3d: u128,
|
||||
/// Estimated network hashrate over last 1 week
|
||||
/// Estimated network hashrate over last 1 week (H/s)
|
||||
#[schemars(example = 700_000_000_000_000_000_000_u128)]
|
||||
pub last_estimated_hashrate1w: u128,
|
||||
}
|
||||
|
||||
@@ -3,8 +3,9 @@ use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{Formattable, Pco};
|
||||
|
||||
/// Transaction locktime
|
||||
/// Transaction locktime. Values below 500,000,000 are interpreted as block heights; values at or above are Unix timestamps.
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Pco, JsonSchema)]
|
||||
#[schemars(example = 0, example = 840000, example = 840001, example = 1713571200, example = 4294967295_u32)]
|
||||
pub struct RawLockTime(u32);
|
||||
|
||||
impl From<LockTime> for RawLockTime {
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::StoredF64;
|
||||
|
||||
use super::{Bitcoin, Cents, Dollars, Height};
|
||||
|
||||
/// Satoshis
|
||||
/// Amount in satoshis (1 BTC = 100,000,000 sats)
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
@@ -30,6 +30,13 @@ use super::{Bitcoin, Cents, Dollars, Height};
|
||||
Pco,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[schemars(
|
||||
example = 0,
|
||||
example = 546,
|
||||
example = 10000,
|
||||
example = 100_000_000,
|
||||
example = 2_100_000_000_000_000_u64
|
||||
)]
|
||||
pub struct Sats(u64);
|
||||
|
||||
#[allow(clippy::inconsistent_digit_grouping)]
|
||||
|
||||
@@ -24,7 +24,13 @@ use super::Date;
|
||||
Pco,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[schemars(example = 1672531200)]
|
||||
#[schemars(
|
||||
example = 1231006505,
|
||||
example = 1672531200,
|
||||
example = 1713571200,
|
||||
example = 1743631892,
|
||||
example = 1759000868
|
||||
)]
|
||||
pub struct Timestamp(u32);
|
||||
|
||||
pub const ONE_HOUR_IN_SEC: u32 = 60 * 60;
|
||||
|
||||
@@ -8,6 +8,7 @@ use vecdb::{CheckedSub, Formattable, Pco, PrintableIndex};
|
||||
|
||||
use super::StoredU32;
|
||||
|
||||
/// Transaction index within a block (0 = coinbase)
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
@@ -25,6 +26,7 @@ use super::StoredU32;
|
||||
JsonSchema,
|
||||
Hash,
|
||||
)]
|
||||
#[schemars(example = 0)]
|
||||
pub struct TxIndex(u32);
|
||||
|
||||
impl TxIndex {
|
||||
|
||||
@@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// Unlike TxVersion (u8, indexed), this preserves non-standard values
|
||||
/// used in coinbase txs for miner signaling/branding.
|
||||
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[schemars(example = 1, example = 2, example = 3, example = 536_870_912, example = 805_306_368)]
|
||||
pub struct TxVersionRaw(i32);
|
||||
|
||||
impl From<bitcoin::transaction::Version> for TxVersionRaw {
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::{Height, TxStatus, Txid, Vin};
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct TxOutspend {
|
||||
/// Whether the output has been spent
|
||||
#[schemars(example = true)]
|
||||
pub spent: bool,
|
||||
|
||||
/// Transaction ID of the spending transaction (only present if spent)
|
||||
|
||||
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(
|
||||
Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
|
||||
)]
|
||||
#[schemars(example = 0)]
|
||||
#[schemars(example = 0, example = 1, example = 2, example = 5, example = 10)]
|
||||
pub struct Vin(u16);
|
||||
|
||||
impl Vin {
|
||||
|
||||
@@ -20,7 +20,7 @@ use vecdb::{Bytes, Formattable};
|
||||
Bytes,
|
||||
Hash,
|
||||
)]
|
||||
#[schemars(example = 0)]
|
||||
#[schemars(example = 0, example = 1, example = 2, example = 5, example = 10)]
|
||||
pub struct Vout(u16);
|
||||
|
||||
impl Vout {
|
||||
|
||||
@@ -7,7 +7,7 @@ use vecdb::{CheckedSub, Formattable, Pco};
|
||||
|
||||
use crate::Weight;
|
||||
|
||||
/// Virtual size in vbytes (weight / 4, rounded up)
|
||||
/// Virtual size in vbytes (weight / 4, rounded up). Max block vsize is ~1,000,000 vB.
|
||||
#[derive(
|
||||
Debug,
|
||||
Default,
|
||||
@@ -23,6 +23,7 @@ use crate::Weight;
|
||||
Pco,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[schemars(example = 110, example = 140, example = 225, example = 500_000, example = 998_368)]
|
||||
pub struct VSize(u64);
|
||||
|
||||
impl VSize {
|
||||
|
||||
@@ -7,7 +7,7 @@ use vecdb::{CheckedSub, Formattable, Pco};
|
||||
|
||||
use crate::VSize;
|
||||
|
||||
/// Transaction or block weight in weight units (WU)
|
||||
/// Weight in weight units (WU). Max block weight is 4,000,000 WU.
|
||||
#[derive(
|
||||
Debug,
|
||||
Default,
|
||||
@@ -23,6 +23,7 @@ use crate::VSize;
|
||||
Pco,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[schemars(example = 396, example = 561, example = 900, example = 2_000_000, example = 3_993_472)]
|
||||
pub struct Weight(u64);
|
||||
|
||||
impl Weight {
|
||||
|
||||
Reference in New Issue
Block a user