penumbra_sdk_asset/
estimated_price.rs

1use crate::asset;
2use penumbra_sdk_proto::{penumbra::core::asset::v1 as pb, DomainType};
3use serde::{Deserialize, Serialize};
4
5/// The estimated price of one asset in terms of another.
6///
7/// This is used to generate an [`EquivalentValue`](crate::EquivalentValue)
8/// that may be helpful in interpreting a [`Value`](crate::Value).
9#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
10#[serde(try_from = "pb::EstimatedPrice", into = "pb::EstimatedPrice")]
11
12pub struct EstimatedPrice {
13    /// The asset that is being priced.
14    pub priced_asset: asset::Id,
15    /// The numeraire that the price is being expressed in.
16    pub numeraire: asset::Id,
17    /// Multiply units of the priced asset by this number to get the value in the numeraire.
18    ///
19    /// This is a floating-point number since the price is approximate.
20    pub numeraire_per_unit: f64,
21    /// If nonzero, gives some idea of when the price was estimated (in terms of block height).
22    pub as_of_height: u64,
23}
24
25impl DomainType for EstimatedPrice {
26    type Proto = pb::EstimatedPrice;
27}
28
29impl From<EstimatedPrice> for pb::EstimatedPrice {
30    fn from(msg: EstimatedPrice) -> Self {
31        Self {
32            priced_asset: Some(msg.priced_asset.into()),
33            numeraire: Some(msg.numeraire.into()),
34            numeraire_per_unit: msg.numeraire_per_unit,
35            as_of_height: msg.as_of_height,
36        }
37    }
38}
39
40impl TryFrom<pb::EstimatedPrice> for EstimatedPrice {
41    type Error = anyhow::Error;
42
43    fn try_from(msg: pb::EstimatedPrice) -> Result<Self, Self::Error> {
44        Ok(Self {
45            priced_asset: msg
46                .priced_asset
47                .ok_or_else(|| anyhow::anyhow!("missing priced asset"))?
48                .try_into()?,
49            numeraire: msg
50                .numeraire
51                .ok_or_else(|| anyhow::anyhow!("missing numeraire"))?
52                .try_into()?,
53            numeraire_per_unit: msg.numeraire_per_unit,
54            as_of_height: msg.as_of_height,
55        })
56    }
57}