Skip to content

feat!: allow loading network-specific PriceAccount #113

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

Merged
merged 1 commit into from
Feb 9, 2024
Merged
Changes from all 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
2 changes: 1 addition & 1 deletion .github/workflows/pyth-sdk-example-anchor-contract.yml
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ jobs:
- name: Install solana binaries
run: |
# Installing 1.16.x cli tools to have sbf instead of bpf. bpf does not work anymore.
sh -c "$(curl -sSfL https://release.solana.com/v1.17.0/install)"
sh -c "$(curl -sSfL https://release.solana.com/v1.18.1/install)"
echo "/home/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH
- name: Install anchor binaries
run: |
2 changes: 1 addition & 1 deletion .github/workflows/pyth-sdk-example-solana-contract.yml
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ jobs:
- name: Install solana binaries
run: |
# Installing 1.16.x cli tools to have sbf instead of bpf. bpf does not work anymore.
sh -c "$(curl -sSfL https://release.solana.com/v1.17.0/install)"
sh -c "$(curl -sSfL https://release.solana.com/v1.18.1/install)"
echo "/home/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH
- name: Build
run: scripts/build.sh
2 changes: 1 addition & 1 deletion .github/workflows/pyth-sdk-solana.yml
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ jobs:
- name: Install Solana Binaries
run: |
# Installing 1.17.x cli tools to have sbf instead of bpf. bpf does not work anymore.
sh -c "$(curl -sSfL https://release.solana.com/v1.17.0/install)"
sh -c "$(curl -sSfL https://release.solana.com/v1.18.1/install)"
echo "/home/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH
- name: Build
run: cargo build --verbose
Original file line number Diff line number Diff line change
@@ -19,4 +19,4 @@ default = []
[dependencies]
anchor-lang = "0.28.0"
pyth-sdk = { path = "../../../../pyth-sdk", version = "0.8.0" }
pyth-sdk-solana = { path = "../../../../pyth-sdk-solana", version = "0.9.0" }
pyth-sdk-solana = { path = "../../../../pyth-sdk-solana", version = "0.10.0" }
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anchor_lang::prelude::*;
use pyth_sdk_solana::state::load_price_account;
use pyth_sdk_solana::state::SolanaPriceAccount;
use std::ops::Deref;
use std::str::FromStr;

