switchboard-on-demand 0.5.5

A Rust library to interact with the Switchboard Solana program.
Documentation
use solana_program::instruction::Instruction;
use solana_program::pubkey::Pubkey;
use solana_program::{hash, pubkey};

use crate::anchor_traits::*;

/// Check if devnet environment is enabled via feature flag OR SB_ENV environment variable
pub fn is_devnet() -> bool {
    cfg!(feature = "devnet") || std::env::var("SB_ENV").unwrap_or_default() == "devnet"
}

pub const SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID: Pubkey =
    pubkey!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");

pub const SPL_TOKEN_PROGRAM_ID: Pubkey = pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");

pub fn find_associated_token_address(owner: &Pubkey, mint: &Pubkey) -> Pubkey {
    let (akey, _bump) = Pubkey::find_program_address(
        &[owner.as_ref(), SPL_TOKEN_PROGRAM_ID.as_ref(), mint.as_ref()],
        &SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
    );
    akey
}

pub fn get_ixn_discriminator(ixn_name: &str) -> [u8; 8] {
    let preimage = format!("global:{}", ixn_name);
    let mut sighash = [0u8; 8];
    sighash.copy_from_slice(&solana_program::hash::hash(preimage.as_bytes()).to_bytes()[..8]);
    sighash
}

pub fn get_account_discriminator(account_name: &str) -> [u8; 8] {
    let id = format!("account:{}", account_name);
    hash::hash(id.as_bytes()).to_bytes()[..8]
        .try_into()
        .unwrap()
}


// #[inline(always)]
// pub fn fast_array_eq_32(a: &[u8; 32], b: &[u8; 32]) -> bool {
    // unsafe {
        // // Direct pointer access - fastest possible on SBF
        // let ap = a.as_ptr() as *const u64;
        // let bp = b.as_ptr() as *const u64;
//
        // // Branchless comparison using XOR+OR pattern
        // let d0 = core::ptr::read_unaligned(ap) ^ core::ptr::read_unaligned(bp);
        // let d1 = core::ptr::read_unaligned(ap.add(1)) ^ core::ptr::read_unaligned(bp.add(1));
        // let d2 = core::ptr::read_unaligned(ap.add(2)) ^ core::ptr::read_unaligned(bp.add(2));
        // let d3 = core::ptr::read_unaligned(ap.add(3)) ^ core::ptr::read_unaligned(bp.add(3));
//
        // (d0 | d1 | d2 | d3) == 0
    // }
// }
//
// use solana_program::program_memory::sol_memcmp;
//
// #[inline(always)]
// pub fn fast_pubkey_eq(a: &Pubkey, b: &Pubkey) -> bool {
    // // One syscall, no unaligned math, minimal CU
    // sol_memcmp(
        // a.as_ref(),
        // b.as_ref(),
        // 32,
    // ) == 0
// }

pub fn build_ix<A: ToAccountMetas, I: InstructionData + Discriminator + std::fmt::Debug>(
    program_id: &Pubkey,
    accounts: &A,
    params: &I,
) -> Instruction {
    Instruction {
        program_id: *program_id,
        accounts: accounts.to_account_metas(None),
        data: params.data(),
    }
}