# Pyth Client **This crate has been deprecated. Please use [pyth-sdk-solana](https://github.com/pyth-network/pyth-sdk-rs/tree/main/pyth-sdk-solana) instead. pyth-sdk-solana provides identical functionalities with an easier interface.** This crate provides utilities for reading price feeds from the [pyth.network](https://pyth.network/) oracle on the Solana network. The crate includes a library for on-chain programs and an off-chain example program. Key features of this library include: * Get the current price of over [50 products](https://pyth.network/markets/), including cryptocurrencies, US equities, forex and more. * Combine listed products to create new price feeds, e.g., for baskets of tokens or non-USD quote currencies. * Consume prices in on-chain Solana programs or off-chain applications. Please see the [pyth.network documentation](https://docs.pyth.network/) for more information about pyth.network. ## Installation Add a dependency to your Cargo.toml: ```toml [dependencies] pyth-client="" ``` If you want to use this library in your on-chain program you should use `no-entrypoint` feature to prevent conflict between your program and this library's program. ```toml [dependencies] pyth-client = {version = "", features = ["no-entrypoint"]} ``` See [pyth-client on crates.io](https://crates.io/crates/pyth-client/) to get the latest version of the library. ## Usage Pyth Network stores its price feeds in a collection of Solana accounts. This crate provides utilities for interpreting and manipulating the content of these accounts. Applications can obtain the content of these accounts in two different ways: * On-chain programs should pass these accounts to the instructions that require price feeds. * Off-chain programs can access these accounts using the Solana RPC client (as in the [example program](examples/get_accounts.rs)). In both cases, the content of the account will be provided to the application as a binary blob (`Vec`). The examples below assume that the user has already obtained this account data. ### Parse account data Pyth Network has several different types of accounts: * Price accounts store the current price for a product * Product accounts store metadata about a product, such as its symbol (e.g., "BTC/USD"). * Mapping accounts store a listing of all Pyth accounts For more information on the different types of Pyth accounts, see the [account structure documentation](https://docs.pyth.network/how-pyth-works/account-structure). The pyth.network website also lists the public keys of the accounts (e.g., [BTC/USD accounts](https://pyth.network/markets/#BTC/USD)). This library provides several `load_*` methods that translate the binary data in each account into an appropriate struct: ```rust // replace with account data, either passed to on-chain program or from RPC node let price_account_data: Vec = ...; let price_account: Price = load_price( &price_account_data ).unwrap(); let product_account_data: Vec = ...; let product_account: Product = load_product( &product_account_data ).unwrap(); let mapping_account_data: Vec = ...; let mapping_account: Mapping = load_mapping( &mapping_account_data ).unwrap(); ``` ### Get the current price Read the current price from a `Price` account: ```rust let price: PriceConf = price_account.get_current_price().unwrap(); println!("price: ({} +- {}) x 10^{}", price.price, price.conf, price.expo); ``` The price is returned along with a confidence interval that represents the degree of uncertainty in the price. Both values are represented as fixed-point numbers, `a * 10^e`. The method will return `None` if the price is not currently available. The status of the price feed determines if the price is available. You can get the current status using: ```rust let price_status: PriceStatus = price_account.get_current_price_status(); ``` ### Non-USD prices Most assets in Pyth are priced in USD. Applications can combine two USD prices to price an asset in a different quote currency: ```rust let btc_usd: Price = ...; let eth_usd: Price = ...; // -8 is the desired exponent for the result let btc_eth: PriceConf = btc_usd.get_price_in_quote(ð_usd, -8); println!("BTC/ETH price: ({} +- {}) x 10^{}", price.price, price.conf, price.expo); ``` ### Price a basket of assets Applications can also compute the value of a basket of multiple assets: ```rust let btc_usd: Price = ...; let eth_usd: Price = ...; // Quantity of each asset in fixed-point a * 10^e. // This represents 0.1 BTC and .05 ETH. // -8 is desired exponent for result let basket_price: PriceConf = Price::price_basket(&[ (btc_usd, 10, -2), (eth_usd, 5, -2) ], -8); println!("0.1 BTC and 0.05 ETH are worth: ({} +- {}) x 10^{} USD", basket_price.price, basket_price.conf, basket_price.expo); ``` This function additionally propagates any uncertainty in the price into uncertainty in the value of the basket. ### Off-chain example program 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 ema_price .............. 7426390900 ema_confidence ......... 2259870 ``` ## Development This library can be built for either your native platform or in BPF (used by Solana programs). Use `cargo build` / `cargo test` to build and test natively. Use `cargo build-bpf` / `cargo test-bpf` to build in BPF for Solana; these commands require you to have installed the [Solana CLI tools](https://docs.solana.com/cli/install-solana-cli-tools). The BPF tests will also run an instruction count program that logs the resource consumption of various library functions. This program can also be run on its own using `cargo test-bpf --test instruction_count`. ### Releases To release a new version of this package, perform the following steps: 1. Increment the version number in `Cargo.toml`. You may use a version number with a `-beta.x` suffix such as `0.0.1-beta.0` to create opt-in test versions. 2. Merge your change into `main` on github. 3. Create and publish a new github release. The name of the release should be the version number, and the tag should be the version number prefixed with `v`. Publishing the release will trigger a github action that will automatically publish the [pyth-client](https://crates.io/crates/pyth-client) rust crate to `crates.io`.