switchboard_on_demand/
utils.rs1use solana_program::instruction::Instruction;
2
3use crate::anchor_traits::*;
4use crate::solana_compat::{hash, pubkey};
5use crate::{solana_program, Pubkey};
6
7#[inline(always)]
9pub fn is_devnet() -> bool {
10 cfg!(feature = "devnet") || std::env::var("SB_ENV").unwrap_or_default() == "devnet"
11}
12
13pub const DEFAULT_DEVNET_QUEUE: Pubkey = pubkey!("EYiAmGSdsQTuCw413V5BzaruWuCCSDgTPtBGvLkXHbe7");
15pub const DEFAULT_MAINNET_QUEUE: Pubkey = pubkey!("A43DyUGA7s8eXPxqEjJY6EBu1KKbNgfxF8h17VAHn13w");
17
18#[inline(always)]
20pub fn default_queue() -> Pubkey {
21 if is_devnet() {
22 DEFAULT_DEVNET_QUEUE
23 } else {
24 DEFAULT_MAINNET_QUEUE
25 }
26}
27
28pub const SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID: Pubkey =
30 pubkey!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
31
32pub const SPL_TOKEN_PROGRAM_ID: Pubkey = pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
34
35pub const NATIVE_MINT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
36
37pub const ADDRESS_LOOKUP_TABLE_PROGRAM_ID: Pubkey =
39 pubkey!("AddressLookupTab1e1111111111111111111111111");
40
41pub const SYSTEM_PROGRAM_ID: Pubkey = pubkey!("11111111111111111111111111111111");
43
44pub fn find_associated_token_address(owner: &Pubkey, mint: &Pubkey) -> Pubkey {
46 let (akey, _bump) = Pubkey::find_program_address(
47 &[owner.as_ref(), SPL_TOKEN_PROGRAM_ID.as_ref(), mint.as_ref()],
48 &SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
49 );
50 akey
51}
52
53pub fn get_ixn_discriminator(ixn_name: &str) -> [u8; 8] {
55 let preimage = format!("global:{}", ixn_name);
56 let mut sighash = [0u8; 8];
57 sighash.copy_from_slice(&hash::hash(preimage.as_bytes()).to_bytes()[..8]);
58 sighash
59}
60
61pub fn get_account_discriminator(account_name: &str) -> [u8; 8] {
63 let id = format!("account:{}", account_name);
64 hash::hash(id.as_bytes()).to_bytes()[..8]
65 .try_into()
66 .unwrap()
67}
68
69#[inline(always)]
77pub unsafe fn read_u64_at(ptr: *const u64, offset: usize) -> u64 {
78 core::ptr::read_unaligned(ptr.add(offset))
79}
80
81#[inline(always)]
89pub unsafe fn read(ptr: *const u64, offset: usize) -> u64 {
90 *ptr.add(offset)
91}
92
93#[inline(always)]
95pub fn check_pubkey_eq<L: AsRef<[u8]>, R: AsRef<[u8]>>(lhs: L, rhs: R) -> bool {
96 let lhs_bytes = lhs.as_ref();
97 let rhs_bytes = rhs.as_ref();
98
99 unsafe {
100 let lhs_ptr = lhs_bytes.as_ptr() as *const u64;
101 let rhs_ptr = rhs_bytes.as_ptr() as *const u64;
102 core::ptr::read_unaligned(lhs_ptr) == core::ptr::read_unaligned(rhs_ptr)
103 && core::ptr::read_unaligned(lhs_ptr.add(1))
104 == core::ptr::read_unaligned(rhs_ptr.add(1))
105 && core::ptr::read_unaligned(lhs_ptr.add(2))
106 == core::ptr::read_unaligned(rhs_ptr.add(2))
107 && core::ptr::read_unaligned(lhs_ptr.add(3))
108 == core::ptr::read_unaligned(rhs_ptr.add(3))
109 }
110}
111
112#[inline(always)]
120pub unsafe fn check_p64_eq(lhs_ptr: *const u64, rhs_ptr: *const u64) -> bool {
121 core::ptr::read_unaligned(lhs_ptr) == core::ptr::read_unaligned(rhs_ptr)
122 && core::ptr::read_unaligned(lhs_ptr.add(1)) == core::ptr::read_unaligned(rhs_ptr.add(1))
123 && core::ptr::read_unaligned(lhs_ptr.add(2)) == core::ptr::read_unaligned(rhs_ptr.add(2))
124 && core::ptr::read_unaligned(lhs_ptr.add(3)) == core::ptr::read_unaligned(rhs_ptr.add(3))
125}
126
127pub fn build_ix<A: ToAccountMetas, I: InstructionData + Discriminator + std::fmt::Debug>(
129 program_id: &Pubkey,
130 accounts: &A,
131 params: &I,
132) -> Instruction {
133 Instruction {
134 program_id: *program_id,
135 accounts: accounts.to_account_metas(None),
136 data: params.data(),
137 }
138}
139
140pub fn derive_lookup_table_address(
141 authority_address: &Pubkey,
142 recent_block_slot: u64,
143) -> (Pubkey, u8) {
144 Pubkey::find_program_address(
145 &[authority_address.as_ref(), &recent_block_slot.to_le_bytes()],
146 &crate::ADDRESS_LOOKUP_TABLE_PROGRAM_ID,
147 )
148}