templar_common/market/
price_oracle_configuration.rs1use near_sdk::{near, AccountId, Gas, Promise};
2
3use crate::{
4 oracle::pyth::{ext_pyth, OracleResponse, PriceIdentifier},
5 price::PricePair,
6};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
13#[near(serializers = [json, borsh])]
14pub struct PriceOracleConfiguration {
15 pub account_id: AccountId,
17 pub collateral_asset_price_id: PriceIdentifier,
19 pub collateral_asset_decimals: i32,
21 pub borrow_asset_price_id: PriceIdentifier,
23 pub borrow_asset_decimals: i32,
25 pub price_maximum_age_s: u32,
28}
29
30impl PriceOracleConfiguration {
31 pub const GAS_RETRIEVE_PRICE_PAIR: Gas = Gas::from_tgas(15);
33
34 pub fn retrieve_price_pair(&self) -> Promise {
35 ext_pyth::ext(self.account_id.clone())
36 .with_static_gas(Self::GAS_RETRIEVE_PRICE_PAIR)
37 .list_ema_prices_no_older_than(
38 vec![self.borrow_asset_price_id, self.collateral_asset_price_id],
39 u64::from(self.price_maximum_age_s),
40 )
41 }
42
43 pub fn create_price_pair(
48 &self,
49 oracle_response: &OracleResponse,
50 ) -> Result<PricePair, error::RetrievalError> {
51 Ok(PricePair::new(
52 oracle_response
53 .get(&self.collateral_asset_price_id)
54 .and_then(|o| o.as_ref())
55 .ok_or(error::RetrievalError::MissingPrice)?,
56 self.collateral_asset_decimals,
57 oracle_response
58 .get(&self.borrow_asset_price_id)
59 .and_then(|o| o.as_ref())
60 .ok_or(error::RetrievalError::MissingPrice)?,
61 self.borrow_asset_decimals,
62 )?)
63 }
64}
65
66pub mod error {
67 use thiserror::Error;
68
69 #[derive(Clone, Debug, Error)]
70 #[error("Error retrieving price: {0}")]
71 pub enum RetrievalError {
72 #[error("Missing price")]
73 MissingPrice,
74 #[error(transparent)]
75 PriceData(#[from] crate::price::error::PriceDataError),
76 }
77}