solana_randomness_service_lite/
lib.rs1#![cfg_attr(doc_cfg, feature(doc_cfg))]
2
3use borsh::{BorshDeserialize, BorshSerialize};
112pub use solana_program::account_info::AccountInfo;
113pub use solana_program::instruction::AccountMeta;
114pub use solana_program::program_error::ProgramError;
115pub use solana_program::pubkey::Pubkey;
116use solana_program::{declare_id, instruction::Instruction};
117use solana_program::{program::invoke, program::invoke_signed, pubkey};
118
119pub mod types;
120pub use types::*;
121
122declare_id!("RANDMo5gFnqnXJW5Z52KNmd24sAo95KAd5VbiCtq5Rh");
123
124pub const SWITCHBOARD_PROGRAM_ID: Pubkey = pubkey!("sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx");
125
126pub const RANDOMNESS_SERVICE_STATE: Pubkey =
127 pubkey!("889J3BcnDDBMA651BoZNnuKrhQtXkLRzDuKhnJkWUfKA");
128pub const RANDOMNESS_SERVICE_REWARD_WALLET: Pubkey =
129 pubkey!("3X7Jy3dc7eRSP9ECWvxiiQWG8gfwmYq1zENfWpzygt6D");
130pub const RANDOMNESS_SERVICE_REWARD_MINT: Pubkey =
131 pubkey!("So11111111111111111111111111111111111111112");
132
133pub const MAINNET_SWITCHBOARD_FUNCTION: Pubkey =
134 pubkey!("yxvdQ9D6eovAQqacSyAL9vYhXXtdtnmgCABfaz8cg2W");
135pub const MAINNET_SWITCHBOARD_SERVICE: Pubkey =
136 pubkey!("3gGs95XHv47gY6aUvSPhQmVrWYt3M6Lz3nxE9eMS3bot");
137
138pub const DEVNET_SWITCHBOARD_FUNCTION: Pubkey =
139 pubkey!("AHV7ygefHZQ5extiZ4GbseGANg3AwBWgSUfnUktTrxjd");
140pub const DEVNET_SWITCHBOARD_SERVICE: Pubkey =
141 pubkey!("2fpdEbugwThMjRQ728Ne4zwGsrjFcCtmYDnwGtzScfnL");
142
143pub struct SimpleRandomnessV1Request<'info> {
145 pub request: AccountInfo<'info>,
146 pub escrow: AccountInfo<'info>,
147 pub state: AccountInfo<'info>,
148 pub mint: AccountInfo<'info>,
149 pub payer: AccountInfo<'info>,
150 pub system_program: AccountInfo<'info>,
151 pub token_program: AccountInfo<'info>,
152 pub associated_token_program: AccountInfo<'info>,
153}
154
155impl<'info> SimpleRandomnessV1Request<'info> {
156 pub const DISCRIMINATOR: [u8; 8] = [179, 249, 152, 75, 164, 218, 230, 36];
157
158 pub fn discriminator() -> [u8; 8] {
159 Self::DISCRIMINATOR
160 }
161
162 pub fn get_instruction(
163 &self,
164 program_id: Pubkey,
165 num_bytes: u8,
166 callback: &Callback,
167 options: &Option<TransactionOptions>,
168 ) -> Result<Instruction, ProgramError> {
169 let accounts = self.to_account_metas();
170
171 let mut data: Vec<u8> = Self::discriminator().to_vec();
172 data.push(num_bytes);
173 data.append(&mut callback.to_vec()?);
174 data.append(&mut TransactionOptions::to_opt_vec(options)?);
175
176 Ok(Instruction {
177 program_id,
178 accounts,
179 data,
180 })
181 }
182
183 pub fn invoke(
184 &self,
185 program: AccountInfo<'info>,
186 num_bytes: u8,
187 callback: &Callback,
188 options: &Option<TransactionOptions>,
189 ) -> Result<(), solana_program::program_error::ProgramError> {
190 let instruction = self.get_instruction(*program.key, num_bytes, callback, options)?;
191 let account_infos = self.to_account_infos();
192
193 invoke(&instruction, &account_infos[..])
194 }
195
196 pub fn invoke_signed(
197 &self,
198 program: AccountInfo<'info>,
199 num_bytes: u8,
200 callback: &Callback,
201 options: &Option<TransactionOptions>,
202 signer_seeds: &[&[&[u8]]],
203 ) -> Result<(), solana_program::program_error::ProgramError> {
204 let instruction = self.get_instruction(*program.key, num_bytes, callback, options)?;
205 let account_infos = self.to_account_infos();
206
207 invoke_signed(&instruction, &account_infos[..], signer_seeds)
208 }
209
210 fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
211 vec![
212 self.request.clone(),
213 self.escrow.clone(),
214 self.state.clone(),
215 self.mint.clone(),
216 self.payer.clone(),
217 self.system_program.clone(),
218 self.token_program.clone(),
219 self.associated_token_program.clone(),
220 ]
221 }
222
223 fn to_account_metas(&self) -> Vec<AccountMeta> {
224 vec![
225 AccountMeta::new(*self.request.key, true),
226 AccountMeta::new(*self.escrow.key, false),
227 AccountMeta::new_readonly(*self.state.key, false),
228 AccountMeta::new_readonly(*self.mint.key, false),
229 AccountMeta::new(*self.payer.key, true),
230 AccountMeta::new_readonly(*self.system_program.key, false),
231 AccountMeta::new_readonly(*self.token_program.key, false),
232 AccountMeta::new_readonly(*self.associated_token_program.key, false),
233 ]
234 }
235}
236
237#[derive(Clone, Default, BorshDeserialize, BorshSerialize)]
238pub struct SimpleRandomnessV1Account {
239 pub is_completed: u8,
240 pub num_bytes: u8,
241 pub user: Pubkey,
242 pub escrow: Pubkey,
243 pub request_slot: u64,
244 pub callback: Callback,
245 pub compute_units: u32,
246 pub priority_fee_micro_lamports: u64,
247 pub error_message: String,
248}
249impl SimpleRandomnessV1Account {
250 pub const DISCRIMINATOR: [u8; 8] = [45, 236, 206, 109, 194, 21, 241, 154];
251
252 pub fn discriminator() -> [u8; 8] {
253 Self::DISCRIMINATOR
254 }
255
256 pub fn owner() -> Pubkey {
257 ID
258 }
259
260 pub fn try_deserialize(buf: &mut &[u8]) -> Result<Self, ProgramError> {
261 if buf.len() < Self::DISCRIMINATOR.len() {
262 return Err(ProgramError::InvalidAccountData);
263 }
264 let given_disc = &buf[..8];
265 if Self::DISCRIMINATOR != given_disc {
266 return Err(ProgramError::InvalidAccountData);
267 }
268 Self::try_deserialize_unchecked(buf)
269 }
270
271 pub fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self, ProgramError> {
272 let mut data: &[u8] = &buf[8..];
273 Self::deserialize(&mut data).map_err(|_| ProgramError::InvalidAccountData)
274 }
275}
276
277#[derive(Clone, Default, BorshDeserialize, BorshSerialize)]
278pub struct State {
279 pub is_completed: u8,
280 pub num_bytes: u8,
281 pub user: Pubkey,
282 pub escrow: Pubkey,
283 pub request_slot: u64,
284 pub callback: Callback,
285 pub compute_units: u32,
286 pub priority_fee_micro_lamports: u64,
287 pub error_message: String,
288}
289impl State {
290 pub const DISCRIMINATOR: [u8; 8] = [216, 146, 107, 94, 104, 75, 182, 177];
291
292 pub fn discriminator() -> [u8; 8] {
293 Self::DISCRIMINATOR
294 }
295
296 pub fn owner() -> Pubkey {
297 ID
298 }
299
300 pub fn try_deserialize(buf: &mut &[u8]) -> Result<Self, ProgramError> {
301 if buf.len() < Self::DISCRIMINATOR.len() {
302 return Err(ProgramError::InvalidAccountData);
303 }
304 let given_disc = &buf[..8];
305 if Self::DISCRIMINATOR != given_disc {
306 return Err(ProgramError::InvalidAccountData);
307 }
308 Self::try_deserialize_unchecked(buf)
309 }
310
311 pub fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self, ProgramError> {
312 let mut data: &[u8] = &buf[8..];
313 Self::deserialize(&mut data).map_err(|_| ProgramError::InvalidAccountData)
314 }
315}