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