gmsol_sdk/serde/
serde_token_map.rs1use gmsol_utils::{
2 oracle::PriceProviderKind,
3 token_config::{FeedConfig, TokenConfig},
4};
5use indexmap::IndexMap;
6use strum::IntoEnumIterator;
7
8use crate::utils::Value;
9
10#[derive(Debug, Clone)]
12#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
13pub struct SerdeTokenConfig {
14 pub name: String,
16 pub is_enabled: bool,
18 pub is_synthetic: bool,
20 pub token_decimals: u8,
22 pub price_precision: u8,
24 pub expected_provider: PriceProviderKind,
26 pub feeds: IndexMap<PriceProviderKind, SerdeFeedConfig>,
28 pub heartbeat_duration: u32,
30}
31
32impl<'a> TryFrom<&'a TokenConfig> for SerdeTokenConfig {
33 type Error = crate::Error;
34
35 fn try_from(config: &'a TokenConfig) -> Result<Self, Self::Error> {
36 let feeds = PriceProviderKind::iter()
37 .filter_map(|kind| {
38 config
39 .get_feed_config(&kind)
40 .ok()
41 .map(|config| (kind, SerdeFeedConfig::from_feed_config(kind, config)))
42 })
43 .collect();
44 Ok(Self {
45 name: config.name().map_err(crate::Error::custom)?.to_string(),
46 is_enabled: config.is_enabled(),
47 is_synthetic: config.is_synthetic(),
48 token_decimals: config.token_decimals(),
49 price_precision: config.precision(),
50 expected_provider: config.expected_provider().map_err(crate::Error::custom)?,
51 feeds,
52 heartbeat_duration: config.heartbeat_duration(),
53 })
54 }
55}
56
57#[derive(Debug, Clone, Copy)]
59#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
60#[cfg_attr(serde, serde(rename_all = "snake_case"))]
61pub enum Encoding {
62 Hex,
64 Base58,
66}
67
68#[derive(Debug, Clone)]
70#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
71pub struct SerdeFeedConfig {
72 pub feed_id: String,
74 pub feed_id_encoding: Encoding,
76 pub timestamp_adjustment: u32,
78 #[cfg_attr(serde, serde(default))]
80 pub max_deviation_factor: Option<Value>,
81}
82
83impl SerdeFeedConfig {
84 pub fn from_feed_config(kind: PriceProviderKind, config: &FeedConfig) -> Self {
86 let max_deviation_factor = config.max_deviation_factor().map(Value::from_u128);
87 match kind {
88 PriceProviderKind::Pyth | PriceProviderKind::ChainlinkDataStreams => Self {
89 feed_id_encoding: Encoding::Hex,
90 feed_id: format!("0x{}", hex::encode(config.feed())),
91 timestamp_adjustment: config.timestamp_adjustment(),
92 max_deviation_factor,
93 },
94 _ => Self {
95 feed_id_encoding: Encoding::Base58,
96 feed_id: config.feed().to_string(),
97 timestamp_adjustment: config.timestamp_adjustment(),
98 max_deviation_factor,
99 },
100 }
101 }
102
103 pub fn formatted_feed_id(&self) -> String {
105 match self.feed_id_encoding {
106 Encoding::Hex => format!("0x{}", self.feed_id),
107 Encoding::Base58 => self.feed_id.clone(),
108 }
109 }
110}