mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-19 23:18:10 -07:00
server: moved params from brk_types
This commit is contained in:
@@ -5,12 +5,13 @@ use axum::{
|
||||
response::Redirect,
|
||||
routing::get,
|
||||
};
|
||||
use brk_types::{
|
||||
AddrParam, AddrStats, AddrTxidsParam, AddrValidation, Transaction, Txid, Utxo,
|
||||
ValidateAddrParam, Version,
|
||||
};
|
||||
use brk_types::{AddrStats, AddrValidation, Transaction, Txid, Utxo, Version};
|
||||
|
||||
use crate::{AppState, CacheStrategy, extended::TransformResponseExtended};
|
||||
use crate::{
|
||||
AppState, CacheStrategy,
|
||||
extended::TransformResponseExtended,
|
||||
params::{AddrParam, AddrTxidsParam, ValidateAddrParam},
|
||||
};
|
||||
|
||||
pub trait AddrRoutes {
|
||||
fn add_addr_routes(self) -> Self;
|
||||
|
||||
@@ -4,12 +4,13 @@ use axum::{
|
||||
http::{HeaderMap, Uri},
|
||||
};
|
||||
use brk_query::BLOCK_TXS_PAGE_SIZE;
|
||||
use brk_types::{
|
||||
BlockHashParam, BlockHashStartIndex, BlockHashTxIndex, BlockInfo, BlockInfoV1, BlockStatus,
|
||||
BlockTimestamp, HeightParam, TimestampParam, Transaction, TxIndex, Txid, Version,
|
||||
};
|
||||
use brk_types::{BlockInfo, BlockInfoV1, BlockStatus, BlockTimestamp, Transaction, TxIndex, Txid, Version};
|
||||
|
||||
use crate::{AppState, CacheStrategy, extended::TransformResponseExtended};
|
||||
use crate::{
|
||||
AppState, CacheStrategy,
|
||||
extended::TransformResponseExtended,
|
||||
params::{BlockHashParam, BlockHashStartIndex, BlockHashTxIndex, HeightParam, TimestampParam},
|
||||
};
|
||||
|
||||
pub trait BlockRoutes {
|
||||
fn add_block_routes(self) -> Self;
|
||||
|
||||
@@ -3,9 +3,13 @@ use axum::{
|
||||
extract::{Query, State},
|
||||
http::{HeaderMap, Uri},
|
||||
};
|
||||
use brk_types::{DifficultyAdjustment, HistoricalPrice, OptionalTimestampParam, Prices, Timestamp};
|
||||
use brk_types::{DifficultyAdjustment, HistoricalPrice, Prices, Timestamp};
|
||||
|
||||
use crate::{AppState, CacheStrategy, extended::TransformResponseExtended};
|
||||
use crate::{
|
||||
AppState, CacheStrategy,
|
||||
extended::TransformResponseExtended,
|
||||
params::OptionalTimestampParam,
|
||||
};
|
||||
|
||||
pub trait GeneralRoutes {
|
||||
fn add_general_routes(self) -> Self;
|
||||
|
||||
@@ -6,12 +6,16 @@ use axum::{
|
||||
routing::get,
|
||||
};
|
||||
use brk_types::{
|
||||
BlockCountParam, BlockFeesEntry, BlockInfoV1, BlockRewardsEntry, BlockSizesWeights,
|
||||
BlockFeesEntry, BlockInfoV1, BlockRewardsEntry, BlockSizesWeights,
|
||||
DifficultyAdjustmentEntry, HashrateSummary, PoolDetail, PoolHashrateEntry, PoolInfo,
|
||||
PoolSlugAndHeightParam, PoolSlugParam, PoolsSummary, RewardStats, TimePeriodParam,
|
||||
PoolsSummary, RewardStats,
|
||||
};
|
||||
|
||||
use crate::{AppState, CacheStrategy, Error, extended::TransformResponseExtended};
|
||||
use crate::{
|
||||
AppState, CacheStrategy, Error,
|
||||
extended::TransformResponseExtended,
|
||||
params::{BlockCountParam, PoolSlugAndHeightParam, PoolSlugParam, TimePeriodParam},
|
||||
};
|
||||
|
||||
pub trait MiningRoutes {
|
||||
fn add_mining_routes(self) -> Self;
|
||||
|
||||
@@ -6,12 +6,13 @@ use axum::{
|
||||
extract::{Path, State},
|
||||
http::{HeaderMap, Uri},
|
||||
};
|
||||
use brk_types::{
|
||||
CpfpInfo, MerkleProof, Transaction, TxOutspend, TxStatus, Txid, TxidParam, TxidVout,
|
||||
TxidsParam, Version,
|
||||
};
|
||||
use brk_types::{CpfpInfo, MerkleProof, Transaction, TxOutspend, TxStatus, Txid, Version};
|
||||
|
||||
use crate::{AppState, CacheStrategy, extended::TransformResponseExtended};
|
||||
use crate::{
|
||||
AppState, CacheStrategy,
|
||||
extended::TransformResponseExtended,
|
||||
params::{TxidParam, TxidVout, TxidsParam},
|
||||
};
|
||||
|
||||
pub trait TxRoutes {
|
||||
fn add_tx_routes(self) -> Self;
|
||||
@@ -24,7 +25,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/cpfp/{txid}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.cpfp(param)).await
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.cpfp(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_cpfp")
|
||||
@@ -45,7 +46,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
Path(param): Path<TxidParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction(param)).await
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx")
|
||||
@@ -67,10 +68,10 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
async |
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Path(txid): Path<TxidParam>,
|
||||
Path(param): Path<TxidParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_text(&headers, state.tx_cache(Version::ONE, &txid.txid), &uri, move |q| q.transaction_hex(txid)).await
|
||||
state.cached_text(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_hex(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_hex")
|
||||
@@ -89,8 +90,8 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/tx/{txid}/merkleblock-proof",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(txid): Path<TxidParam>, State(state): State<AppState>| {
|
||||
state.cached_text(&headers, state.tx_cache(Version::ONE, &txid.txid), &uri, move |q| q.merkleblock_proof(txid)).await
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, State(state): State<AppState>| {
|
||||
state.cached_text(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.merkleblock_proof(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_merkleblock_proof")
|
||||
@@ -107,8 +108,8 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/tx/{txid}/merkle-proof",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(txid): Path<TxidParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, &txid.txid), &uri, move |q| q.merkle_proof(txid)).await
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.merkle_proof(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_merkle_proof")
|
||||
@@ -131,8 +132,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
Path(path): Path<TxidVout>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let txid = TxidParam { txid: path.txid };
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.outspend(txid, path.vout)).await
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.outspend(&path.txid, path.vout)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_outspend")
|
||||
@@ -154,10 +154,10 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
async |
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Path(txid): Path<TxidParam>,
|
||||
Path(param): Path<TxidParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.outspends(txid)).await
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.outspends(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_outspends")
|
||||
@@ -176,8 +176,8 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/tx/{txid}/raw",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(txid): Path<TxidParam>, State(state): State<AppState>| {
|
||||
state.cached_bytes(&headers, state.tx_cache(Version::ONE, &txid.txid), &uri, move |q| q.transaction_raw(txid)).await
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, State(state): State<AppState>| {
|
||||
state.cached_bytes(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_raw(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_raw")
|
||||
@@ -200,7 +200,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
Path(param): Path<TxidParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_status(param)).await
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_status(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_status")
|
||||
|
||||
@@ -9,10 +9,12 @@ use axum::{
|
||||
};
|
||||
use brk_traversable::TreeNode;
|
||||
use brk_types::{
|
||||
CostBasisCohortParam, CostBasisFormatted, CostBasisParams, CostBasisQuery, DataRangeFormat,
|
||||
Date, DetailedSeriesCount, Index, IndexInfo, PaginatedSeries, Pagination, SearchQuery,
|
||||
SeriesData, SeriesInfo, SeriesList, SeriesName, SeriesSelection, SeriesSelectionLegacy,
|
||||
CostBasisFormatted, DataRangeFormat, Date, DetailedSeriesCount, Index, IndexInfo,
|
||||
PaginatedSeries, Pagination, SearchQuery, SeriesData, SeriesInfo, SeriesList, SeriesName,
|
||||
SeriesSelection, SeriesSelectionLegacy,
|
||||
};
|
||||
|
||||
use crate::params::{CostBasisCohortParam, CostBasisParams, CostBasisQuery};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
@@ -9,12 +9,15 @@ use axum::{
|
||||
};
|
||||
use brk_traversable::TreeNode;
|
||||
use brk_types::{
|
||||
CostBasisCohortParam, CostBasisFormatted, CostBasisParams, CostBasisQuery, DataRangeFormat,
|
||||
Date, IndexInfo, PaginatedSeries, Pagination, SearchQuery, SeriesCount, SeriesData, SeriesInfo,
|
||||
SeriesNameWithIndex, SeriesParam, SeriesSelection,
|
||||
CostBasisFormatted, DataRangeFormat, Date, IndexInfo, PaginatedSeries, Pagination, SearchQuery,
|
||||
SeriesCount, SeriesData, SeriesInfo, SeriesNameWithIndex, SeriesSelection,
|
||||
};
|
||||
|
||||
use crate::{CacheStrategy, extended::TransformResponseExtended};
|
||||
use crate::{
|
||||
CacheStrategy,
|
||||
extended::TransformResponseExtended,
|
||||
params::{CostBasisCohortParam, CostBasisParams, CostBasisQuery, SeriesParam},
|
||||
};
|
||||
|
||||
use super::AppState;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ mod api;
|
||||
pub mod cache;
|
||||
mod error;
|
||||
mod extended;
|
||||
pub mod params;
|
||||
mod state;
|
||||
|
||||
pub use api::ApiRoutes;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::Addr;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct AddrParam {
|
||||
#[serde(rename = "address")]
|
||||
pub addr: Addr,
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::Txid;
|
||||
|
||||
#[derive(Debug, Default, Deserialize, JsonSchema)]
|
||||
pub struct AddrTxidsParam {
|
||||
/// Txid to paginate from (return transactions before this one)
|
||||
pub after_txid: Option<Txid>,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct BlockCountParam {
|
||||
/// Number of recent blocks to include
|
||||
#[schemars(example = 100)]
|
||||
pub block_count: usize,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::BlockHash;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct BlockHashParam {
|
||||
pub hash: BlockHash,
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::{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,
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::{BlockHash, TxIndex};
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct BlockHashTxIndex {
|
||||
/// Bitcoin block hash
|
||||
pub hash: BlockHash,
|
||||
|
||||
/// Transaction index within the block (0-based)
|
||||
#[schemars(example = 0)]
|
||||
pub index: TxIndex,
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::{Cohort, CostBasisBucket, CostBasisValue, Date};
|
||||
|
||||
/// Path parameters for cost basis distribution endpoint.
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct CostBasisParams {
|
||||
pub cohort: Cohort,
|
||||
#[schemars(with = "String", example = &"2024-01-01")]
|
||||
pub date: Date,
|
||||
}
|
||||
|
||||
/// Path parameters for cost basis dates endpoint.
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct CostBasisCohortParam {
|
||||
pub cohort: Cohort,
|
||||
}
|
||||
|
||||
/// Query parameters for cost basis distribution endpoint.
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct CostBasisQuery {
|
||||
/// Bucket type for aggregation. Default: raw (no aggregation).
|
||||
#[serde(default)]
|
||||
pub bucket: CostBasisBucket,
|
||||
/// Value type to return. Default: supply.
|
||||
#[serde(default)]
|
||||
pub value: CostBasisValue,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::Height;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct HeightParam {
|
||||
pub height: Height,
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::Limit;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct LimitParam {
|
||||
#[serde(default)]
|
||||
pub limit: Limit,
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
mod addr_param;
|
||||
mod addr_txids_param;
|
||||
mod block_count_param;
|
||||
mod blockhash_param;
|
||||
mod blockhash_start_index;
|
||||
mod blockhash_tx_index;
|
||||
mod cost_basis_params;
|
||||
mod height_param;
|
||||
mod limit_param;
|
||||
mod pool_slug_param;
|
||||
mod series_param;
|
||||
mod time_period_param;
|
||||
mod timestamp_param;
|
||||
mod txid_param;
|
||||
mod txid_vout;
|
||||
mod txids_param;
|
||||
mod validate_addr_param;
|
||||
|
||||
pub use addr_param::*;
|
||||
pub use addr_txids_param::*;
|
||||
pub use block_count_param::*;
|
||||
pub use blockhash_param::*;
|
||||
pub use blockhash_start_index::*;
|
||||
pub use blockhash_tx_index::*;
|
||||
pub use cost_basis_params::*;
|
||||
pub use height_param::*;
|
||||
pub use limit_param::*;
|
||||
pub use pool_slug_param::*;
|
||||
pub use series_param::*;
|
||||
pub use time_period_param::*;
|
||||
pub use timestamp_param::*;
|
||||
pub use txid_param::*;
|
||||
pub use txid_vout::*;
|
||||
pub use txids_param::*;
|
||||
pub use validate_addr_param::*;
|
||||
@@ -0,0 +1,15 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::{Height, PoolSlug};
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct PoolSlugParam {
|
||||
pub slug: PoolSlug,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct PoolSlugAndHeightParam {
|
||||
pub slug: PoolSlug,
|
||||
pub height: Height,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::SeriesName;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct SeriesParam {
|
||||
pub series: SeriesName,
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::TimePeriod;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct TimePeriodParam {
|
||||
#[schemars(example = &"24h")]
|
||||
pub time_period: TimePeriod,
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::Timestamp;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct TimestampParam {
|
||||
pub timestamp: Timestamp,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct OptionalTimestampParam {
|
||||
pub timestamp: Option<Timestamp>,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::Txid;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct TxidParam {
|
||||
pub txid: Txid,
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::{Txid, Vout};
|
||||
|
||||
/// Transaction output reference (txid + output index)
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct TxidVout {
|
||||
/// Transaction ID
|
||||
pub txid: Txid,
|
||||
/// Output index
|
||||
pub vout: Vout,
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use schemars::JsonSchema;
|
||||
|
||||
use brk_types::Txid;
|
||||
|
||||
/// Query parameter for transaction-times endpoint.
|
||||
#[derive(JsonSchema)]
|
||||
pub struct TxidsParam {
|
||||
#[serde(rename = "txId[]")]
|
||||
pub txids: Vec<Txid>,
|
||||
}
|
||||
|
||||
impl TxidsParam {
|
||||
/// Parsed manually from URI since serde_urlencoded doesn't support repeated keys.
|
||||
pub fn from_query(query: &str) -> Self {
|
||||
Self {
|
||||
txids: query
|
||||
.split('&')
|
||||
.filter_map(|pair| {
|
||||
let (key, val) = pair.split_once('=')?;
|
||||
if key == "txId[]" || key == "txId%5B%5D" {
|
||||
Txid::from_str(val).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct ValidateAddrParam {
|
||||
/// Bitcoin address to validate (can be any string)
|
||||
#[schemars(
|
||||
example = &"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f",
|
||||
example = &"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
|
||||
example = &"not-a-valid-addr",
|
||||
example = &"bc1qinvalid"
|
||||
)]
|
||||
#[serde(rename = "address")]
|
||||
pub addr: String,
|
||||
}
|
||||
Reference in New Issue
Block a user