Skip to content

Commit a98d36f

Browse files
committed
Add support for gettin ghistorical price
Signed-off-by: Yuki Kishimoto <yukikishimoto@protonmail.com>
1 parent 5bdd8d1 commit a98d36f

2 files changed

Lines changed: 110 additions & 10 deletions

File tree

src/client.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,38 @@ use crate::builder::MempoolClientBuilder;
99
use crate::error::Error;
1010
use crate::response::{
1111
AddressStats, BlockInfo, BlockInfoV1, DifficultyAdjustment, FeeRecommendations, HashrateStats,
12-
MempoolBlockFees, MempoolResponse, MempoolStats, Prices,
12+
HistoricalPrice, MempoolBlockFees, MempoolResponse, MempoolStats, Prices,
1313
};
1414
#[cfg(feature = "ws")]
1515
use crate::websocket::{self, MempoolSubscription, MempoolSubscriptionRequest};
1616

17+
/// Currency
18+
#[allow(missing_docs)]
19+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
20+
pub enum Currency {
21+
USD,
22+
EUR,
23+
GBP,
24+
CAD,
25+
CHF,
26+
AUD,
27+
JPY,
28+
}
29+
30+
impl Currency {
31+
fn as_str(&self) -> &str {
32+
match self {
33+
Self::USD => "USD",
34+
Self::EUR => "EUR",
35+
Self::GBP => "GBP",
36+
Self::CAD => "CAD",
37+
Self::CHF => "CHF",
38+
Self::AUD => "AUD",
39+
Self::JPY => "JPY",
40+
}
41+
}
42+
}
43+
1744
/// Hashrate time period
1845
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1946
pub enum HashratePeriod {
@@ -108,6 +135,22 @@ impl MempoolClient {
108135
self.get_response(url).await
109136
}
110137

138+
/// Get historical price
139+
pub async fn historical_price(
140+
&self,
141+
currency: Currency,
142+
timestamp: u64,
143+
) -> Result<HistoricalPrice, Error> {
144+
let mut url: Url = self.url.join("/api/v1/historical-price")?;
145+
146+
// Set query string
147+
let query: String = format!("currency={}&timestamp={timestamp}", currency.as_str());
148+
url.set_query(Some(&query));
149+
150+
// Get response
151+
self.get_response(url).await
152+
}
153+
111154
/// Get details about an address.
112155
pub async fn get_address(&self, address: &Address) -> Result<AddressStats, Error> {
113156
let url: Url = self

src/response.rs

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Responses
22
33
use std::cmp::Ordering;
4-
use std::collections::BTreeSet;
4+
use std::collections::{BTreeSet, HashMap};
55

66
use bitcoin::address::{Address, NetworkUnchecked};
77
use bitcoin::{Amount, BlockHash, FeeRate, TxMerkleNode, Weight};
@@ -32,32 +32,42 @@ impl<T> MempoolResponse<T> {
3232
}
3333

3434
/// Prices
35-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
35+
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Deserialize)]
3636
pub struct Prices {
3737
/// Timestamp
3838
#[serde(rename = "time")]
3939
pub timestamp: u64,
4040
/// USD
4141
#[serde(rename = "USD")]
42-
pub usd: u32,
42+
pub usd: f64,
4343
/// EUR
4444
#[serde(rename = "EUR")]
45-
pub eur: u32,
45+
pub eur: Option<f64>,
4646
/// GBP
4747
#[serde(rename = "GBP")]
48-
pub gbp: u32,
48+
pub gbp: Option<f64>,
4949
/// CAD
5050
#[serde(rename = "CAD")]
51-
pub cad: u32,
51+
pub cad: Option<f64>,
5252
/// CHF
5353
#[serde(rename = "CHF")]
54-
pub chf: u32,
54+
pub chf: Option<f64>,
5555
/// AUD
5656
#[serde(rename = "AUD")]
57-
pub aud: u32,
57+
pub aud: Option<f64>,
5858
/// JPY
5959
#[serde(rename = "JPY")]
60-
pub jpy: u32,
60+
pub jpy: Option<f64>,
61+
}
62+
63+
/// Historical price
64+
#[derive(Debug, Clone, PartialEq, Deserialize)]
65+
pub struct HistoricalPrice {
66+
/// Prices
67+
pub prices: Vec<Prices>,
68+
/// Exchange rates
69+
#[serde(rename = "exchangeRates")]
70+
pub rates: HashMap<String, f64>,
6171
}
6272

6373
/// Bitcoin difficulty adjustment information
@@ -881,4 +891,51 @@ mod tests {
881891
};
882892
assert_eq!(stats.avg_fee_rate(), FeeRate::from_sat_per_vb_unchecked(10));
883893
}
894+
895+
#[test]
896+
fn test_historical_price_deserialization() {
897+
let json = r#"{
898+
"prices": [
899+
{
900+
"time": 1499904000,
901+
"EUR": 1964,
902+
"USD": 2254.9
903+
}
904+
],
905+
"exchangeRates": {
906+
"USDEUR": 0.92,
907+
"USDGBP": 0.78,
908+
"USDCAD": 1.36,
909+
"USDCHF": 0.89,
910+
"USDAUD": 1.53,
911+
"USDJPY": 149.48
912+
}
913+
}
914+
"#;
915+
916+
let historical_price: HistoricalPrice = serde_json::from_str(json).unwrap();
917+
assert_eq!(
918+
historical_price,
919+
HistoricalPrice {
920+
prices: vec![Prices {
921+
timestamp: 1499904000,
922+
usd: 2254.9,
923+
eur: Some(1964.0),
924+
gbp: None,
925+
cad: None,
926+
chf: None,
927+
aud: None,
928+
jpy: None,
929+
}],
930+
rates: HashMap::from([
931+
("USDEUR".to_string(), 0.92),
932+
("USDGBP".to_string(), 0.78),
933+
("USDCAD".to_string(), 1.36),
934+
("USDCHF".to_string(), 0.89),
935+
("USDAUD".to_string(), 1.53),
936+
("USDJPY".to_string(), 149.48),
937+
]),
938+
}
939+
)
940+
}
884941
}

0 commit comments

Comments
 (0)