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

feat!: allow loading network-specific PriceAccount #113

Merged
merged 1 commit into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pyth-sdk-example-solana-contract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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];
Expand Down
2 changes: 1 addition & 1 deletion examples/sol-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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;
Expand Down Expand Up @@ -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()?;
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
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"
Expand Down
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;
Expand All @@ -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.....");

Expand Down
4 changes: 3 additions & 1 deletion pyth-sdk-solana/examples/get_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
41 changes: 32 additions & 9 deletions pyth-sdk-solana/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Loading