1use serde::Deserialize;
2use std::collections::HashMap;
3
4pub 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 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}