switchboard-on-demand 0.4.8

A Rust library to interact with the Switchboard Solana program.
Documentation
#[cfg(feature = "anchor")]
use anchor_lang::solana_program;
use anyhow::{bail, Error as AnyhowError};
use solana_program::secp256k1_program;
use solana_program::sysvar::instructions::get_instruction_relative;

use crate::{ParsedSignatureData, SecpSysvar};

#[derive(Copy, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct Instructions;

#[cfg(feature = "anchor")]
impl anchor_lang::solana_program::sysvar::SysvarId for Instructions {
    fn id() -> solana_program::pubkey::Pubkey {
        solana_program::sysvar::instructions::id().to_bytes().into()
    }

    fn check_id(id: &solana_program::pubkey::Pubkey) -> bool {
        solana_program::sysvar::instructions::id() == id.to_bytes().into()
    }
}
#[cfg(feature = "anchor")]
impl anchor_lang::solana_program::sysvar::Sysvar for Instructions {
    // override
    fn size_of() -> usize {
        // hard-coded so that we don't have to construct an empty
        0 // golden, update if MAX_ENTRIES changes
    }
    fn from_account_info(
        _account_info: &anchor_lang::prelude::AccountInfo,
    ) -> Result<Self, solana_program::program_error::ProgramError> {
        Ok(Self {})
    }
}

impl Instructions {
    pub fn load_secp_ix(
        ix_sysvar: &solana_program::account_info::AccountInfo,
    ) -> Result<Vec<ParsedSignatureData>, AnyhowError> {
        let mut idx = -1;
        while let Ok(ix) = get_instruction_relative(idx, ix_sysvar) {
            if ix.program_id == secp256k1_program::ID {
                return SecpSysvar::parse_combined_secp256k1_instruction(&ix.data);
            }
            idx -= 1;
        }
        bail!("No secp256k1 instruction found in the instruction sysvar")
    }
}