pyth_hermes_rs/
types.rs

1use serde::Deserialize;
2use std::collections::HashMap;
3
4/// URL of the public hermes api
5pub const PUBLIC_BASE_URL: &str = "https://hermes.pyth.network";
6
7#[derive(Debug, Deserialize)]
8pub struct RpcPriceFeed {
9    pub id: String,
10    pub price: RpcPrice,
11    pub ema_price: RpcPrice,
12    pub metadata: Option<RpcPriceFeedMetadata>,
13    pub vaa: Option<String>,
14}
15
16#[derive(Debug, Deserialize, Clone)]
17pub struct RpcPrice {
18    pub price: String,
19    pub conf: String,
20    pub expo: i32,
21    pub publish_time: i64,
22}
23
24#[derive(Debug, Deserialize, Clone)]
25pub struct RpcPriceFeedMetadata {
26    pub emitter_chain: Option<i32>,
27    pub prev_publish_time: Option<i64>,
28    pub price_service_receive_time: Option<i64>,
29    pub slot: Option<i64>,
30}
31
32#[derive(Debug, Deserialize)]
33pub struct PriceFeedMetadata {
34    pub id: String,
35    pub attributes: HashMap<String, String>,
36}
37
38#[derive(Debug, Deserialize)]
39pub struct PriceUpdate {
40    pub binary: BinaryUpdate,
41    pub parsed: Option<Vec<RpcPriceFeed>>,
42}
43
44#[derive(Debug, Deserialize)]
45pub struct BinaryUpdate {
46    pub encoding: String,
47    pub data: Vec<String>,
48}
49
50#[derive(Debug, Deserialize)]
51pub struct TwapsResponse {
52    pub binary: BinaryUpdate,
53    pub parsed: Option<Vec<ParsedPriceFeedTwap>>,
54}
55
56#[derive(Debug, Deserialize)]
57pub struct ParsedPriceFeedTwap {
58    pub id: String,
59    pub start_timestamp: i64,
60    pub end_timestamp: i64,
61    pub twap: RpcPrice,
62    pub down_slots_ratio: String,
63}
64
65#[derive(Debug, Deserialize)]
66pub struct LatestPublisherStakeCapsUpdateDataResponse {
67    pub binary: BinaryUpdate,
68    pub parsed: Option<Vec<ParsedPublisherStakeCapsUpdate>>,
69}
70
71#[derive(Debug, Deserialize)]
72pub struct ParsedPublisherStakeCapsUpdate {
73    pub publisher_stake_caps: Vec<ParsedPublisherStakeCap>,
74}
75
76#[derive(Debug, Deserialize)]
77pub struct ParsedPublisherStakeCap {
78    pub publisher: String,
79    pub cap: i64,
80}
81
82#[derive(Debug, Deserialize, Clone)]
83pub struct ParsedPriceUpdate {
84    pub id: String,
85    pub price: RpcPrice,
86    pub ema_price: RpcPrice,
87    pub metadata: RpcPriceFeedMetadata,
88}
89
90impl RpcPrice {
91    /// Converts the pyth reported price from an integer into a floating point
92    pub fn to_f64(&self) -> Option<f64> {
93        let price = self.price.parse::<u64>().ok()?;
94        Some(price as f64 / ((10_u64.pow(self.expo.unsigned_abs())) as f64))
95    }
96}
97
98#[cfg(test)]
99mod test {
100    use super::RpcPrice;
101
102    #[test]
103    fn test_rpc_price_to_f64() {
104        let price = RpcPrice {
105            price: "12971500000".to_string(),
106            conf: "6486733".to_string(),
107            expo: -8,
108            publish_time: 1744523548,
109        };
110        assert_eq!(price.to_f64().unwrap(), 129.715);
111        let price = RpcPrice {
112            price: "160644665033".to_string(),
113            conf: "73725033".to_string(),
114            expo: -8,
115            publish_time: 1744523627,
116        };
117        assert_eq!(price.to_f64().unwrap(), 1606.44665033)
118    }
119}