templar_common/oracle/
pyth.rs

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