switchboard-on-demand 0.5.5

A Rust library to interact with the Switchboard Solana program.
Documentation
use anyhow::{Context, Error as AnyError};

use crate::prelude::*;

#[allow(unused)]
const SLOTS_PER_EPOCH: u64 = 432_000;

#[derive(Clone, Copy)]
pub struct VerifiedBundle<'a> {
    // References to bundle headers (stored as array since headers aren't contiguous)
    bundle_header_refs: &'a crate::on_demand::bundle::feed_info::PackedBundleHeader,
    pub oracle_count: u8, // Number of valid oracles in the array
    // Zero-copy reference to shared packed feed data from first signature
    pub packed_feed_infos: &'a [crate::on_demand::bundle::feed_info::PackedFeedInfo],
    feed_count: u8,       // Number of valid feeds in the array (private, calculated)
    pub oracle_idxs: &'a [u8],
    pub recent_slot: u64, // Recent slot from Ed25519 instruction data
    pub version: u8,      // Version from Ed25519 instruction data
}

impl<'a> VerifiedBundle<'a> {
    /// Creates a new VerifiedBundle with header references and zero-copy feed data
    #[inline(always)]
    pub(crate) fn new(
        bundle_header_ref: &'a crate::on_demand::bundle::feed_info::PackedBundleHeader,
        oracle_count: u8,
        packed_feed_infos: &'a [crate::on_demand::bundle::feed_info::PackedFeedInfo],
        feed_count: u8,
        oracle_idxs: &'a [u8],
        recent_slot: u64,
        version: u8,
    ) -> Self {
        Self {
            bundle_header_refs: bundle_header_ref,
            oracle_count,
            packed_feed_infos,
            feed_count,
            oracle_idxs,
            recent_slot,
            version,
        }
    }

    #[inline(always)]
    pub fn slot(&self) -> u64 {
        // Return the recent slot from Ed25519 instruction data
        self.recent_slot
    }

    #[inline(always)]
    pub fn version(&self) -> u8 {
        // Return the version from Ed25519 instruction data
        self.version
    }

    /// Returns a slice of the valid packed feeds (up to feed_count)
    #[inline(always)]
    pub fn feeds(&self) -> &[crate::on_demand::bundle::feed_info::PackedFeedInfo] {
        &self.packed_feed_infos[..self.feed_count as usize]
    }

    /// Returns the number of valid feeds in this bundle
    #[inline(always)]
    pub fn len(&self) -> usize {
        self.feed_count as usize
    }

    /// Returns true if this bundle contains no feeds
    #[inline(always)]
    pub fn is_empty(&self) -> bool {
        self.feed_count == 0
    }

    /// Returns the oracle index for a specific signature position
    #[inline(always)]
    pub fn oracle_index(&self, signature_index: usize) -> u8 {
        if signature_index < self.oracle_count as usize {
            self.oracle_idxs[signature_index]
        } else {
            panic!(
                "Invalid signature index {} for bundle with {} oracles",
                signature_index, self.oracle_count
            );
        }
    }

    /// Returns an iterator over all valid bundle headers (up to oracle_count)
    #[inline(always)]
    pub fn header(
        &self,
    ) -> &'a crate::on_demand::bundle::feed_info::PackedBundleHeader {
        self.bundle_header_refs
    }

    /// Finds a packed feed with a specific feed ID
    /// # Arguments
    /// * `feed_id` - A 32-byte array representing the feed ID to look for.
    /// # Returns
    /// A `Result` containing a reference to the `PackedFeedInfo` if found and valid
    #[inline(always)]
    pub fn feed(
        &self,
        feed_id: &[u8; 32],
    ) -> Result<&crate::on_demand::bundle::feed_info::PackedFeedInfo, AnyError> {
        let info = self.packed_feed_infos[..self.feed_count as usize]
            .iter()
            .find(|info| info.feed_id() == feed_id)
            .context("Switchboard On-Demand FeedNotFound")?;
        Ok(info)
    }
}