Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update price feed structure + cascade changes #77

Merged
merged 9 commits into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions examples/cw-contract/schema/fetch_price_response.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@
},
"definitions": {
"Price": {
"description": "A price with a degree of uncertainty, represented as a price +- a confidence interval.\n\nThe 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. For example:\n\n``` use pyth_sdk::Price; Price { price: 12345, conf: 267, expo: -2 }; // represents 123.45 +- 2.67 Price { price: 123, conf: 1, expo: 2 }; // represents 12300 +- 100 ```\n\n`Price` supports a limited set of mathematical operations. All of these operations will propagate any uncertainty in the arguments into the result. However, the uncertainty in the result may overestimate the true uncertainty (by at most a factor of `sqrt(2)`) due to computational limitations. Furthermore, all of these operations may return `None` if their result cannot be represented within the numeric representation (e.g., the exponent is so small that the price does not fit into an i64). Users of these methods should (1) select their exponents to avoid this problem, and (2) handle the `None` case gracefully.",
"description": "A price with a degree of uncertainty at a certain time, represented as a price +- a confidence interval.\n\nPlease refer to the documentation at https://docs.pyth.network/consumers/best-practices for using this price safely.\n\nThe 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. For example:\n\n``` use pyth_sdk::Price; Price { price: 12345, conf: 267, expo: -2, publish_time: 100 }; // represents 123.45 +- 2.67 published at UnixTimestamp 100 Price { price: 123, conf: 1, expo: 2, publish_time: 100 }; // represents 12300 +- 100 published at UnixTimestamp 100 ```\n\n`Price` supports a limited set of mathematical operations. All of these operations will propagate any uncertainty in the arguments into the result. However, the uncertainty in the result may overestimate the true uncertainty (by at most a factor of `sqrt(2)`) due to computational limitations. Furthermore, all of these operations may return `None` if their result cannot be represented within the numeric representation (e.g., the exponent is so small that the price does not fit into an i64). Users of these methods should (1) select their exponents to avoid this problem, and (2) handle the `None` case gracefully.",
"type": "object",
"required": [
"conf",
"expo",
"price"
"price",
"publish_time"
],
"properties": {
"conf": {
"description": "Confidence Interval.",
"description": "Confidence interval.",
"type": "string"
},
"expo": {
Expand All @@ -36,6 +37,11 @@
"price": {
"description": "Price.",
"type": "string"
},
"publish_time": {
"description": "Publish time.",
"type": "integer",
"format": "int64"
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions examples/cw-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ pub fn execute(

/// Query the Pyth contract the current price of the configured price feed.
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::FetchPrice {} => to_binary(&query_fetch_price(deps)?),
QueryMsg::FetchPrice {} => to_binary(&query_fetch_price(deps, env)?),
}
}

fn query_fetch_price(deps: Deps) -> StdResult<FetchPriceResponse> {
fn query_fetch_price(deps: Deps, env: Env) -> StdResult<FetchPriceResponse> {
let state = STATE.load(deps.storage)?;

// query_price_feed is the standard way to read the current price from a Pyth price feed.
Expand All @@ -92,13 +92,13 @@ fn query_fetch_price(deps: Deps) -> StdResult<FetchPriceResponse> {
// you handle this scenario more carefully. Consult the [consumer best practices](https://docs.pyth.network/consumers/best-practices)
// for recommendations.
let current_price = price_feed
.get_current_price()
.get_price_no_older_than(env.block.time.seconds() as i64, 60)
ali-bahjati marked this conversation as resolved.
Show resolved Hide resolved
.ok_or_else(|| StdError::not_found("Current price is not available"))?;

// Get an exponentially-weighted moving average price and confidence interval.
// The same notes about availability apply to this price.
let ema_price = price_feed
.get_ema_price()
.get_ema_price_no_older_than(env.block.time.seconds() as i64, 60)
.ok_or_else(|| StdError::not_found("EMA price is not available"))?;

Ok(FetchPriceResponse {
Expand Down
131 changes: 33 additions & 98 deletions pyth-sdk-cw/schema/price_feed_response.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,135 +19,70 @@
"Identifier": {
"type": "string"
},
"PriceFeed": {
"description": "Represents a current aggregation price from pyth publisher feeds.",
"Price": {
"description": "A price with a degree of uncertainty at a certain time, represented as a price +- a confidence interval.\n\nPlease refer to the documentation at https://docs.pyth.network/consumers/best-practices for using this price safely.\n\nThe 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. For example:\n\n``` use pyth_sdk::Price; Price { price: 12345, conf: 267, expo: -2, publish_time: 100 }; // represents 123.45 +- 2.67 published at UnixTimestamp 100 Price { price: 123, conf: 1, expo: 2, publish_time: 100 }; // represents 12300 +- 100 published at UnixTimestamp 100 ```\n\n`Price` supports a limited set of mathematical operations. All of these operations will propagate any uncertainty in the arguments into the result. However, the uncertainty in the result may overestimate the true uncertainty (by at most a factor of `sqrt(2)`) due to computational limitations. Furthermore, all of these operations may return `None` if their result cannot be represented within the numeric representation (e.g., the exponent is so small that the price does not fit into an i64). Users of these methods should (1) select their exponents to avoid this problem, and (2) handle the `None` case gracefully.",
"type": "object",
"required": [
"conf",
"ema_conf",
"ema_price",
"expo",
"id",
"max_num_publishers",
"num_publishers",
"prev_conf",
"prev_price",
"prev_publish_time",
"price",
"product_id",
"publish_time",
"status"
"publish_time"
],
"properties": {
"conf": {
"description": "Confidence interval around the current aggregation price.",
"type": "string"
},
"ema_conf": {
"description": "Exponentially moving average confidence interval.",
"type": "string"
},
"ema_price": {
"description": "Exponentially moving average price.",
"description": "Confidence interval.",
"type": "string"
},
"expo": {
"description": "Price exponent.",
"description": "Exponent.",
"type": "integer",
"format": "int32"
},
"id": {
"description": "Unique identifier for this price.",
"allOf": [
{
"$ref": "#/definitions/Identifier"
}
]
},
"max_num_publishers": {
"description": "Maximum number of allowed publishers that can contribute to a price.",
"type": "integer",
"format": "uint32",
"minimum": 0.0
},
"num_publishers": {
"description": "Number of publishers that made up current aggregate.",
"type": "integer",
"format": "uint32",
"minimum": 0.0
},
"prev_conf": {
"description": "Confidence interval of previous aggregate with Trading status.",
"type": "string"
},
"prev_price": {
"description": "Price of previous aggregate with Trading status.",
"price": {
"description": "Price.",
"type": "string"
},
"prev_publish_time": {
"description": "Publish time of previous aggregate with Trading status.",
"publish_time": {
"description": "Publish time.",
"type": "integer",
"format": "int64"
}
}
},
"PriceFeed": {
"description": "Represents a current aggregation price from pyth publisher feeds.",
"type": "object",
"required": [
"ema_price",
"id",
"price"
],
"properties": {
"ema_price": {
"description": "Exponentially-weighted moving average (EMA) price.",
"allOf": [
{
"$ref": "#/definitions/Price"
}
]
},
"price": {
"description": "The current aggregation price.",
"type": "string"
},
"product_id": {
"description": "Product account key.",
"id": {
"description": "Unique identifier for this price.",
"allOf": [
{
"$ref": "#/definitions/Identifier"
}
]
},
"publish_time": {
"description": "Current price aggregation publish time",
"type": "integer",
"format": "int64"
},
"status": {
"description": "Status of price (Trading is valid).",
"price": {
"description": "Price.",
"allOf": [
{
"$ref": "#/definitions/PriceStatus"
"$ref": "#/definitions/Price"
}
]
}
}
},
"PriceStatus": {
"description": "Represents availability status of a price feed.",
"oneOf": [
{
"description": "The price feed is not currently updating for an unknown reason.",
"type": "string",
"enum": [
"Unknown"
]
},
{
"description": "The price feed is updating as expected.",
"type": "string",
"enum": [
"Trading"
]
},
{
"description": "The price feed is not currently updating because trading in the product has been halted.",
"type": "string",
"enum": [
"Halted"
]
},
{
"description": "The price feed is not currently updating because an auction is setting the price.",
"type": "string",
"enum": [
"Auction"
]
}
]
}
}
}
1 change: 0 additions & 1 deletion pyth-sdk-cw/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ pub use pyth_sdk::{
Price,
PriceFeed,
PriceIdentifier,
PriceStatus,
ProductIdentifier,
};

Expand Down
15 changes: 11 additions & 4 deletions pyth-sdk-solana/examples/eth_price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ use pyth_sdk_solana::load_price_feed_from_account;
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use std::str::FromStr;
use std::time::{
SystemTime,
UNIX_EPOCH,
};
use std::{
thread,
time,
Expand All @@ -24,10 +28,13 @@ fn main() {
load_price_feed_from_account(&eth_price_key, &mut eth_price_account).unwrap();

println!(".....ETH/USD.....");
println!("status .......... {:?}", eth_price_feed.status);
println!("num_publishers .. {}", eth_price_feed.num_publishers);

let maybe_price = eth_price_feed.get_current_price();
let current_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as i64;

let maybe_price = eth_price_feed.get_price_no_older_than(current_time, 60);
match maybe_price {
Some(p) => {
println!("price ........... {} x 10^{}", p.price, p.expo);
Expand All @@ -40,7 +47,7 @@ fn main() {
}


let maybe_ema_price = eth_price_feed.get_ema_price();
let maybe_ema_price = eth_price_feed.get_ema_price_no_older_than(current_time, 60);
match maybe_ema_price {
Some(ema_price) => {
println!(
Expand Down
27 changes: 12 additions & 15 deletions pyth-sdk-solana/examples/get_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ use pyth_sdk_solana::state::{
load_price_account,
load_product_account,
CorpAction,
PriceStatus,
PriceType,
};
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use std::str::FromStr;
use std::time::{
SystemTime,
UNIX_EPOCH,
};

fn get_price_type(ptype: &PriceType) -> &'static str {
match ptype {
Expand All @@ -22,15 +25,6 @@ fn get_price_type(ptype: &PriceType) -> &'static str {
}
}

fn get_status(st: &PriceStatus) -> &'static str {
match st {
PriceStatus::Unknown => "unknown",
PriceStatus::Trading => "trading",
PriceStatus::Halted => "halted",
PriceStatus::Auction => "auction",
}
}

fn get_corp_act(cact: &CorpAction) -> &'static str {
match cact {
CorpAction::NoCorpAct => "nocorpact",
Expand All @@ -52,7 +46,7 @@ fn main() {
// iget and print each Product in Mapping directory
let mut i = 0;
for prod_pkey in &map_acct.products {
let prod_data = clnt.get_account_data(&prod_pkey).unwrap();
let prod_data = clnt.get_account_data(prod_pkey).unwrap();
let prod_acct = load_product_account(&prod_data).unwrap();

// print key and reference data for this Product
Expand All @@ -73,7 +67,12 @@ fn main() {

println!(" price_account .. {:?}", px_pkey);

let maybe_price = price_feed.get_current_price();
let current_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as i64;

let maybe_price = price_feed.get_price_no_older_than(current_time, 60);
match maybe_price {
Some(p) => {
println!(" price ........ {} x 10^{}", p.price, p.expo);
Expand All @@ -89,8 +88,6 @@ fn main() {
" price_type ... {}",
get_price_type(&price_account.ptype)
);
println!(" exponent ..... {}", price_feed.expo);
println!(" status ....... {}", get_status(&price_feed.status));
println!(
" corp_act ..... {}",
get_corp_act(&price_account.agg.corp_act)
Expand All @@ -100,7 +97,7 @@ fn main() {
println!(" valid_slot ... {}", price_account.valid_slot);
println!(" publish_slot . {}", price_account.agg.pub_slot);

let maybe_ema_price = price_feed.get_ema_price();
let maybe_ema_price = price_feed.get_ema_price_no_older_than(current_time, 60);
ali-bahjati marked this conversation as resolved.
Show resolved Hide resolved
match maybe_ema_price {
Some(ema_price) => {
println!(
Expand Down
1 change: 0 additions & 1 deletion pyth-sdk-solana/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ pub use pyth_sdk::{
Price,
PriceFeed,
PriceIdentifier,
PriceStatus,
ProductIdentifier,
};

Expand Down
Loading