1use borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10
11pub struct SetAndVerifyCollection {
13 pub metadata: solana_program::pubkey::Pubkey,
15 pub collection_authority: solana_program::pubkey::Pubkey,
17 pub payer: solana_program::pubkey::Pubkey,
19 pub update_authority: solana_program::pubkey::Pubkey,
21 pub collection_mint: solana_program::pubkey::Pubkey,
23 pub collection: solana_program::pubkey::Pubkey,
25 pub collection_master_edition_account: solana_program::pubkey::Pubkey,
27 pub collection_authority_record: Option<solana_program::pubkey::Pubkey>,
29}
30
31impl SetAndVerifyCollection {
32 pub fn instruction(&self) -> solana_program::instruction::Instruction {
33 self.instruction_with_remaining_accounts(&[])
34 }
35 #[allow(clippy::vec_init_then_push)]
36 pub fn instruction_with_remaining_accounts(
37 &self,
38 remaining_accounts: &[solana_program::instruction::AccountMeta],
39 ) -> solana_program::instruction::Instruction {
40 let mut accounts = Vec::with_capacity(8 + remaining_accounts.len());
41 accounts.push(solana_program::instruction::AccountMeta::new(
42 self.metadata,
43 false,
44 ));
45 accounts.push(solana_program::instruction::AccountMeta::new(
46 self.collection_authority,
47 true,
48 ));
49 accounts.push(solana_program::instruction::AccountMeta::new(
50 self.payer, true,
51 ));
52 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
53 self.update_authority,
54 false,
55 ));
56 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
57 self.collection_mint,
58 false,
59 ));
60 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
61 self.collection,
62 false,
63 ));
64 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
65 self.collection_master_edition_account,
66 false,
67 ));
68 if let Some(collection_authority_record) = self.collection_authority_record {
69 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
70 collection_authority_record,
71 false,
72 ));
73 }
74 accounts.extend_from_slice(remaining_accounts);
75 let data = SetAndVerifyCollectionInstructionData::new()
76 .try_to_vec()
77 .unwrap();
78
79 solana_program::instruction::Instruction {
80 program_id: crate::MPL_TOKEN_METADATA_ID,
81 accounts,
82 data,
83 }
84 }
85}
86
87#[derive(BorshDeserialize, BorshSerialize)]
88struct SetAndVerifyCollectionInstructionData {
89 discriminator: u8,
90}
91
92impl SetAndVerifyCollectionInstructionData {
93 fn new() -> Self {
94 Self { discriminator: 25 }
95 }
96}
97
98#[derive(Default)]
111pub struct SetAndVerifyCollectionBuilder {
112 metadata: Option<solana_program::pubkey::Pubkey>,
113 collection_authority: Option<solana_program::pubkey::Pubkey>,
114 payer: Option<solana_program::pubkey::Pubkey>,
115 update_authority: Option<solana_program::pubkey::Pubkey>,
116 collection_mint: Option<solana_program::pubkey::Pubkey>,
117 collection: Option<solana_program::pubkey::Pubkey>,
118 collection_master_edition_account: Option<solana_program::pubkey::Pubkey>,
119 collection_authority_record: Option<solana_program::pubkey::Pubkey>,
120 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
121}
122
123impl SetAndVerifyCollectionBuilder {
124 pub fn new() -> Self {
125 Self::default()
126 }
127 #[inline(always)]
129 pub fn metadata(&mut self, metadata: solana_program::pubkey::Pubkey) -> &mut Self {
130 self.metadata = Some(metadata);
131 self
132 }
133 #[inline(always)]
135 pub fn collection_authority(
136 &mut self,
137 collection_authority: solana_program::pubkey::Pubkey,
138 ) -> &mut Self {
139 self.collection_authority = Some(collection_authority);
140 self
141 }
142 #[inline(always)]
144 pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self {
145 self.payer = Some(payer);
146 self
147 }
148 #[inline(always)]
150 pub fn update_authority(
151 &mut self,
152 update_authority: solana_program::pubkey::Pubkey,
153 ) -> &mut Self {
154 self.update_authority = Some(update_authority);
155 self
156 }
157 #[inline(always)]
159 pub fn collection_mint(
160 &mut self,
161 collection_mint: solana_program::pubkey::Pubkey,
162 ) -> &mut Self {
163 self.collection_mint = Some(collection_mint);
164 self
165 }
166 #[inline(always)]
168 pub fn collection(&mut self, collection: solana_program::pubkey::Pubkey) -> &mut Self {
169 self.collection = Some(collection);
170 self
171 }
172 #[inline(always)]
174 pub fn collection_master_edition_account(
175 &mut self,
176 collection_master_edition_account: solana_program::pubkey::Pubkey,
177 ) -> &mut Self {
178 self.collection_master_edition_account = Some(collection_master_edition_account);
179 self
180 }
181 #[inline(always)]
184 pub fn collection_authority_record(
185 &mut self,
186 collection_authority_record: Option<solana_program::pubkey::Pubkey>,
187 ) -> &mut Self {
188 self.collection_authority_record = collection_authority_record;
189 self
190 }
191 #[inline(always)]
193 pub fn add_remaining_account(
194 &mut self,
195 account: solana_program::instruction::AccountMeta,
196 ) -> &mut Self {
197 self.__remaining_accounts.push(account);
198 self
199 }
200 #[inline(always)]
202 pub fn add_remaining_accounts(
203 &mut self,
204 accounts: &[solana_program::instruction::AccountMeta],
205 ) -> &mut Self {
206 self.__remaining_accounts.extend_from_slice(accounts);
207 self
208 }
209 #[allow(clippy::clone_on_copy)]
210 pub fn instruction(&self) -> solana_program::instruction::Instruction {
211 let accounts = SetAndVerifyCollection {
212 metadata: self.metadata.expect("metadata is not set"),
213 collection_authority: self
214 .collection_authority
215 .expect("collection_authority is not set"),
216 payer: self.payer.expect("payer is not set"),
217 update_authority: self.update_authority.expect("update_authority is not set"),
218 collection_mint: self.collection_mint.expect("collection_mint is not set"),
219 collection: self.collection.expect("collection is not set"),
220 collection_master_edition_account: self
221 .collection_master_edition_account
222 .expect("collection_master_edition_account is not set"),
223 collection_authority_record: self.collection_authority_record,
224 };
225
226 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
227 }
228}
229
230pub struct SetAndVerifyCollectionCpiAccounts<'a, 'b> {
232 pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
234 pub collection_authority: &'b solana_program::account_info::AccountInfo<'a>,
236 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
238 pub update_authority: &'b solana_program::account_info::AccountInfo<'a>,
240 pub collection_mint: &'b solana_program::account_info::AccountInfo<'a>,
242 pub collection: &'b solana_program::account_info::AccountInfo<'a>,
244 pub collection_master_edition_account: &'b solana_program::account_info::AccountInfo<'a>,
246 pub collection_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
248}
249
250pub struct SetAndVerifyCollectionCpi<'a, 'b> {
252 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
254 pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
256 pub collection_authority: &'b solana_program::account_info::AccountInfo<'a>,
258 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
260 pub update_authority: &'b solana_program::account_info::AccountInfo<'a>,
262 pub collection_mint: &'b solana_program::account_info::AccountInfo<'a>,
264 pub collection: &'b solana_program::account_info::AccountInfo<'a>,
266 pub collection_master_edition_account: &'b solana_program::account_info::AccountInfo<'a>,
268 pub collection_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
270}
271
272impl<'a, 'b> SetAndVerifyCollectionCpi<'a, 'b> {
273 pub fn new(
274 program: &'b solana_program::account_info::AccountInfo<'a>,
275 accounts: SetAndVerifyCollectionCpiAccounts<'a, 'b>,
276 ) -> Self {
277 Self {
278 __program: program,
279 metadata: accounts.metadata,
280 collection_authority: accounts.collection_authority,
281 payer: accounts.payer,
282 update_authority: accounts.update_authority,
283 collection_mint: accounts.collection_mint,
284 collection: accounts.collection,
285 collection_master_edition_account: accounts.collection_master_edition_account,
286 collection_authority_record: accounts.collection_authority_record,
287 }
288 }
289 #[inline(always)]
290 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
291 self.invoke_signed_with_remaining_accounts(&[], &[])
292 }
293 #[inline(always)]
294 pub fn invoke_with_remaining_accounts(
295 &self,
296 remaining_accounts: &[(
297 &'b solana_program::account_info::AccountInfo<'a>,
298 bool,
299 bool,
300 )],
301 ) -> solana_program::entrypoint::ProgramResult {
302 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
303 }
304 #[inline(always)]
305 pub fn invoke_signed(
306 &self,
307 signers_seeds: &[&[&[u8]]],
308 ) -> solana_program::entrypoint::ProgramResult {
309 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
310 }
311 #[allow(clippy::clone_on_copy)]
312 #[allow(clippy::vec_init_then_push)]
313 pub fn invoke_signed_with_remaining_accounts(
314 &self,
315 signers_seeds: &[&[&[u8]]],
316 remaining_accounts: &[(
317 &'b solana_program::account_info::AccountInfo<'a>,
318 bool,
319 bool,
320 )],
321 ) -> solana_program::entrypoint::ProgramResult {
322 let mut accounts = Vec::with_capacity(8 + remaining_accounts.len());
323 accounts.push(solana_program::instruction::AccountMeta::new(
324 *self.metadata.key,
325 false,
326 ));
327 accounts.push(solana_program::instruction::AccountMeta::new(
328 *self.collection_authority.key,
329 true,
330 ));
331 accounts.push(solana_program::instruction::AccountMeta::new(
332 *self.payer.key,
333 true,
334 ));
335 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
336 *self.update_authority.key,
337 false,
338 ));
339 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
340 *self.collection_mint.key,
341 false,
342 ));
343 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
344 *self.collection.key,
345 false,
346 ));
347 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
348 *self.collection_master_edition_account.key,
349 false,
350 ));
351 if let Some(collection_authority_record) = self.collection_authority_record {
352 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
353 *collection_authority_record.key,
354 false,
355 ));
356 }
357 remaining_accounts.iter().for_each(|remaining_account| {
358 accounts.push(solana_program::instruction::AccountMeta {
359 pubkey: *remaining_account.0.key,
360 is_signer: remaining_account.1,
361 is_writable: remaining_account.2,
362 })
363 });
364 let data = SetAndVerifyCollectionInstructionData::new()
365 .try_to_vec()
366 .unwrap();
367
368 let instruction = solana_program::instruction::Instruction {
369 program_id: crate::MPL_TOKEN_METADATA_ID,
370 accounts,
371 data,
372 };
373 let mut account_infos = Vec::with_capacity(8 + 1 + remaining_accounts.len());
374 account_infos.push(self.__program.clone());
375 account_infos.push(self.metadata.clone());
376 account_infos.push(self.collection_authority.clone());
377 account_infos.push(self.payer.clone());
378 account_infos.push(self.update_authority.clone());
379 account_infos.push(self.collection_mint.clone());
380 account_infos.push(self.collection.clone());
381 account_infos.push(self.collection_master_edition_account.clone());
382 if let Some(collection_authority_record) = self.collection_authority_record {
383 account_infos.push(collection_authority_record.clone());
384 }
385 remaining_accounts
386 .iter()
387 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
388
389 if signers_seeds.is_empty() {
390 solana_program::program::invoke(&instruction, &account_infos)
391 } else {
392 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
393 }
394 }
395}
396
397pub struct SetAndVerifyCollectionCpiBuilder<'a, 'b> {
410 instruction: Box<SetAndVerifyCollectionCpiBuilderInstruction<'a, 'b>>,
411}
412
413impl<'a, 'b> SetAndVerifyCollectionCpiBuilder<'a, 'b> {
414 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
415 let instruction = Box::new(SetAndVerifyCollectionCpiBuilderInstruction {
416 __program: program,
417 metadata: None,
418 collection_authority: None,
419 payer: None,
420 update_authority: None,
421 collection_mint: None,
422 collection: None,
423 collection_master_edition_account: None,
424 collection_authority_record: None,
425 __remaining_accounts: Vec::new(),
426 });
427 Self { instruction }
428 }
429 #[inline(always)]
431 pub fn metadata(
432 &mut self,
433 metadata: &'b solana_program::account_info::AccountInfo<'a>,
434 ) -> &mut Self {
435 self.instruction.metadata = Some(metadata);
436 self
437 }
438 #[inline(always)]
440 pub fn collection_authority(
441 &mut self,
442 collection_authority: &'b solana_program::account_info::AccountInfo<'a>,
443 ) -> &mut Self {
444 self.instruction.collection_authority = Some(collection_authority);
445 self
446 }
447 #[inline(always)]
449 pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
450 self.instruction.payer = Some(payer);
451 self
452 }
453 #[inline(always)]
455 pub fn update_authority(
456 &mut self,
457 update_authority: &'b solana_program::account_info::AccountInfo<'a>,
458 ) -> &mut Self {
459 self.instruction.update_authority = Some(update_authority);
460 self
461 }
462 #[inline(always)]
464 pub fn collection_mint(
465 &mut self,
466 collection_mint: &'b solana_program::account_info::AccountInfo<'a>,
467 ) -> &mut Self {
468 self.instruction.collection_mint = Some(collection_mint);
469 self
470 }
471 #[inline(always)]
473 pub fn collection(
474 &mut self,
475 collection: &'b solana_program::account_info::AccountInfo<'a>,
476 ) -> &mut Self {
477 self.instruction.collection = Some(collection);
478 self
479 }
480 #[inline(always)]
482 pub fn collection_master_edition_account(
483 &mut self,
484 collection_master_edition_account: &'b solana_program::account_info::AccountInfo<'a>,
485 ) -> &mut Self {
486 self.instruction.collection_master_edition_account =
487 Some(collection_master_edition_account);
488 self
489 }
490 #[inline(always)]
493 pub fn collection_authority_record(
494 &mut self,
495 collection_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
496 ) -> &mut Self {
497 self.instruction.collection_authority_record = collection_authority_record;
498 self
499 }
500 #[inline(always)]
502 pub fn add_remaining_account(
503 &mut self,
504 account: &'b solana_program::account_info::AccountInfo<'a>,
505 is_writable: bool,
506 is_signer: bool,
507 ) -> &mut Self {
508 self.instruction
509 .__remaining_accounts
510 .push((account, is_writable, is_signer));
511 self
512 }
513 #[inline(always)]
518 pub fn add_remaining_accounts(
519 &mut self,
520 accounts: &[(
521 &'b solana_program::account_info::AccountInfo<'a>,
522 bool,
523 bool,
524 )],
525 ) -> &mut Self {
526 self.instruction
527 .__remaining_accounts
528 .extend_from_slice(accounts);
529 self
530 }
531 #[inline(always)]
532 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
533 self.invoke_signed(&[])
534 }
535 #[allow(clippy::clone_on_copy)]
536 #[allow(clippy::vec_init_then_push)]
537 pub fn invoke_signed(
538 &self,
539 signers_seeds: &[&[&[u8]]],
540 ) -> solana_program::entrypoint::ProgramResult {
541 let instruction = SetAndVerifyCollectionCpi {
542 __program: self.instruction.__program,
543
544 metadata: self.instruction.metadata.expect("metadata is not set"),
545
546 collection_authority: self
547 .instruction
548 .collection_authority
549 .expect("collection_authority is not set"),
550
551 payer: self.instruction.payer.expect("payer is not set"),
552
553 update_authority: self
554 .instruction
555 .update_authority
556 .expect("update_authority is not set"),
557
558 collection_mint: self
559 .instruction
560 .collection_mint
561 .expect("collection_mint is not set"),
562
563 collection: self.instruction.collection.expect("collection is not set"),
564
565 collection_master_edition_account: self
566 .instruction
567 .collection_master_edition_account
568 .expect("collection_master_edition_account is not set"),
569
570 collection_authority_record: self.instruction.collection_authority_record,
571 };
572 instruction.invoke_signed_with_remaining_accounts(
573 signers_seeds,
574 &self.instruction.__remaining_accounts,
575 )
576 }
577}
578
579struct SetAndVerifyCollectionCpiBuilderInstruction<'a, 'b> {
580 __program: &'b solana_program::account_info::AccountInfo<'a>,
581 metadata: Option<&'b solana_program::account_info::AccountInfo<'a>>,
582 collection_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
583 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
584 update_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
585 collection_mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
586 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
587 collection_master_edition_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
588 collection_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
589 __remaining_accounts: Vec<(
591 &'b solana_program::account_info::AccountInfo<'a>,
592 bool,
593 bool,
594 )>,
595}