pyth-client 0.5.1

pyth price oracle data structures and example usage
Documentation
// example usage of pyth-client account structure
// bootstrap all product and pricing accounts from root mapping account

use pyth_client::{
  PriceType,
  PriceStatus,
  CorpAction,
  load_mapping,
  load_product,
  load_price
};
use solana_client::{
  rpc_client::RpcClient
};
use solana_program::{
  pubkey::Pubkey
};
use std::{
  str::FromStr
};

fn get_price_type( ptype: &PriceType ) -> &'static str
{
  match ptype {
    PriceType::Unknown    => "unknown",
    PriceType::Price      => "price",
  }
}

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",
  }
}

fn main() {
  // get pyth mapping account
  let url = "http://api.devnet.solana.com";
  let key = "BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2";
  let clnt = RpcClient::new( url.to_string() );
  let mut akey = Pubkey::from_str( key ).unwrap();

  loop {
    // get Mapping account from key
    let map_data = clnt.get_account_data( &akey ).unwrap();
    let map_acct = load_mapping( &map_data ).unwrap();

    // iget and print each Product in Mapping directory
    let mut i = 0;
    for prod_akey in &map_acct.products {
      let prod_pkey = Pubkey::new( &prod_akey.val );
      let prod_data = clnt.get_account_data( &prod_pkey ).unwrap();
      let prod_acct = load_product( &prod_data ).unwrap();

      // print key and reference data for this Product
      println!( "product_account .. {:?}", prod_pkey );
      for (key, val) in prod_acct.iter() {
        if key.len() > 0 {
          println!( "  {:.<16} {}", key, val );
        }
      }

      // print all Prices that correspond to this Product
      if prod_acct.px_acc.is_valid() {
        let mut px_pkey = Pubkey::new( &prod_acct.px_acc.val );
        loop {
          let pd = clnt.get_account_data( &px_pkey ).unwrap();
          let pa = load_price( &pd ).unwrap();

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

          let maybe_price = pa.get_current_price();
          match maybe_price {
            Some(p) => {
              println!("    price ........ {} x 10^{}", p.price, p.expo);
              println!("    conf ......... {} x 10^{}", p.conf, p.expo);
            }
            None => {
              println!("    price ........ unavailable");
              println!("    conf ......... unavailable");
            }
          }

          println!( "    price_type ... {}", get_price_type(&pa.ptype));
          println!( "    exponent ..... {}", pa.expo );
          println!( "    status ....... {}", get_status(&pa.get_current_price_status()));
          println!( "    corp_act ..... {}", get_corp_act(&pa.agg.corp_act));

          println!( "    num_qt ....... {}", pa.num_qt );
          println!( "    valid_slot ... {}", pa.valid_slot );
          println!( "    publish_slot . {}", pa.agg.pub_slot );

          let maybe_ema_price = pa.get_ema_price();
          match maybe_ema_price {
            Some(ema_price) => {
              println!( "    ema_price ......... {} x 10^{}", ema_price.price, ema_price.expo );
              println!( "    ema_confidence ......... {} x 10^{}", ema_price.conf, ema_price.expo );
            }
            None => {
              println!( "    ema_price ......... unavailable");
              println!( "    ema_confidence ......... unavailable");
            }
          }

          // go to next price account in list
          if pa.next.is_valid() {
            px_pkey = Pubkey::new( &pa.next.val );
          } else {
            break;
          }
        }
      }
      // go to next product
      i += 1;
      if i == map_acct.num {
        break;
      }
    }

    // go to next Mapping account in list
    if !map_acct.next.is_valid() {
      break;
    }
    akey = Pubkey::new( &map_acct.next.val );
  }
}