1#[cfg(feature = "anchor")]
9use anchor_lang::prelude::{AnchorDeserialize, AnchorSerialize};
10#[cfg(not(feature = "anchor"))]
11use borsh::{BorshDeserialize, BorshSerialize};
12
13pub struct CompressV1 {
15 pub asset: solana_program::pubkey::Pubkey,
17 pub collection: Option<solana_program::pubkey::Pubkey>,
19 pub payer: solana_program::pubkey::Pubkey,
21 pub authority: Option<solana_program::pubkey::Pubkey>,
23 pub system_program: solana_program::pubkey::Pubkey,
25 pub log_wrapper: Option<solana_program::pubkey::Pubkey>,
27}
28
29impl CompressV1 {
30 pub fn instruction(&self) -> solana_program::instruction::Instruction {
31 self.instruction_with_remaining_accounts(&[])
32 }
33 #[allow(clippy::vec_init_then_push)]
34 pub fn instruction_with_remaining_accounts(
35 &self,
36 remaining_accounts: &[solana_program::instruction::AccountMeta],
37 ) -> solana_program::instruction::Instruction {
38 let mut accounts = Vec::with_capacity(6 + remaining_accounts.len());
39 accounts.push(solana_program::instruction::AccountMeta::new(
40 self.asset, false,
41 ));
42 if let Some(collection) = self.collection {
43 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
44 collection, false,
45 ));
46 } else {
47 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
48 crate::MPL_CORE_ID,
49 false,
50 ));
51 }
52 accounts.push(solana_program::instruction::AccountMeta::new(
53 self.payer, true,
54 ));
55 if let Some(authority) = self.authority {
56 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
57 authority, true,
58 ));
59 } else {
60 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
61 crate::MPL_CORE_ID,
62 false,
63 ));
64 }
65 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
66 self.system_program,
67 false,
68 ));
69 if let Some(log_wrapper) = self.log_wrapper {
70 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
71 log_wrapper,
72 false,
73 ));
74 } else {
75 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
76 crate::MPL_CORE_ID,
77 false,
78 ));
79 }
80 accounts.extend_from_slice(remaining_accounts);
81 let data = CompressV1InstructionData::new().try_to_vec().unwrap();
82
83 solana_program::instruction::Instruction {
84 program_id: crate::MPL_CORE_ID,
85 accounts,
86 data,
87 }
88 }
89}
90
91#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
92#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
93pub struct CompressV1InstructionData {
94 discriminator: u8,
95}
96
97impl CompressV1InstructionData {
98 pub fn new() -> Self {
99 Self { discriminator: 17 }
100 }
101}
102
103#[derive(Default)]
114pub struct CompressV1Builder {
115 asset: Option<solana_program::pubkey::Pubkey>,
116 collection: Option<solana_program::pubkey::Pubkey>,
117 payer: Option<solana_program::pubkey::Pubkey>,
118 authority: Option<solana_program::pubkey::Pubkey>,
119 system_program: Option<solana_program::pubkey::Pubkey>,
120 log_wrapper: Option<solana_program::pubkey::Pubkey>,
121 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
122}
123
124impl CompressV1Builder {
125 pub fn new() -> Self {
126 Self::default()
127 }
128 #[inline(always)]
130 pub fn asset(&mut self, asset: solana_program::pubkey::Pubkey) -> &mut Self {
131 self.asset = Some(asset);
132 self
133 }
134 #[inline(always)]
137 pub fn collection(&mut self, collection: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
138 self.collection = collection;
139 self
140 }
141 #[inline(always)]
143 pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self {
144 self.payer = Some(payer);
145 self
146 }
147 #[inline(always)]
150 pub fn authority(&mut self, authority: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
151 self.authority = authority;
152 self
153 }
154 #[inline(always)]
157 pub fn system_program(&mut self, system_program: solana_program::pubkey::Pubkey) -> &mut Self {
158 self.system_program = Some(system_program);
159 self
160 }
161 #[inline(always)]
164 pub fn log_wrapper(
165 &mut self,
166 log_wrapper: Option<solana_program::pubkey::Pubkey>,
167 ) -> &mut Self {
168 self.log_wrapper = log_wrapper;
169 self
170 }
171 #[inline(always)]
173 pub fn add_remaining_account(
174 &mut self,
175 account: solana_program::instruction::AccountMeta,
176 ) -> &mut Self {
177 self.__remaining_accounts.push(account);
178 self
179 }
180 #[inline(always)]
182 pub fn add_remaining_accounts(
183 &mut self,
184 accounts: &[solana_program::instruction::AccountMeta],
185 ) -> &mut Self {
186 self.__remaining_accounts.extend_from_slice(accounts);
187 self
188 }
189 #[allow(clippy::clone_on_copy)]
190 pub fn instruction(&self) -> solana_program::instruction::Instruction {
191 let accounts = CompressV1 {
192 asset: self.asset.expect("asset is not set"),
193 collection: self.collection,
194 payer: self.payer.expect("payer is not set"),
195 authority: self.authority,
196 system_program: self
197 .system_program
198 .unwrap_or(solana_program::pubkey!("11111111111111111111111111111111")),
199 log_wrapper: self.log_wrapper,
200 };
201
202 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
203 }
204}
205
206pub struct CompressV1CpiAccounts<'a, 'b> {
208 pub asset: &'b solana_program::account_info::AccountInfo<'a>,
210 pub collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
212 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
214 pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
216 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
218 pub log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
220}
221
222pub struct CompressV1Cpi<'a, 'b> {
224 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
226 pub asset: &'b solana_program::account_info::AccountInfo<'a>,
228 pub collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
230 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
232 pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
234 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
236 pub log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
238}
239
240impl<'a, 'b> CompressV1Cpi<'a, 'b> {
241 pub fn new(
242 program: &'b solana_program::account_info::AccountInfo<'a>,
243 accounts: CompressV1CpiAccounts<'a, 'b>,
244 ) -> Self {
245 Self {
246 __program: program,
247 asset: accounts.asset,
248 collection: accounts.collection,
249 payer: accounts.payer,
250 authority: accounts.authority,
251 system_program: accounts.system_program,
252 log_wrapper: accounts.log_wrapper,
253 }
254 }
255 #[inline(always)]
256 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
257 self.invoke_signed_with_remaining_accounts(&[], &[])
258 }
259 #[inline(always)]
260 pub fn invoke_with_remaining_accounts(
261 &self,
262 remaining_accounts: &[(
263 &'b solana_program::account_info::AccountInfo<'a>,
264 bool,
265 bool,
266 )],
267 ) -> solana_program::entrypoint::ProgramResult {
268 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
269 }
270 #[inline(always)]
271 pub fn invoke_signed(
272 &self,
273 signers_seeds: &[&[&[u8]]],
274 ) -> solana_program::entrypoint::ProgramResult {
275 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
276 }
277 #[allow(clippy::clone_on_copy)]
278 #[allow(clippy::vec_init_then_push)]
279 pub fn invoke_signed_with_remaining_accounts(
280 &self,
281 signers_seeds: &[&[&[u8]]],
282 remaining_accounts: &[(
283 &'b solana_program::account_info::AccountInfo<'a>,
284 bool,
285 bool,
286 )],
287 ) -> solana_program::entrypoint::ProgramResult {
288 let mut accounts = Vec::with_capacity(6 + remaining_accounts.len());
289 accounts.push(solana_program::instruction::AccountMeta::new(
290 *self.asset.key,
291 false,
292 ));
293 if let Some(collection) = self.collection {
294 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
295 *collection.key,
296 false,
297 ));
298 } else {
299 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
300 crate::MPL_CORE_ID,
301 false,
302 ));
303 }
304 accounts.push(solana_program::instruction::AccountMeta::new(
305 *self.payer.key,
306 true,
307 ));
308 if let Some(authority) = self.authority {
309 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
310 *authority.key,
311 true,
312 ));
313 } else {
314 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
315 crate::MPL_CORE_ID,
316 false,
317 ));
318 }
319 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
320 *self.system_program.key,
321 false,
322 ));
323 if let Some(log_wrapper) = self.log_wrapper {
324 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
325 *log_wrapper.key,
326 false,
327 ));
328 } else {
329 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
330 crate::MPL_CORE_ID,
331 false,
332 ));
333 }
334 remaining_accounts.iter().for_each(|remaining_account| {
335 accounts.push(solana_program::instruction::AccountMeta {
336 pubkey: *remaining_account.0.key,
337 is_signer: remaining_account.1,
338 is_writable: remaining_account.2,
339 })
340 });
341 let data = CompressV1InstructionData::new().try_to_vec().unwrap();
342
343 let instruction = solana_program::instruction::Instruction {
344 program_id: crate::MPL_CORE_ID,
345 accounts,
346 data,
347 };
348 let mut account_infos = Vec::with_capacity(6 + 1 + remaining_accounts.len());
349 account_infos.push(self.__program.clone());
350 account_infos.push(self.asset.clone());
351 if let Some(collection) = self.collection {
352 account_infos.push(collection.clone());
353 }
354 account_infos.push(self.payer.clone());
355 if let Some(authority) = self.authority {
356 account_infos.push(authority.clone());
357 }
358 account_infos.push(self.system_program.clone());
359 if let Some(log_wrapper) = self.log_wrapper {
360 account_infos.push(log_wrapper.clone());
361 }
362 remaining_accounts
363 .iter()
364 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
365
366 if signers_seeds.is_empty() {
367 solana_program::program::invoke(&instruction, &account_infos)
368 } else {
369 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
370 }
371 }
372}
373
374pub struct CompressV1CpiBuilder<'a, 'b> {
385 instruction: Box<CompressV1CpiBuilderInstruction<'a, 'b>>,
386}
387
388impl<'a, 'b> CompressV1CpiBuilder<'a, 'b> {
389 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
390 let instruction = Box::new(CompressV1CpiBuilderInstruction {
391 __program: program,
392 asset: None,
393 collection: None,
394 payer: None,
395 authority: None,
396 system_program: None,
397 log_wrapper: None,
398 __remaining_accounts: Vec::new(),
399 });
400 Self { instruction }
401 }
402 #[inline(always)]
404 pub fn asset(&mut self, asset: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
405 self.instruction.asset = Some(asset);
406 self
407 }
408 #[inline(always)]
411 pub fn collection(
412 &mut self,
413 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
414 ) -> &mut Self {
415 self.instruction.collection = collection;
416 self
417 }
418 #[inline(always)]
420 pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
421 self.instruction.payer = Some(payer);
422 self
423 }
424 #[inline(always)]
427 pub fn authority(
428 &mut self,
429 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
430 ) -> &mut Self {
431 self.instruction.authority = authority;
432 self
433 }
434 #[inline(always)]
436 pub fn system_program(
437 &mut self,
438 system_program: &'b solana_program::account_info::AccountInfo<'a>,
439 ) -> &mut Self {
440 self.instruction.system_program = Some(system_program);
441 self
442 }
443 #[inline(always)]
446 pub fn log_wrapper(
447 &mut self,
448 log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
449 ) -> &mut Self {
450 self.instruction.log_wrapper = log_wrapper;
451 self
452 }
453 #[inline(always)]
455 pub fn add_remaining_account(
456 &mut self,
457 account: &'b solana_program::account_info::AccountInfo<'a>,
458 is_writable: bool,
459 is_signer: bool,
460 ) -> &mut Self {
461 self.instruction
462 .__remaining_accounts
463 .push((account, is_writable, is_signer));
464 self
465 }
466 #[inline(always)]
471 pub fn add_remaining_accounts(
472 &mut self,
473 accounts: &[(
474 &'b solana_program::account_info::AccountInfo<'a>,
475 bool,
476 bool,
477 )],
478 ) -> &mut Self {
479 self.instruction
480 .__remaining_accounts
481 .extend_from_slice(accounts);
482 self
483 }
484 #[inline(always)]
485 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
486 self.invoke_signed(&[])
487 }
488 #[allow(clippy::clone_on_copy)]
489 #[allow(clippy::vec_init_then_push)]
490 pub fn invoke_signed(
491 &self,
492 signers_seeds: &[&[&[u8]]],
493 ) -> solana_program::entrypoint::ProgramResult {
494 let instruction = CompressV1Cpi {
495 __program: self.instruction.__program,
496
497 asset: self.instruction.asset.expect("asset is not set"),
498
499 collection: self.instruction.collection,
500
501 payer: self.instruction.payer.expect("payer is not set"),
502
503 authority: self.instruction.authority,
504
505 system_program: self
506 .instruction
507 .system_program
508 .expect("system_program is not set"),
509
510 log_wrapper: self.instruction.log_wrapper,
511 };
512 instruction.invoke_signed_with_remaining_accounts(
513 signers_seeds,
514 &self.instruction.__remaining_accounts,
515 )
516 }
517}
518
519struct CompressV1CpiBuilderInstruction<'a, 'b> {
520 __program: &'b solana_program::account_info::AccountInfo<'a>,
521 asset: Option<&'b solana_program::account_info::AccountInfo<'a>>,
522 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
523 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
524 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
525 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
526 log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
527 __remaining_accounts: Vec<(
529 &'b solana_program::account_info::AccountInfo<'a>,
530 bool,
531 bool,
532 )>,
533}