@@ -25,7 +26,8 @@ impl anchor_lang::Owner for PriceFeed {

impl anchor_lang::AccountDeserialize for PriceFeed {
fn try_deserialize_unchecked(data: &mut &[u8]) -> Result<Self> {
let account = load_price_account(data).map_err(|_x| error!(ErrorCode::PythError))?;
let account: &SolanaPriceAccount =
load_price_account(data).map_err(|_x| error!(ErrorCode::PythError))?;

// Use a dummy key since the key field will be removed from the SDK
let zeros: [u8; 32] = [0; 32];
2 changes: 1 addition & 1 deletion examples/sol-contract/Cargo.toml
Original file line number Diff line number Diff line change
@@ -11,4 +11,4 @@ crate-type = ["cdylib", "lib"]
borsh = "0.10.3"
arrayref = "0.3.6"
solana-program = ">= 1.10"
pyth-sdk-solana = { path = "../../pyth-sdk-solana", version = "0.9.0" }
pyth-sdk-solana = { path = "../../pyth-sdk-solana", version = "0.10.0" }
10 changes: 5 additions & 5 deletions examples/sol-contract/src/processor.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ use borsh::{
BorshDeserialize,
BorshSerialize,
};
use pyth_sdk_solana::load_price_feed_from_account_info;
use pyth_sdk_solana::state::SolanaPriceAccount;

use crate::instruction::ExampleInstructions;
use crate::state::AdminConfig;
@@ -53,8 +53,8 @@ pub fn process_instruction(
config.collateral_price_feed_id = *pyth_collateral_account.key;

// Make sure these Pyth price accounts can be loaded
load_price_feed_from_account_info(pyth_loan_account)?;
load_price_feed_from_account_info(pyth_collateral_account)?;
SolanaPriceAccount::account_info_to_feed(pyth_loan_account)?;
SolanaPriceAccount::account_info_to_feed(pyth_collateral_account)?;

let config_data = config.try_to_vec()?;
let config_dst = &mut admin_config_account.try_borrow_mut_data()?;
@@ -85,7 +85,7 @@ pub fn process_instruction(
// (price + conf) * loan_qty * 10 ^ (expo).
// Here is more explanation on confidence interval in Pyth:
// https://docs.pyth.network/consume-data/best-practices
let feed1 = load_price_feed_from_account_info(pyth_loan_account)?;
let feed1 = SolanaPriceAccount::account_info_to_feed(pyth_loan_account)?;
let current_timestamp1 = Clock::get()?.unix_timestamp;
let result1 = feed1
.get_price_no_older_than(current_timestamp1, 60)
@@ -107,7 +107,7 @@ pub fn process_instruction(
// (price - conf) * collateral_qty * 10 ^ (expo).
// Here is more explanation on confidence interval in Pyth:
// https://docs.pyth.network/consume-data/best-practices
let feed2 = load_price_feed_from_account_info(pyth_collateral_account)?;
let feed2 = SolanaPriceAccount::account_info_to_feed(pyth_collateral_account)?;
let current_timestamp2 = Clock::get()?.unix_timestamp;
let result2 = feed2
.get_price_no_older_than(current_timestamp2, 60)
2 changes: 1 addition & 1 deletion pyth-sdk-solana/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyth-sdk-solana"
version = "0.9.0"
version = "0.10.0"
authors = ["Pyth Data Foundation"]
edition = "2018"
license = "Apache-2.0"
4 changes: 2 additions & 2 deletions pyth-sdk-solana/examples/eth_price.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// example usage of reading pyth price from solana/pythnet price account

use pyth_sdk_solana::load_price_feed_from_account;
use pyth_sdk_solana::state::SolanaPriceAccount;
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use std::str::FromStr;
@@ -25,7 +25,7 @@ fn main() {
// get price data from key
let mut eth_price_account = clnt.get_account(&eth_price_key).unwrap();
let eth_price_feed =
load_price_feed_from_account(&eth_price_key, &mut eth_price_account).unwrap();
SolanaPriceAccount::account_to_feed(&eth_price_key, &mut eth_price_account).unwrap();

println!(".....ETH/USD.....");

4 changes: 3 additions & 1 deletion pyth-sdk-solana/examples/get_accounts.rs
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ use pyth_sdk_solana::state::{
load_product_account,
CorpAction,
PriceType,
SolanaPriceAccount,
};
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
@@ -62,7 +63,8 @@ fn main() {
let mut px_pkey = prod_acct.px_acc;
loop {
let price_data = clnt.get_account_data(&px_pkey).unwrap();
let price_account = load_price_account(&price_data).unwrap();
let price_account: &SolanaPriceAccount =
load_price_account(&price_data).unwrap();
let price_feed = price_account.to_price_feed(&px_pkey);

println!(" price_account .. {:?}", px_pkey);
41 changes: 32 additions & 9 deletions pyth-sdk-solana/src/lib.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,11 @@ use solana_program::account_info::{
};
use solana_program::pubkey::Pubkey;

use state::load_price_account;
use state::{
load_price_account,
GenericPriceAccount,
SolanaPriceAccount,
};

pub use pyth_sdk::{
Price,
@@ -27,24 +31,43 @@ pub use pyth_sdk::{
pub const VALID_SLOT_PERIOD: u64 = 25;

/// Loads Pyth Feed Price from Price Account Info.
#[deprecated(note = "solana-specific, use SolanaPriceAccount::account_info_to_feed instead.")]
pub fn load_price_feed_from_account_info(
price_account_info: &AccountInfo,
) -> Result<PriceFeed, PythError> {
let data = price_account_info
.try_borrow_data()
.map_err(|_| PythError::InvalidAccountData)?;
let price_account = load_price_account(*data)?;

Ok(price_account.to_price_feed(price_account_info.key))
SolanaPriceAccount::account_info_to_feed(price_account_info)
}

/// Loads Pyth Price Feed from Account when using Solana Client.
///
/// It is a helper function which constructs Account Info when reading Account in clients.
#[deprecated(note = "solana-specific, use SolanaPriceAccount::account_to_feed instead.")]
pub fn load_price_feed_from_account(
price_key: &Pubkey,
price_account: &mut impl Account,
) -> Result<PriceFeed, PythError> {
let price_account_info = (price_key, price_account).into_account_info();
load_price_feed_from_account_info(&price_account_info)
SolanaPriceAccount::account_to_feed(price_key, price_account)
}

impl<const N: usize, T: 'static> GenericPriceAccount<N, T>
where
T: Default,
T: Copy,
{
pub fn account_info_to_feed(price_account_info: &AccountInfo) -> Result<PriceFeed, PythError> {
load_price_account::<N, T>(
*price_account_info
.try_borrow_data()
.map_err(|_| PythError::InvalidAccountData)?,
)
.map(|acc| acc.to_price_feed(price_account_info.key))
}

pub fn account_to_feed(
price_key: &Pubkey,
price_account: &mut impl Account,
) -> Result<PriceFeed, PythError> {
let price_account_info = (price_key, price_account).into_account_info();
Self::account_info_to_feed(&price_account_info)
}
}
Loading