diff --git a/Cargo.lock b/Cargo.lock index a9556fda..f11a93fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,7 +90,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -206,7 +206,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -770,7 +770,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -973,7 +973,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", "syn_derive", ] @@ -1090,7 +1090,7 @@ checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -1286,7 +1286,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -1532,7 +1532,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -1543,7 +1543,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -1624,7 +1624,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -1688,7 +1688,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -1711,15 +1711,9 @@ checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - [[package]] name = "eager" version = "0.1.0" @@ -1799,7 +1793,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -1837,6 +1831,15 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "fast-math" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2465292146cdfc2011350fe3b1c616ac83cf0faeedb33463ba1c332ed8948d66" +dependencies = [ + "ieee754", +] + [[package]] name = "fastrand" version = "2.1.0" @@ -1957,7 +1960,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -2317,6 +2320,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "ieee754" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9007da9cacbd3e6343da136e98b0d2df013f553d35bdec8b518f07bea768e19c" + [[package]] name = "im" version = "15.1.0" @@ -2759,7 +2768,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -2861,7 +2870,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -2873,7 +2882,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -2935,7 +2944,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -3151,38 +3160,43 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] [[package]] -name = "pyth-sdk" -version = "0.8.0" -source = "git+https://github.com/AdrenaDEX/pyth-sdk-rs?branch=fix-solana-deps#267bcaa19eb5d9760ef49a4c4b4dfff604c26695" +name = "pyth-solana-receiver-sdk" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b7854c4176470c8d86de301dc5b57ac84227dabb9527328b585fc332962d60b" dependencies = [ - "borsh 0.10.3", - "borsh-derive 0.10.3", - "getrandom 0.2.15", + "anchor-lang", "hex", - "schemars", - "serde", + "pythnet-sdk", + "solana-program", ] [[package]] -name = "pyth-sdk-solana" -version = "0.10.1" -source = "git+https://github.com/AdrenaDEX/pyth-sdk-rs?branch=fix-solana-deps#267bcaa19eb5d9760ef49a4c4b4dfff604c26695" +name = "pythnet-sdk" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bbbc0456f9f27c9ad16b6c3bf1b2a7fea61eebf900f4d024a0468b9a84fe0c1" dependencies = [ + "anchor-lang", + "bincode", "borsh 0.10.3", - "borsh-derive 0.10.3", "bytemuck", - "num-derive 0.3.3", - "num-traits", - "pyth-sdk", + "byteorder", + "fast-math", + "hex", + "proc-macro2", + "rustc_version", "serde", + "sha3 0.10.8", + "slow_primes", "solana-program", "thiserror", ] @@ -3204,7 +3218,7 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -3685,7 +3699,7 @@ dependencies = [ "quote", "sablier-utils", "solana-sdk", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -3749,7 +3763,7 @@ version = "1.0.0-alpha.3" dependencies = [ "anchor-lang", "chrono", - "pyth-sdk-solana", + "pyth-solana-receiver-sdk", "sablier-cron", "sablier-network-program", "sablier-utils", @@ -3762,6 +3776,7 @@ version = "1.0.0-alpha.3" dependencies = [ "anchor-lang", "base64 0.21.7", + "pyth-solana-receiver-sdk", "sablier-macros", "serde", "static-pubkey", @@ -3786,7 +3801,7 @@ dependencies = [ "chrono", "futures", "log", - "pyth-sdk-solana", + "pyth-solana-receiver-sdk", "reqwest", "rustc_version", "sablier-cron", @@ -3803,7 +3818,6 @@ dependencies = [ "solana-program", "solana-quic-client", "solana-sdk", - "static-pubkey", "tokio", ] @@ -3816,30 +3830,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.69", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -3863,7 +3853,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -3934,18 +3924,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -3990,7 +3969,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -4109,6 +4088,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slow_primes" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58267dd2fbaa6dceecba9e3e106d2d90a2b02497c0e8b01b8759beccf5113938" +dependencies = [ + "num", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -4286,7 +4274,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -4678,7 +4666,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -4958,7 +4946,7 @@ checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -4970,7 +4958,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.69", + "syn 2.0.58", "thiserror", ] @@ -5027,7 +5015,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -5273,9 +5261,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.69" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -5291,7 +5279,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -5397,7 +5385,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -5492,7 +5480,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -5617,7 +5605,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -5843,7 +5831,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -5877,7 +5865,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6166,7 +6154,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] @@ -6186,7 +6174,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.58", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 058a929d..3203cffa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ termcolor = "1.2.0" cargo_metadata = "=0.18.1" nom = "~7" log = "0.4" -pyth-sdk-solana = { git = "https://github.com/AdrenaDEX/pyth-sdk-rs", branch = "fix-solana-deps" } +pyth-solana-receiver-sdk = "0.3.1" tokio = "1.18.4" futures = "0.3.26" version = "3.0.0" diff --git a/plugin/Cargo.toml b/plugin/Cargo.toml index 32963be0..06ab8336 100644 --- a/plugin/Cargo.toml +++ b/plugin/Cargo.toml @@ -31,7 +31,7 @@ sablier-thread-program = { workspace = true, features = ["no-entrypoint"] } sablier-webhook-program = { workspace = true, features = ["no-entrypoint"] } sablier-utils.workspace = true log.workspace = true -pyth-sdk-solana.workspace = true +pyth-solana-receiver-sdk.workspace = true reqwest.workspace = true solana-account-decoder.workspace = true solana-client.workspace = true @@ -42,7 +42,6 @@ solana-program.workspace = true solana-sdk.workspace = true tokio.workspace = true futures.workspace = true -static-pubkey.workspace = true [build-dependencies] cargo_metadata.workspace = true diff --git a/plugin/src/events.rs b/plugin/src/events.rs index f5380183..0103f490 100644 --- a/plugin/src/events.rs +++ b/plugin/src/events.rs @@ -1,24 +1,18 @@ -use anchor_lang::{prelude::AccountInfo, AccountDeserialize, Discriminator}; +use anchor_lang::{AccountDeserialize, Discriminator}; use bincode::deserialize; -use pyth_sdk_solana::{state::SolanaPriceAccount, PriceFeed}; +use pyth_solana_receiver_sdk::price_update::{PriceFeedMessage, PriceUpdateV2}; use sablier_thread_program::state::{Thread, VersionedThread}; use sablier_webhook_program::state::Webhook; use solana_geyser_plugin_interface::geyser_plugin_interface::{ GeyserPluginError, ReplicaAccountInfo, }; use solana_program::{clock::Clock, pubkey::Pubkey, sysvar}; -use static_pubkey::static_pubkey; - -static PYTH_ORACLE_PROGRAM_ID_MAINNET: Pubkey = - static_pubkey!("FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH"); -static PYTH_ORACLE_PROGRAM_ID_DEVNET: Pubkey = - static_pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"); #[derive(Debug)] pub enum AccountUpdateEvent { Clock { clock: Clock }, Thread { thread: VersionedThread }, - PriceFeed { price_feed: PriceFeed }, + PriceFeed { price_feed: PriceFeedMessage }, Webhook { webhook: Webhook }, } @@ -57,26 +51,17 @@ impl TryFrom<&mut ReplicaAccountInfo<'_>> for AccountUpdateEvent { } // If the account belongs to Pyth, attempt to parse it. - if owner_pubkey.eq(&PYTH_ORACLE_PROGRAM_ID_MAINNET) - || owner_pubkey.eq(&PYTH_ORACLE_PROGRAM_ID_DEVNET) - { - let data = &mut account_info.data.to_vec(); - let acc_info = AccountInfo::new( - &account_pubkey, - false, - false, - &mut account_info.lamports, - data, - &owner_pubkey, - account_info.executable, - account_info.rent_epoch, - ); - let price_feed = SolanaPriceAccount::account_info_to_feed(&acc_info).map_err(|_| { - GeyserPluginError::AccountsUpdateError { - msg: "Failed to parse Pyth price account".into(), - } - })?; - return Ok(AccountUpdateEvent::PriceFeed { price_feed }); + if owner_pubkey.eq(&pyth_solana_receiver_sdk::ID) { + let price_account = + PriceUpdateV2::try_deserialize(&mut account_info.data).map_err(|_| { + GeyserPluginError::AccountsUpdateError { + msg: "Failed to parse Pyth price account".into(), + } + })?; + + return Ok(AccountUpdateEvent::PriceFeed { + price_feed: price_account.price_message, + }); } // If the account belongs to the webhook program, parse in diff --git a/plugin/src/observers/thread.rs b/plugin/src/observers/thread.rs index 1e0b2949..a444c4dc 100644 --- a/plugin/src/observers/thread.rs +++ b/plugin/src/observers/thread.rs @@ -1,6 +1,6 @@ use chrono::DateTime; use log::info; -use pyth_sdk_solana::PriceFeed; +use pyth_solana_receiver_sdk::price_update::PriceFeedMessage; use sablier_cron::Schedule; use sablier_thread_program::state::{Equality, Trigger, TriggerContext, VersionedThread}; use solana_geyser_plugin_interface::geyser_plugin_interface::{ @@ -165,29 +165,21 @@ impl ThreadObserver { pub async fn observe_price_feed( self: Arc, account_pubkey: Pubkey, - price_feed: PriceFeed, + price_feed: PriceFeedMessage, ) -> PluginResult<()> { let r_pyth_threads = self.pyth_threads.read().await; if let Some(pyth_threads) = r_pyth_threads.get(&account_pubkey) { for pyth_thread in pyth_threads { match pyth_thread.equality { Equality::GreaterThanOrEqual => { - if price_feed - .get_price_unchecked() - .price - .ge(&pyth_thread.limit) - { + if price_feed.price.ge(&pyth_thread.limit) { let mut w_now_threads = self.now_threads.write().await; w_now_threads.insert(pyth_thread.thread_pubkey); drop(w_now_threads); } } Equality::LessThanOrEqual => { - if price_feed - .get_price_unchecked() - .price - .le(&pyth_thread.limit) - { + if price_feed.price.le(&pyth_thread.limit) { let mut w_now_threads = self.now_threads.write().await; w_now_threads.insert(pyth_thread.thread_pubkey); drop(w_now_threads); diff --git a/programs/thread/Cargo.toml b/programs/thread/Cargo.toml index 54493ccd..7e67a7ad 100644 --- a/programs/thread/Cargo.toml +++ b/programs/thread/Cargo.toml @@ -27,5 +27,5 @@ chrono = { workspace = true, features = ["alloc"] } sablier-cron.workspace = true sablier-network-program = { features = ["cpi"], workspace = true } sablier-utils.workspace = true -pyth-sdk-solana.workspace = true +pyth-solana-receiver-sdk.workspace = true version.workspace = true diff --git a/programs/thread/src/instructions/thread_kickoff.rs b/programs/thread/src/instructions/thread_kickoff.rs index ef441834..8fb3359b 100644 --- a/programs/thread/src/instructions/thread_kickoff.rs +++ b/programs/thread/src/instructions/thread_kickoff.rs @@ -6,7 +6,7 @@ use std::{ use anchor_lang::prelude::*; use chrono::DateTime; -use pyth_sdk_solana::state::SolanaPriceAccount; +use pyth_solana_receiver_sdk::price_update::PriceUpdateV2; use sablier_cron::Schedule; use sablier_network_program::state::{Worker, WorkerAccount}; use sablier_utils::thread::Trigger; @@ -195,7 +195,7 @@ pub fn handler(ctx: Context) -> Result<()> { }) } Trigger::Pyth { - price_feed: price_feed_pubkey, + feed_id, equality, limit, } => { @@ -205,17 +205,21 @@ pub fn handler(ctx: Context) -> Result<()> { return Err(SablierError::TriggerConditionFailed.into()); } Some(account_info) => { - require!( - price_feed_pubkey.eq(account_info.key), + require_keys_eq!( + *account_info.owner, + pyth_solana_receiver_sdk::ID, SablierError::TriggerConditionFailed ); const STALENESS_THRESHOLD: u64 = 60; // staleness threshold in seconds - let price_feed = - SolanaPriceAccount::account_info_to_feed(account_info).unwrap(); - let current_timestamp = Clock::get()?.unix_timestamp; - let current_price = price_feed - .get_price_no_older_than(current_timestamp, STALENESS_THRESHOLD) - .unwrap(); + let price_update = + PriceUpdateV2::try_deserialize(&mut account_info.data.borrow().as_ref())?; + + let current_price = price_update.get_price_no_older_than( + &Clock::get()?, + STALENESS_THRESHOLD, + feed_id, + )?; + match equality { Equality::GreaterThanOrEqual => { require!( diff --git a/utils/Cargo.toml b/utils/Cargo.toml index c81f50a9..671d3cdf 100644 --- a/utils/Cargo.toml +++ b/utils/Cargo.toml @@ -19,3 +19,4 @@ base64.workspace = true serde = { workspace = true, features = ["derive"] } static-pubkey.workspace = true sablier-macros = { path = "./macros" } +pyth-solana-receiver-sdk.workspace = true diff --git a/utils/macros/src/lib.rs b/utils/macros/src/lib.rs index 7384658c..6936f817 100644 --- a/utils/macros/src/lib.rs +++ b/utils/macros/src/lib.rs @@ -10,7 +10,7 @@ use syn::{ mod space; -#[proc_macro_derive(MinSpace, attributes(max_len, raw_space, internal))] +#[proc_macro_derive(MinSpace, attributes(max_len, raw_space))] pub fn derive_min_space(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); diff --git a/utils/src/thread.rs b/utils/src/thread.rs index bbfb41bd..d93abb54 100644 --- a/utils/src/thread.rs +++ b/utils/src/thread.rs @@ -5,6 +5,7 @@ use anchor_lang::{ solana_program::{self, instruction::Instruction}, AnchorDeserialize, }; +use pyth_solana_receiver_sdk::price_update::FeedId; use sablier_macros::MinSpace; use serde::{Deserialize, Serialize}; use static_pubkey::static_pubkey; @@ -84,8 +85,9 @@ pub enum Trigger { /// Allows a thread to be kicked off according to a Pyth price feed movement. Pyth { - /// The address of the price feed to monitor. - price_feed: Pubkey, + /// The price feed id to monitor. + #[raw_space(32)] + feed_id: FeedId, // TODO implement in the macro /// The equality operator (gte or lte) used to compare prices. equality: Equality, /// The limit price to compare the Pyth feed to.