### Rust Pub/Sub Event Client: Starting and Aborting Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/event_client This code provides methods to start the PubSubEventClient and abort its operation. The `start` method uses `tokio::select!` to concurrently listen for cancellation signals or the completion of the `start_pubsub` task. The `abort` method triggers the cancellation token. ```rust impl PubSubEventClientWithHandlers { pub fn abort(self) { self.cancellation_token.cancel(); } pub async fn start(self) { let cancellation_token = self.cancellation_token.clone(); tokio::select! { _ = cancellation_token.cancelled() => { // Perform cleanup log::info!("pubsub token cancelled"); }, _ = self.start_pubsub() => { // Perform cleanup log::info!("start_pubsub returned unexpectedly"); } } } // ... other methods ``` -------------------------------- ### Rust Result 'and' Method Examples Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Demonstrates the behavior of the Result::and method, which returns the second Result if the first is Ok, otherwise returns the first Result's Err. It shows scenarios with both Ok and Err values. ```rust let x: Result = Ok(2); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("late error")); let x: Result = Err("early error"); let y: Result<&str, &str> = Ok("foo"); assert_eq!(x.and(y), Err("early error")); let x: Result = Err("not a 2"); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("not a 2")); let x: Result = Ok(2); let y: Result<&str, &str> = Ok("different result type"); assert_eq!(x.and(y), Ok("different result type")); ``` -------------------------------- ### Rust Result Product Implementation: product Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Shows the implementation of the Product trait for Rust's Result type. This allows for computing the product of an iterator of Results, short-circuiting on the first Err encountered. The example demonstrates parsing strings to numbers and calculating their product. ```rust impl Product> for Result where T: Product, { fn product(iter: I) -> Result where I: Iterator>; } // Example Usage: let nums = vec!["5", "10", "1", "2"]; let total: Result = nums.iter().map(|w| w.parse::()).product(); assert_eq!(total, Ok(100)); let nums = vec!["5", "10", "one", "2"]; let total: Result = nums.iter().map(|w| w.parse::()).product(); assert!(total.is_err()); ``` -------------------------------- ### Get Transaction Instructions (Rust) Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Returns a vector of all instructions associated with the transaction. If no instructions are found, it returns an error indicating that the instructions are empty. This method is crucial for retrieving the instructions to be processed or signed. ```rust pub fn ixs(&self) -> Result, OnDemandError> { if self.ixs.len() == 0 { return Err(OnDemandError::SolanaInstructionsEmpty); } let mut pre_ixs = vec![]; if let Some(compute_units) = self.compute_units { pre_ixs.push(ComputeBudgetInstruction::set_compute_unit_limit( ``` -------------------------------- ### Build Transaction with ArcSwap Payer Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Shows how to construct a transaction using a payer managed by `ArcSwap`. This example verifies that the transaction's payer is correctly set to the public key of the `Keypair` loaded from the `ArcSwap`. ```rust #[tokio::test] async fn test_transaction_builder_with_arcswap_payer() { let payer = arc_swap::ArcSwap::new(Arc::new(Keypair::new())); let payer_arc = payer.load(); let tx = TransactionBuilder::new_with_payer(payer_arc.clone()) .add_ix(Instruction::new_with_borsh( Pubkey::new_unique(), &vec![1u8, 2u8, 3u8, 4u8], vec![ AccountMeta::new(payer_arc.signer_pubkey(), true), AccountMeta::new_readonly(Pubkey::new_unique(), false), ], )) .set_compute_units(750_000); assert_eq!(tx.payer, payer_arc.pubkey()); } ``` -------------------------------- ### Rust Result 'or' Method Examples Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Shows the Result::or method, which returns the second Result if the first is Err, otherwise returns the first Result's Ok value. This method eagerly evaluates its argument. ```rust let x: Result = Ok(2); let y: Result = Err("late error"); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("early error"); let y: Result = Ok(2); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("not a 2"); let y: Result = Err("late error"); assert_eq!(x.or(y), Err("late error")); let x: Result = Ok(2); let y: Result = Ok(100); assert_eq!(x.or(y), Ok(2)); ``` -------------------------------- ### Client Implementations in Rust Source: https://switchboard-on-demand-rust-docs.web.app/type Details various implementation methods for the generic Client struct, where C must implement Clone and Deref to a Signer. These methods include constructors and a method to get a Program instance. ```rust impl Client where C: Clone + Deref { pub fn new(cluster: Cluster, payer: C) -> Client pub fn new_with_options( cluster: Cluster, payer: C, options: CommitmentConfig, ) -> Client pub fn program(&self, program_id: Pubkey) -> Result, ClientError> } ``` -------------------------------- ### Get Payer Keypair with RwLock and OnceCell Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Shows an asynchronous function `get_payer_keypair` that initializes and retrieves a payer `Keypair` wrapped in `Arc>>` using `OnceCell`. This ensures thread-safe, lazy initialization of the payer. ```rust pub static PAYER_KEYPAIR: OnceCell>>> = OnceCell::const_new(); async fn get_payer_keypair() -> &'static Arc>> { PAYER_KEYPAIR .get_or_init(|| async { Arc::new(RwLock::new(Arc::new(Keypair::new()))) }) .await } ``` -------------------------------- ### Basic Usage of unwrap for Ok Result in Rust Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Shows the basic usage of the `unwrap` method on a `Result` to get the `Ok` value. This method panics if the `Result` is an `Err`, so it's generally discouraged in favor of explicit error handling. ```rust let x: Result = Ok(2); assert_eq!(x.unwrap(), 2); ``` -------------------------------- ### Rust: Get Reference to Ok or Err Value Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Demonstrates the `as_ref()` method, which converts a reference to a `Result` into a `Result` containing references to the inner values. This allows inspecting the `Ok` or `Err` content without taking ownership. ```rust let x: Result = Ok(2); assert_eq!(x.as_ref(), Ok(&2)); let x: Result = Err("Error"); assert_eq!(x.as_ref(), Err(&"Error")); ``` -------------------------------- ### Fetch Lookup Table Account (Rust) Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/accounts/oracle This function fetches an Address Lookup Table (LUT) account associated with a given Oracle public key. It first retrieves the Oracle's data to determine the LUT slot and then uses a helper function `address_lookup_table::fetch` to get the actual LUT account. Dependencies include `solana_client` and custom error handling. ```rust pub async fn fetch_lut( &self, oracle_pubkey: &Pubkey, client: &solana_client::nonblocking::rpc_client::RpcClient, ) -> std::result::Result { let oracle = Self::fetch_async(client, *oracle_pubkey).await?; let lut_slot = oracle.lut_slot; let lut = find_lut_of(oracle_pubkey, lut_slot); Ok(address_lookup_table::fetch(client, &lut).await?) } ``` -------------------------------- ### Get Switchboard Program ID by Cluster (Rust) Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/program_id A utility function that returns the appropriate Switchboard program ID based on the provided cluster string. It defaults to the devnet program ID if the cluster string does not start with 'mainnet'. ```rust pub fn get_sb_program_id(cluster: &str) -> Pubkey { if !cluster.starts_with("mainnet") { ON_DEMAND_DEVNET_PID } else { ON_DEMAND_MAINNET_PID } } ``` -------------------------------- ### Build Oracle Heartbeat Instruction (Rust) Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/instructions/oracle_heartbeat This Rust code snippet constructs an oracle heartbeat instruction for the Switchboard On-Demand system. It reads the cluster environment variable, retrieves the program ID, and then builds the instruction with provided accounts and parameters. It also iterates through pending paid accounts and escrow accounts, adding them to the instruction's account list. Dependencies include the `std::env` module and custom `crate::utils` and state structures. ```rust let cluster = std::env::var("CLUSTER").unwrap_or("mainnet".to_string()); let pid = get_sb_program_id(&cluster); let mut ix = crate::utils::build_ix( &pid, &OracleHeartbeatAccounts { oracle: args.oracle, oracle_signer: args.oracle_signer, queue: args.queue, queue_authority: args.queue_authority, gc_node: args.gc_node, payer: args.payer, stake_program: state.stake_program, delegation_pool: delegation_pool, delegation_group: delegation_group, switch_mint: state.switch_mint, }, &OracleHeartbeatParams { uri: args.uri }, ); for ppa in args.pending_paid_accounts { ix.accounts.push(AccountMeta::new_readonly(ppa, false)); } for escrow in args.escrows { ix.accounts.push(AccountMeta::new(escrow, false)); } Ok(ix) } } } ``` -------------------------------- ### Rust: Build QueueGarbageCollect Instruction Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/instructions/queue_garbage_collect This Rust code defines the necessary structures and methods to build a `QueueGarbageCollect` instruction for the Switchboard On-Demand program. It includes account metadata and argument handling. Dependencies include the `solana_program` crate and custom `anchor_traits`, `prelude`, and `utils` modules. ```rust use crate::anchor_traits::* use crate::prelude::* use borsh::BorshSerialize; use solana_program::pubkey::Pubkey; use crate::get_sb_program_id; pub struct QueueGarbageCollect {} #[derive(Clone, BorshSerialize, Debug)] pub struct QueueGarbageCollectParams { pub idx: u32, } impl InstructionData for QueueGarbageCollectParams {} impl Discriminator for QueueGarbageCollect { const DISCRIMINATOR: [u8; 8] = [187, 208, 104, 247, 16, 91, 96, 98]; } impl Discriminator for QueueGarbageCollectParams { const DISCRIMINATOR: [u8; 8] = QueueGarbageCollect::DISCRIMINATOR; } pub struct QueueGarbageCollectArgs { pub queue: Pubkey, pub oracle: Pubkey, pub idx: u32, } pub struct QueueGarbageCollectAccounts { pub queue: Pubkey, pub oracle: Pubkey, } impl ToAccountMetas for QueueGarbageCollectAccounts { fn to_account_metas(&self, _: Option) -> Vec { vec![ AccountMeta::new(self.queue, false), AccountMeta::new(self.oracle, false), ] } } impl QueueGarbageCollect { pub fn build_ix(args: QueueGarbageCollectArgs) -> Result { let cluster = std::env::var("CLUSTER").unwrap_or("mainnet".to_string()); let pid = get_sb_program_id(&cluster); Ok(crate::utils::build_ix( &pid, &QueueGarbageCollectAccounts { queue: args.queue, oracle: args.oracle, }, &QueueGarbageCollectParams { idx: args.idx }, )) } } ``` -------------------------------- ### Rust Build OracleHeartbeat Instruction Client-Side Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/instructions/oracle_heartbeat Asynchronously builds an OracleHeartbeat instruction using a Solana RPC client. It fetches state data and calculates Program Derived Addresses (PDAs) for delegation pools and groups based on provided arguments and current state. Requires `solana-client` and custom crate modules. ```rust cfg_client! { use solana_client::nonblocking::rpc_client::RpcClient; impl OracleHeartbeat { pub async fn build_ix(client: &RpcClient, args: OracleHeartbeatArgs) -> Result { let state_key = State::get_pda(); let state = State::fetch_async(client).await?; let (delegation_pool, _) = Pubkey::find_program_address( &[ b"Delegation", &state_key.to_bytes(), &OracleAccountData::stats_key(&args.oracle).to_bytes(), &state.stake_pool.to_bytes(), ], &state.stake_program, ); let (delegation_group, _) = Pubkey::find_program_address( &[ b"Group", &state_key.to_bytes(), &state.stake_pool.to_bytes(), &args.queue.to_bytes(), ], &state.stake_program, ); ``` -------------------------------- ### Rust: Get TypeId of self Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/pull_feed/struct This function retrieves the `TypeId` of the current object. It is part of the `Any` trait implementation. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Rust: Get Discriminator Value Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/queue/struct Retrieves the 8-byte discriminator for QueueAccountData. This function is part of the Owner implementation for QueueAccountData. ```rust fn discriminator() -> [u8; 8] ``` -------------------------------- ### Rust: Get Owned Data Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/queue/struct Creates owned data from borrowed data, typically by cloning. This is part of the ToOwned trait. ```rust fn to_owned(&self) -> T ``` -------------------------------- ### TransactionBuilder Constructor Methods Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Provides multiple ways to initialize a `TransactionBuilder`. Methods include `new` (with just a payer), `new_with_payer` (accepting an `AsSigner` for the payer and adding it to signers), `new_with_ixs` (with payer and initial instructions), and `new_with_payer_and_ixs` (combining `AsSigner` payer with initial instructions). These constructors streamline the process of setting up a transaction. ```rust impl TransactionBuilder { pub fn new(payer: Pubkey) -> Self { Self { payer, ..Default::default() } } pub fn new_with_payer(payer: Arc) -> Self { Self { payer: payer.as_signer().pubkey(), signers: vec![Arc::clone(&payer)], ..Default::default() } } pub fn new_with_ixs(payer: Pubkey, ixs: impl IntoIterator) -> Self { Self { payer, ixs: ixs.into_iter().collect::>(), ..Default::default() } } pub fn new_with_payer_and_ixs( payer: Arc, ixs: impl IntoIterator, ) -> Self { Self { payer: payer.as_signer().pubkey(), signers: vec![Arc::clone(&payer)], ixs: ixs.into_iter().collect::>(), ..Default::default() } } // Builder methods, consumes self and returns self pub fn set_compute_units(mut self, compute_units: u32) -> Self { self.compute_units = Some(compute_units); self } pub fn set_priority_fees(mut self, priority_fees: u64) -> Self { self.priority_fees = Some(priority_fees); self } pub fn add_ix(mut self, ix: Instruction) -> Self { self.ixs.push(ix); self } pub fn has_signer(&self, signer: Pubkey) -> bool { self.signers .iter() .find(|s| s.as_signer().pubkey() == signer) .is_some() } pub fn has_payer(&self) -> bool { self.has_signer(self.payer) } pub fn add_signer(mut self, signer: Arc) -> TransactionBuilder { let signer_key = signer.as_signer().pubkey(); if let None = self .signers ``` -------------------------------- ### Build Solana Instruction (Rust) Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/utils Constructs a Solana `Instruction` object given a program ID, accounts, and instruction data. This is a fundamental utility for creating on-chain calls. ```rust use solana_program::instruction::Instruction; use solana_program::pubkey::Pubkey; use crate::anchor_traits::{ToAccountMetas, InstructionData, Discriminator}; pub fn build_ix( program_id: &Pubkey, accounts: &A, params: &I, ) -> Instruction { Instruction { program_id: *program_id, accounts: accounts.to_account_metas(None), data: params.data(), } } ``` -------------------------------- ### Rust: Dereference Pointer Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/queue/struct Dereferences a raw pointer to get an immutable reference to the value. This is an unsafe function from the Pointable trait. ```rust unsafe fn deref<'a>(ptr: usize) -> &'a T ``` -------------------------------- ### Rust: Mutably Dereference Pointer Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/queue/struct Dereferences a raw pointer to get a mutable reference to the value. This is an unsafe function from the Pointable trait. ```rust unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T ``` -------------------------------- ### Rust: Get Owner Public Key Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/queue/struct Returns the public key associated with the owner of QueueAccountData. This function is part of the Owner implementation. ```rust fn owner() -> Pubkey ``` -------------------------------- ### Add Compute Budget Instructions to Transaction Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Demonstrates how to add instructions to a transaction builder and set compute units and priority fees. It shows that setting compute units adds one instruction, setting priority fees adds another, and setting both adds a third instruction. ```rust #[test] fn test_add_compute_budget_ixs() { let payer = Arc::new(Keypair::new()); let payer_pubkey = payer.pubkey(); let tx = TransactionBuilder::new_with_payer(payer.clone()) .add_ix(Instruction::new_with_borsh( Pubkey::new_unique(), &vec![1u8, 2u8, 3u8, 4u8], vec![ AccountMeta::new(payer_pubkey, true), AccountMeta::new_readonly(Pubkey::new_unique(), false), ], )) .set_compute_units(750_000); assert_eq!(tx.ixs().unwrap_or_default().len(), 2); let tx = TransactionBuilder::new_with_payer(payer.clone()) .add_ix(Instruction::new_with_borsh( Pubkey::new_unique(), &vec![1u8, 2u8, 3u8, 4u8], vec![ AccountMeta::new(payer_pubkey, true), AccountMeta::new_readonly(Pubkey::new_unique(), false), ], )) .set_priority_fees(500); assert_eq!(tx.ixs().unwrap_or_default().len(), 2); let tx = TransactionBuilder::new_with_payer(payer.clone()) .add_ix(Instruction::new_with_borsh( Pubkey::new_unique(), &vec![1u8, 2u8, 3u8, 4u8], vec![ AccountMeta::new(payer_pubkey, true), AccountMeta::new_readonly(Pubkey::new_unique(), false), ], )) .set_compute_units(750_000) .set_priority_fees(500); assert_eq!(tx.ixs().unwrap_or_default().len(), 3); } ``` -------------------------------- ### Get All Oracle Keys in Rust Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/accounts/queue Returns a vector containing all active oracle public keys. It slices the `oracle_keys` array up to the `oracle_keys_len` and converts it into a new `Vec`. ```rust pub fn oracle_keys(&self) -> Vec { self.oracle_keys[..self.oracle_keys_len as usize].to_vec() } ``` -------------------------------- ### IpfsManager IPFS Get Methods in Rust Source: https://switchboard-on-demand-rust-docs.web.app/ipfs/struct Asynchronous methods for retrieving data from IPFS. `get_bytes` fetches raw bytes, while `get_object` deserializes IPFS content into a specified type `T`. ```rust pub async fn get_bytes(&self, cid: String) -> Result, SbError> ``` ```rust pub async fn get_object(&self, cid: String) -> Result where T: for<'a> Deserialize<'a> + Default ``` -------------------------------- ### Import Switchboard On-Demand Core and Common Types (Rust) Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/prelude This snippet imports essential modules and types from the Switchboard On-Demand crate, including account definitions, configuration client, decimal types, instruction builders, and common utility types like timestamps and result structures. It also imports the necessary Anchor client and Solana program modules. ```rust pub use crate::accounts::*; use crate::cfg_client; pub use crate::decimal::*; pub use crate::instructions::*; pub use crate::types::*; pub use crate::{SWITCHBOARD_ON_DEMAND_PROGRAM_ID, SWITCHBOARD_PROGRAM_ID}; pub use rust_decimal; pub use switchboard_common::{ unix_timestamp, ChainResultInfo, FunctionResult, FunctionResultV0, FunctionResultV1, LegacyChainResultInfo, LegacySolanaFunctionResult, SolanaFunctionRequestType, SolanaFunctionResult, SolanaFunctionResultV0, SolanaFunctionResultV1, FUNCTION_RESULT_PREFIX, }; cfg_client! { pub use crate::client::*; use anchor_client; use anchor_client::anchor_lang::solana_program; } pub use solana_program::entrypoint::ProgramResult; pub use solana_program::instruction::{AccountMeta, Instruction}; pub use solana_program::program::{invoke, invoke_signed}; pub use std::result::Result; ``` -------------------------------- ### Rust Result 'unwrap_or' Method Examples Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Shows the Result::unwrap_or method, which returns the contained Ok value or a provided default if the Result is Err. The default value is eagerly evaluated. ```rust let default = 2; let x: Result = Ok(9); assert_eq!(x.unwrap_or(default), 9); let x: Result = Err("error"); assert_eq!(x.unwrap_or(default), default); ``` -------------------------------- ### Create Solana Transaction from Instructions Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/utils Constructs a Solana `Transaction` from a list of `Instruction`s, signers, and a recent blockhash. It handles signing the transaction with the provided signers. Dependencies include Solana SDK crates. ```rust use crate::prelude::*; use solana_sdk::transaction::Transaction; use solana_sdk::message::Message; use solana_program::hash::Hash; pub fn ix_to_tx( ixs: &[Instruction], signers: &[&Keypair], blockhash: Hash, ) -> Result { let msg = Message::new(ixs, Some(&signers[0].pubkey())); let mut tx = Transaction::new_unsigned(msg); tx.try_sign(&signers.to_vec(), blockhash) .map_err(|_e| OnDemandError::SolanaSignError)?; Ok(tx) } ``` -------------------------------- ### Rust: Traits for POD and NoUninit Types Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/state/struct These traits, `AnyBitPattern` and `NoUninit`, are marker traits for types that satisfy specific memory layout and initialization requirements, typically associated with the `Pod` trait. ```rust impl AnyBitPattern for T where T: Pod ``` ```rust impl NoUninit for T where T: Pod ``` -------------------------------- ### Rust: Get Mutable Reference to Ok or Err Value Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Explains the `as_mut()` method, which provides mutable references to the contained values within a `Result`. This is useful for modifying the `Ok` or `Err` value in place. ```rust fn mutate(r: &mut Result) { match r.as_mut() { Ok(v) => *v = 42, Err(e) => *e = 0, } } let mut x: Result = Ok(2); mutate(&mut x); assert_eq!(x.unwrap(), 42); let mut x: Result = Err(13); mutate(&mut x); assert_eq!(x.unwrap_err(), 0); ``` -------------------------------- ### Build V0 Solana Transaction Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Initiates the construction of a v0 Solana transaction. This function signature suggests it will take a payer, a vector of instructions, and a vector of signers. The implementation would then use these parameters to create a `Transaction` object suitable for v0 transaction standards. Dependencies would include `solana_sdk` components. ```rust pub fn build_v0_tx( payer: Pubkey, ixs: Vec, signers: Vec<&dyn Signer>, ``` -------------------------------- ### Get Secp256k1 Authority Key in Rust Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/accounts/oracle Retrieves the Secp256k1 authority key from an Oracle account. Returns `None` if the key is the default value (64 zero bytes), indicating no Secp256k1 authority is set. ```rust pub fn secp_authority(&self) -> Option<[u8; 64]> { let key = self.secp_authority; if key == [0u8; 64] { return None; } Some(key) } ``` -------------------------------- ### Rust Result 'or_else' Method Examples Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Demonstrates the Result::or_else method, which calls a closure only if the Result is Err, providing a fallback mechanism. This is useful for lazily evaluating alternative error handling strategies. ```rust fn sq(x: u32) -> Result { Ok(x * x) } fn err(x: u32) -> Result { Err(x) } assert_eq!(Ok(2).or_else(sq).or_else(sq), Ok(2)); assert_eq!(Ok(2).or_else(err).or_else(sq), Ok(2)); assert_eq!(Err(3).or_else(sq).or_else(err), Ok(9)); assert_eq!(Err(3).or_else(err).or_else(err), Err(3)); ``` -------------------------------- ### OracleAccountData Size Calculation and Constructor Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/accounts/oracle Provides a static method `size()` to calculate the total size of the `OracleAccountData` including its discriminator. Also includes a constructor `new()` for creating an instance from a Solana `AccountInfo`. ```rust impl OracleAccountData { pub fn size() -> usize { 8 + std::mem::size_of::() } /// Returns the deserialized Switchboard Quote account /// /// # Arguments /// /// * `quote_account_info` - A Solana AccountInfo referencing an existing Switchboard QuoteAccount /// /// # Examples /// /// ```ignore /// use switchboard_on_demand::OracleAccountData; /// /// let quote_account = OracleAccountData::new(quote_account_info)?; /// ``` pub fn new<'info>( quote_account_info: &'info AccountInfo<'info>, ) -> Result, OnDemandError> { let data = quote_account_info .try_borrow_data() .map_err(|_| OnDemandError::AccountBorrowError)?; ``` -------------------------------- ### Get Payer Public Key from Transaction Builder (Rust) Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Returns the public key of the transaction's payer. This is a simple getter method that accesses the `payer` field of the `TransactionBuilder` struct. ```rust // Getters pub fn payer(&self) -> Pubkey { self.payer } ``` -------------------------------- ### Rust Result 'unwrap_err_unchecked' Unsafe Method Examples Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Shows the unsafe Result::unwrap_err_unchecked method, which returns the contained Err value without checking if it's an Ok. Calling this on an Ok results in undefined behavior. ```rust let x: Result = Ok(2); unsafe { x.unwrap_err_unchecked() }; // Undefined behavior! ``` ```rust let x: Result = Err("emergency failure"); assert_eq!(unsafe { x.unwrap_err_unchecked() }, "emergency failure"); ``` -------------------------------- ### Rust State PDA and Fetching Methods Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/accounts/state Provides utility methods for the `State` struct in Rust, including calculating the account size, deriving the Program Derived Address (PDA) for the state, and fetching the state account asynchronously using a Solana RPC client. It dynamically determines the program ID based on the `CLUSTER` environment variable. ```rust impl State { pub fn size() -> usize { 8 + std::mem::size_of::() } pub fn get_pda() -> Pubkey { let cluster = std::env::var("CLUSTER").unwrap_or("mainnet".to_string()); let pid = get_sb_program_id(&cluster); let (pda_key, _) = Pubkey::find_program_address(&[STATE_SEED], &pid); pda_key } pub fn get_program_pda(program_id: Option) -> Pubkey { let cluster = std::env::var("CLUSTER").unwrap_or("mainnet".to_string()); let pid = get_sb_program_id(&cluster); let (pda_key, _) = Pubkey::find_program_address( &[STATE_SEED], &program_id.unwrap_or(pid), ); pda_key } cfg_client! { pub async fn fetch_async( client: &solana_client::nonblocking::rpc_client::RpcClient, ) -> std::result::Result { let pubkey = State::get_pda(); crate::client::fetch_zerocopy_account_async(client, pubkey).await } } } ``` -------------------------------- ### Rust Result 'unwrap_unchecked' Unsafe Method Examples Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Demonstrates the unsafe Result::unwrap_unchecked method, which returns the contained Ok value without checking if it's an Err. Calling this on an Err results in undefined behavior. ```rust let x: Result = Ok(2); assert_eq!(unsafe { x.unwrap_unchecked() }, 2); ``` ```rust let x: Result = Err("emergency failure"); unsafe { x.unwrap_unchecked(); } // Undefined behavior! ``` -------------------------------- ### IpfsManager Constructor Methods in Rust Source: https://switchboard-on-demand-rust-docs.web.app/ipfs/struct Provides methods for creating instances of IpfsManager. `from_env` creates an instance using environment variables, while `new` takes explicit IPFS connection details. ```rust pub fn from_env() -> Result ``` ```rust pub fn new(ipfs_url: &str, ipfs_key: &str, ipfs_secret: &str) -> IpfsManager ``` -------------------------------- ### Rust Result 'unwrap_or_else' Method Examples Source: https://switchboard-on-demand-rust-docs.web.app/prelude/type Illustrates the Result::unwrap_or_else method, which returns the contained Ok value or computes a default value using a closure if the Result is Err. This allows for lazy evaluation of the default. ```rust fn count(x: &str) -> usize { x.len() } assert_eq!(Ok(2).unwrap_or_else(count), 2); assert_eq!(Err("foo").unwrap_or_else(count), 3); ``` -------------------------------- ### Fetch Multiple Address Lookup Accounts Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Fetches multiple address lookup table accounts from the Solana RPC using `get_multiple_accounts`. It takes an `RpcClient` and a vector of public keys. It handles cases where no public keys are provided and deserializes the account data, returning a vector of `AddressLookupTableAccount` structs or an error. Dependencies include `solana_client::rpc::RpcClient`, `solana_sdk::pubkey::Pubkey`, and `OnDemandError`. ```rust pub async fn fetch_multiple_address_lookup_accounts( rpc: &RpcClient, address_lookup_pubkeys: Vec, ) -> Result, OnDemandError> { let address_lookup_accounts: Vec = if address_lookup_pubkeys.is_empty() { vec![] } else { let accounts = rpc .get_multiple_accounts(&address_lookup_pubkeys) .await .map_err(|_| OnDemandError::NetworkError)?; let mut address_lookup_accounts: Vec = vec![]; for (i, account) in accounts.iter().enumerate() { let account = account.as_ref().ok_or(OnDemandError::AccountNotFound)?; let address_lookup_table = AddressLookupTable::deserialize(&account.data) .map_err(|_| OnDemandError::AccountDeserializeError)?; let address_lookup_table_account = AddressLookupTableAccount { key: address_lookup_pubkeys[i], addresses: address_lookup_table.addresses.to_vec(), }; address_lookup_accounts.push(address_lookup_table_account); } address_lookup_accounts }; Ok(address_lookup_accounts) } ``` -------------------------------- ### Rust: Build AttestationPermissionSet Instruction Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/instructions/permission_set This Rust code defines the `AttestationPermissionSet` instruction, which allows for managing permissions related to oracles and queues. It includes account metas and a builder function to construct the instruction with specified permissions and enablement. ```rust use crate::anchor_traits::* use crate::prelude::* use borsh::BorshSerialize; use solana_program::pubkey::Pubkey; use crate::get_sb_program_id; #[repr(u32)] #[derive(Copy, Clone)] pub enum SwitchboardPermission { None = 0 << 0, PermitOracleHeartbeat = 1 << 0, PermitOracleQueueUsage = 1 << 1, } pub struct AttestationPermissionSet {} #[derive(Clone, BorshSerialize, Debug)] pub struct AttestationPermissionSetParams { pub permission: u8, pub enable: bool, } impl InstructionData for AttestationPermissionSetParams {} impl Discriminator for AttestationPermissionSetParams { const DISCRIMINATOR: [u8; 8] = AttestationPermissionSet::DISCRIMINATOR; } impl Discriminator for AttestationPermissionSet { const DISCRIMINATOR: [u8; 8] = [211, 122, 185, 120, 129, 182, 55, 103]; } pub struct AttestationPermissionSetAccounts { pub authority: Pubkey, pub granter: Pubkey, pub grantee: Pubkey, } impl ToAccountMetas for AttestationPermissionSetAccounts { fn to_account_metas(&self, _: Option) -> Vec { vec![ AccountMeta::new_readonly(self.authority, true), AccountMeta::new_readonly(self.granter, false), AccountMeta::new(self.grantee, false), ] } } impl AttestationPermissionSet { pub fn build_ix( granter: Pubkey, authority: Pubkey, grantee: Pubkey, permission: SwitchboardPermission, enable: bool, ) -> Result { let cluster = std::env::var("CLUSTER").unwrap_or("mainnet".to_string()); let pid = get_sb_program_id(&cluster); Ok(crate::utils::build_ix( &pid, &AttestationPermissionSetAccounts { authority, granter, grantee, }, &AttestationPermissionSetParams { permission: permission as u8, enable, }, )) } } ``` -------------------------------- ### Load Keypair from File System (Rust) Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/utils Loads a `Keypair` from a specified file path on the file system. It handles potential I/O errors during file reading and returns an `OnDemandError` if the operation fails. ```rust pub fn load_keypair_fs(fs_path: &str) -> Result, OnDemandError> { match read_keypair_file(fs_path) { Ok(keypair) => Ok(Arc::new(keypair)), Err(e) => { if let Some(err) = e.source() { println!("Failed to read keypair file -- {}", err); } Err(OnDemandError::IoError) } } } ``` -------------------------------- ### Rust Blanket Implementations for State: CheckedBitPattern and CloneToUninit Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/state/struct Demonstrates blanket implementations for `CheckedBitPattern` and `CloneToUninit`. `CheckedBitPattern` aids in validating bit patterns for types that can be represented as raw bits. `CloneToUninit` provides methods for cloning data into uninitialized memory, often used in performance-critical scenarios. ```rust impl CheckedBitPattern for T where T: AnyBitPattern, type Bits = T fn is_valid_bit_pattern(_bits: &T) -> bool impl CloneToUninit for T where T: Clone, default unsafe fn clone_to_uninit(&self, dst: *mut T) impl CloneToUninit for T where T: Copy, unsafe fn clone_to_uninit(&self, dst: *mut T) ``` -------------------------------- ### Get Ed25519 Signer Public Key in Rust Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/on_demand/accounts/oracle Retrieves the Ed25519 signer's public key from an Oracle account. Returns `None` if the public key is the default value (all zeros), indicating no Ed25519 signer is configured. ```rust pub fn ed25519_signer(&self) -> Option { let key = self.enclave.enclave_signer; if key == Pubkey::default() { return None; } Some(key) } ``` -------------------------------- ### Rust Pub/Sub Event Client Builder Initialization Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/event_client This snippet shows the initialization of the PubSubEventClientBuilder. It sets the program ID and WebSocket URL, automatically converting http/https to ws/wss. It also initializes an empty vector for other public keys and sets the maximum retries to None by default. ```rust impl PubSubEventClientBuilder { // Creates a new builder with the provided WebSocket URL pub fn new(program_id: Pubkey, websocket_url: String) -> Self { Self { program_id, websocket_url: websocket_url .replace("https://", "wss://") .replace("http://", "ws://"), other_pubkeys: Vec::new(), max_retries: None, } } // ... other methods ``` -------------------------------- ### Get Oracle Account Size in Rust Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/oracle/struct Provides a static method `size()` to retrieve the memory size of the `OracleAccountData` struct in bytes. This is useful for calculating account rent or performing other size-related operations. ```rust pub fn size() -> usize ``` -------------------------------- ### Build Legacy Solana Transaction Source: https://switchboard-on-demand-rust-docs.web.app/src/switchboard_on_demand/client/transaction_builder Constructs a legacy Solana transaction from a payer, instructions, signers, and a recent blockhash. It handles transaction signing and returns a Result indicating success or a Solana-specific error. Dependencies include the `solana_sdk` crate for `Transaction`, `Pubkey`, `Signer`, and `Hash`. ```rust pub fn build_legacy_tx( payer: Pubkey, ixs: Vec, signers: Vec<&dyn Signer>, recent_blockhash: Hash, ) -> Result { let mut tx = Transaction::new_with_payer(&ixs, Some(&payer)); tx.try_sign(&signers, recent_blockhash).map_err(|_| OnDemandError::SolanaSignError)?; Ok(tx) } ``` -------------------------------- ### Rust: Pointer Initialization and Dereferencing Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/state/struct Implements the `Pointable` trait for raw pointer operations. It includes methods for getting pointer alignment, initializing memory, dereferencing pointers to immutable or mutable references, and dropping pointed-to objects. ```rust const ALIGN: usize type Init = T; unsafe fn init(init: ::Init) -> usize; unsafe fn deref<'a>(ptr: usize) -> &'a T; unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T; unsafe fn drop(ptr: usize); ``` -------------------------------- ### Dereference raw pointer to get reference Source: https://switchboard-on-demand-rust-docs.web.app/on_demand/accounts/randomness/struct Dereferences a raw pointer (`usize`) to obtain an immutable reference (`&'a T`) to the object it points to. This is an unsafe operation and requires that the pointer is valid and points to an initialized object of type `T`. The lifetime `'a` is determined by the context. ```rust impl Pointable for T where T: Pod ``` ```rust unsafe fn deref<'a>(ptr: usize) -> &'a T ```