#solana #pyth #oracle

pyth-sdk-solana

Pyth 价格预言机数据结构和示例用法

16 个版本 (9 个重大更新)

0.10.1 2024 年 3 月 13 日
0.9.0 2023 年 12 月 12 日
0.8.0 2023 年 8 月 15 日
0.7.2 2023 年 5 月 16 日
0.2.0 2022 年 3 月 16 日

#408 in 魔法豆

Download history 1243/week @ 2024-04-20 1273/week @ 2024-04-27 1242/week @ 2024-05-04 1369/week @ 2024-05-11 1614/week @ 2024-05-18 1519/week @ 2024-05-25 1806/week @ 2024-06-01 1277/week @ 2024-06-08 1169/week @ 2024-06-15 1421/week @ 2024-06-22 1445/week @ 2024-06-29 1472/week @ 2024-07-06 1884/week @ 2024-07-13 2400/week @ 2024-07-20 2250/week @ 2024-07-27 1947/week @ 2024-08-03

8,619 每月下载量
用于 30 个 crate (14 个直接使用)

Apache-2.0

135KB
2.5K SLoC

Pyth Network Solana SDK

该软件包提供从 Solana 网络上的 pyth.network 预言机读取价格数据的功能。它还包括几个 链外示例程序

安装

在 Cargo.toml 中添加依赖项

[dependencies]
pyth-sdk-solana="<version>"

请参阅 crates.io 上的 pyth-sdk-solana 以获取库的最新版本。

用法

Pyth Network 将其价格数据存储在一系列 Solana 账户中,这些账户具有各种类型

  • 价格账户存储产品的当前价格
  • 产品账户存储有关产品的元数据,例如其符号(例如,“BTC/USD”)。
  • 映射账户存储所有 Pyth 账户的列表

大多数使用此 SDK 的用户只需要访问价格账户的内容;其他两种账户类型是预言机的实现细节。应用程序可以通过两种不同的方式获取这些账户的内容

  • 链上程序应将这些账户传递给需要价格数据的指令。
  • 链外程序可以使用 Solana RPC 客户端(例如,在 eth 价格示例程序)访问这些账户。

pyth.network 网站可用于识别每个价格账户的公钥(例如,Crypto.BTC/USD)。

链上

链上应用程序应将相关的Pyth网络价格账户传递给消费它的Solana指令。这个价格账户在Solana指令的代码中将表示为AccountInfoload_price_feed_from_account_info函数将从AccountInfo构建一个PriceFeed结构。

use pyth_sdk_solana::{load_price_feed_from_account_info, PriceFeed};

const STALENESS_THRESHOLD : u64 = 60; // staleness threshold in seconds
let price_account_info: AccountInfo = ...;
let price_feed: PriceFeed = load_price_feed_from_account_info( &price_account_info ).unwrap();
let current_timestamp = Clock::get()?.unix_timestamp;
let current_price: Price = price_feed.get_price_no_older_than(current_timestamp, STALENESS_THRESHOLD).unwrap();
msg!("price: ({} +- {}) x 10^{}", current_price.price, current_price.conf, current_price.expo);

load_price_feed_from_account_info返回的PriceFeed对象包含关于产品的所有当前可用价格信息。此结构还有一些有用的函数用于操作和组合价格;有关更多详细信息,请参阅常见SDK文档

get_price_no_older_than函数接受一个以秒为单位的age。如果当前链上聚合数据比current_timestamp - age旧,get_price_no_older_than将返回None

请注意,在您的应用程序使用之前,也应验证传入的价格账户的地址。否则,攻击者可能会传递不同的账户并将价格设置为任意值。

链下

链下应用程序可以使用Solana RPC客户端读取Pyth网络价格账户的当前值。该客户端将以Account结构返回账户的内容。load_price_feed_from_account函数将从Account构建一个PriceFeed结构。

use pyth_sdk_solana::{load_price_feed_from_account, PriceFeed};

const STALENESS_THRESHOLD : u64 = 60; // staleness threshold in seconds
let current_time = SystemTime::now()
    .duration_since(UNIX_EPOCH)
    .unwrap()
    .as_secs() as i64;

let price_key: Pubkey = ...;
let mut price_account: Account = clnt.get_account(&price_key).unwrap();
let price_feed: PriceFeed = load_price_feed_from_account( &price_key, &mut price_account ).unwrap();
let current_price: Price = price_feed.get_price_no_older_than(current_time, STALENESS_THRESHOLD).unwrap();
println!("price: ({} +- {}) x 10^{}", current_price.price, current_price.conf, current_price.expo);

低级Solana账户结构

⚠️ Solana账户结构是一个内部API,可能会更改。尽可能使用load_price_feed_*

此库还提供了一些load_*方法,允许用户将每个账户中的二进制数据转换为适当的结构。

use pyth_sdk_solana::state::*;

// replace with account data, either passed to on-chain program or from RPC node
let price_account_data: Vec<u8> = ...;
let price_account: &PriceAccount = load_price_account( &price_account_data ).unwrap();

let product_account_data: Vec<u8> = ...;
let product_account: &ProductAccount = load_product_account( &product_account_data ).unwrap();

let mapping_account_data: Vec<u8> = ...;
let mapping_account: &MappingAccount = load_mapping_account( &mapping_account_data ).unwrap();

有关不同类型Pyth账户的更多信息,请参阅账户结构文档

链下示例程序

示例程序eth_price打印了pythnet上Pyth的产品参考数据和当前价格信息。您可以使用相同的示例,并使用相关的Solana集群URL替换URL,以获取Solana集群的相同信息。运行以下命令尝试此示例程序

cargo build --examples
cargo run --example eth_price

此命令的输出是ETH/USD随时间变化的价格,例如

.....ETH/USD.....
status .......... Trading
num_publishers .. 19
price ........... 291958500000 x 10^-8
conf ............ 163920000 x 10^-8
ema_price ....... 291343470000 x 10^-8
ema_conf ........ 98874533 x 10^-8

有关使用Solana账户结构的示例,请运行以下命令

cargo run --example get_accounts

此命令的输出是Pyth账户的列表,例如

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_conf ..... 2259870

开发

此库可以为您自己的平台或BPF(由Solana程序使用)构建。使用cargo build / cargo test本地构建和测试。使用cargo build-bpf / cargo test-bpf在BPF中为Solana构建;这些命令要求您已安装Solana CLI工具

依赖项

~11–20MB
~283K SLoC