diff --git a/README.md b/README.md index 9e7e2ea..09df993 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,37 @@ A rust API for desribing on-chain pyth account structures. A primer on pyth acc Contains a library for use in on-chain program development and an off-chain example program for loading and printing product reference data and aggregate prices from all devnet pyth accounts. + +### Running the Example + +The example program prints the product reference data and current price information for Pyth on Solana devnet. +Run the following commands to try this example program: + +``` +cargo build --examples +cargo run --example get_accounts +``` + +The output of this command is a listing of Pyth's accounts, such as: + +``` +product_account .. 6MEwdxe4g1NeAF9u6KDG14anJpFsVEa2cvr5H6iriFZ8 + symbol.......... SRM/USD + asset_type...... Crypto + quote_currency.. USD + description..... SRM/USD + generic_symbol.. SRMUSD + base............ SRM + price_account .. 992moaMQKs32GKZ9dxi8keyM2bUmbrwBZpK4p2K6X5Vs + price ........ 7398000000 + conf ......... 3200000 + price_type ... price + exponent ..... -9 + status ....... trading + corp_act ..... nocorpact + num_qt ....... 1 + valid_slot ... 91340924 + publish_slot . 91340925 + twap ......... 7426390900 + twac ......... 2259870 +``` \ No newline at end of file diff --git a/examples/get_accounts.rs b/examples/get_accounts.rs index ce6b8da..4e57442 100644 --- a/examples/get_accounts.rs +++ b/examples/get_accounts.rs @@ -107,18 +107,30 @@ fn main() { loop { let pd = clnt.get_account_data( &px_pkey ).unwrap(); let pa = cast::( &pd ); + + let maybe_price = pa.get_current_price(); assert_eq!( pa.magic, MAGIC, "not a valid pyth account" ); assert_eq!( pa.atype, AccountType::Price as u32, "not a valid pyth price account" ); assert_eq!( pa.ver, VERSION_2, "unexpected pyth price account version" ); println!( " price_account .. {:?}", px_pkey ); + match maybe_price { + Some((price, confidence, _)) => { + println!(" price ........ {}", price); + println!(" conf ......... {}", confidence); + } + None => { + println!(" price ........ unavailable"); + println!(" conf ......... unavailable"); + } + } + println!( " price_type ... {}", get_price_type(&pa.ptype)); println!( " exponent ..... {}", pa.expo ); println!( " status ....... {}", get_status(&pa.agg.status)); println!( " corp_act ..... {}", get_corp_act(&pa.agg.corp_act)); - println!( " price ........ {}", pa.agg.price ); - println!( " conf ......... {}", pa.agg.conf ); + println!( " num_qt ....... {}", pa.num_qt ); println!( " valid_slot ... {}", pa.valid_slot ); println!( " publish_slot . {}", pa.agg.pub_slot ); diff --git a/src/lib.rs b/src/lib.rs index 52ce26e..c81c968 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -131,6 +131,27 @@ pub struct Price pub comp : [PriceComp;32] // price components one per quoter } +impl Price { + /** + * Get the current price and confidence interval as fixed-point numbers. Returns a triple of + * the current price, confidence interval, and the exponent for both numbers (i.e., the number + * of decimal places.) + * For example: + * + * get_current_price() -> Some((12345, 267, -2)) // represents 123.45 +- 2.67 + * get_current_price() -> Some((123, 1, 2)) // represents 12300 +- 100 + * + * Returns None if price information is currently unavailable. + */ + pub fn get_current_price(&self) -> Option<(i64, u64, i32)> { + if !matches!(self.agg.status, PriceStatus::Trading) { + None + } else { + Some((self.agg.price, self.agg.conf, self.expo)) + } + } +} + struct AccKeyU64 { pub val: [u64;4]