templar_common/oracle/pyth.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
//! Derived from <https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near>.
//! Modified for use with the Templar Protocol contracts.
//!
//! The original code was released under the following license:
//!
//! Copyright 2025 Pyth Data Association.
//!
//! Licensed under the Apache License, Version 2.0 (the "License");
//! you may not use this file except in compliance with the License.
//! You may obtain a copy of the License at
//!
//! http://www.apache.org/licenses/LICENSE-2.0
//!
//! Unless required by applicable law or agreed to in writing, software
//! distributed under the License is distributed on an "AS IS" BASIS,
//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//! See the License for the specific language governing permissions and
//! limitations under the License.
use std::{collections::HashMap, fmt::Display};
use near_sdk::{
ext_contract,
json_types::{I64, U64},
near,
};
pub type OracleResponse = HashMap<PriceIdentifier, Option<Price>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[near(serializers = [borsh, json])]
pub struct PriceIdentifier(
#[serde(
serialize_with = "hex::serde::serialize",
deserialize_with = "hex::serde::deserialize"
)]
pub [u8; 32],
);
impl Display for PriceIdentifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", hex::encode(self.0))
}
}
/// A price with a degree of uncertainty, represented as a price +- a confidence interval.
///
/// The confidence interval roughly corresponds to the standard error of a normal distribution.
/// Both the price and confidence are stored in a fixed-point numeric representation,
/// `x * (10^expo)`, where `expo` is the exponent.
//
/// Please refer to the documentation at
/// <https://docs.pyth.network/documentation/pythnet-price-feeds/best-practices>
/// for how to use this price safely.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[near(serializers = [json, borsh])]
pub struct Price {
pub price: I64,
/// Confidence interval around the price
pub conf: U64,
/// The exponent
pub expo: i32,
/// Unix timestamp of when this price was computed
pub publish_time: i64,
}
#[ext_contract(ext_pyth)]
pub trait Pyth {
// See implementations for details, PriceIdentifier can be passed either as a 64 character
// hex price ID which can be found on the Pyth homepage.
fn price_feed_exists(&self, price_identifier: PriceIdentifier) -> bool;
// fn get_price(&self, price_identifier: PriceIdentifier) -> Option<Price>;
// fn get_price_unsafe(&self, price_identifier: PriceIdentifier) -> Option<Price>;
// fn get_price_no_older_than(&self, price_id: PriceIdentifier, age: u64) -> Option<Price>;
// fn get_ema_price(&self, price_id: PriceIdentifier) -> Option<Price>;
// fn get_ema_price_unsafe(&self, price_id: PriceIdentifier) -> Option<Price>;
// fn get_ema_price_no_older_than(&self, price_id: PriceIdentifier, age: u64) -> Option<Price>;
// fn list_prices(
// &self,
// price_ids: Vec<PriceIdentifier>,
// ) -> HashMap<PriceIdentifier, Option<Price>>;
// fn list_prices_unsafe(
// &self,
// price_ids: Vec<PriceIdentifier>,
// ) -> HashMap<PriceIdentifier, Option<Price>>;
// fn list_prices_no_older_than(
// &self,
// price_ids: Vec<PriceIdentifier>,
// ) -> HashMap<PriceIdentifier, Option<Price>>;
// fn list_ema_prices(
// &self,
// price_ids: Vec<PriceIdentifier>,
// ) -> HashMap<PriceIdentifier, Option<Price>>;
// fn list_ema_prices_unsafe(
// &self,
// price_ids: Vec<PriceIdentifier>,
// ) -> HashMap<PriceIdentifier, Option<Price>>;
fn list_ema_prices_no_older_than(
&self,
price_ids: Vec<PriceIdentifier>,
age: u64,
) -> HashMap<PriceIdentifier, Option<Price>>;
}