1use borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10
11pub struct VerifyCollection {
13 pub metadata: solana_program::pubkey::Pubkey,
15 pub collection_authority: solana_program::pubkey::Pubkey,
17 pub payer: solana_program::pubkey::Pubkey,
19 pub collection_mint: solana_program::pubkey::Pubkey,
21 pub collection: solana_program::pubkey::Pubkey,
23 pub collection_master_edition_account: solana_program::pubkey::Pubkey,
25 pub collection_authority_record: Option<solana_program::pubkey::Pubkey>,
27}
28
29impl VerifyCollection {
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(7 + remaining_accounts.len());
39 accounts.push(solana_program::instruction::AccountMeta::new(
40 self.metadata,
41 false,
42 ));
43 accounts.push(solana_program::instruction::AccountMeta::new(
44 self.collection_authority,
45 true,
46 ));
47 accounts.push(solana_program::instruction::AccountMeta::new(
48 self.payer, true,
49 ));
50 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
51 self.collection_mint,
52 false,
53 ));
54 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
55 self.collection,
56 false,
57 ));
58 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
59 self.collection_master_edition_account,
60 false,
61 ));
62 if let Some(collection_authority_record) = self.collection_authority_record {
63 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
64 collection_authority_record,
65 false,
66 ));
67 }
68 accounts.extend_from_slice(remaining_accounts);
69 let data = VerifyCollectionInstructionData::new().try_to_vec().unwrap();
70
71 solana_program::instruction::Instruction {
72 program_id: crate::MPL_TOKEN_METADATA_ID,
73 accounts,
74 data,
75 }
76 }
77}
78
79#[derive(BorshDeserialize, BorshSerialize)]
80struct VerifyCollectionInstructionData {
81 discriminator: u8,
82}
83
84impl VerifyCollectionInstructionData {
85 fn new() -> Self {
86 Self { discriminator: 18 }
87 }
88}
89
90#[derive(Default)]
102pub struct VerifyCollectionBuilder {
103 metadata: Option<solana_program::pubkey::Pubkey>,
104 collection_authority: Option<solana_program::pubkey::Pubkey>,
105 payer: Option<solana_program::pubkey::Pubkey>,
106 collection_mint: Option<solana_program::pubkey::Pubkey>,
107 collection: Option<solana_program::pubkey::Pubkey>,
108 collection_master_edition_account: Option<solana_program::pubkey::Pubkey>,
109 collection_authority_record: Option<solana_program::pubkey::Pubkey>,
110 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
111}
112
113impl VerifyCollectionBuilder {
114 pub fn new() -> Self {
115 Self::default()
116 }
117 #[inline(always)]
119 pub fn metadata(&mut self, metadata: solana_program::pubkey::Pubkey) -> &mut Self {
120 self.metadata = Some(metadata);
121 self
122 }
123 #[inline(always)]
125 pub fn collection_authority(
126 &mut self,
127 collection_authority: solana_program::pubkey::Pubkey,
128 ) -> &mut Self {
129 self.collection_authority = Some(collection_authority);
130 self
131 }
132 #[inline(always)]
134 pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self {
135 self.payer = Some(payer);
136 self
137 }
138 #[inline(always)]
140 pub fn collection_mint(
141 &mut self,
142 collection_mint: solana_program::pubkey::Pubkey,
143 ) -> &mut Self {
144 self.collection_mint = Some(collection_mint);
145 self
146 }
147 #[inline(always)]
149 pub fn collection(&mut self, collection: solana_program::pubkey::Pubkey) -> &mut Self {
150 self.collection = Some(collection);
151 self
152 }
153 #[inline(always)]
155 pub fn collection_master_edition_account(
156 &mut self,
157 collection_master_edition_account: solana_program::pubkey::Pubkey,
158 ) -> &mut Self {
159 self.collection_master_edition_account = Some(collection_master_edition_account);
160 self
161 }
162 #[inline(always)]
165 pub fn collection_authority_record(
166 &mut self,
167 collection_authority_record: Option<solana_program::pubkey::Pubkey>,
168 ) -> &mut Self {
169 self.collection_authority_record = collection_authority_record;
170 self
171 }
172 #[inline(always)]
174 pub fn add_remaining_account(
175 &mut self,
176 account: solana_program::instruction::AccountMeta,
177 ) -> &mut Self {
178 self.__remaining_accounts.push(account);
179 self
180 }
181 #[inline(always)]
183 pub fn add_remaining_accounts(
184 &mut self,
185 accounts: &[solana_program::instruction::AccountMeta],
186 ) -> &mut Self {
187 self.__remaining_accounts.extend_from_slice(accounts);
188 self
189 }
190 #[allow(clippy::clone_on_copy)]
191 pub fn instruction(&self) -> solana_program::instruction::Instruction {
192 let accounts = VerifyCollection {
193 metadata: self.metadata.expect("metadata is not set"),
194 collection_authority: self
195 .collection_authority
196 .expect("collection_authority is not set"),
197 payer: self.payer.expect("payer is not set"),
198 collection_mint: self.collection_mint.expect("collection_mint is not set"),
199 collection: self.collection.expect("collection is not set"),
200 collection_master_edition_account: self
201 .collection_master_edition_account
202 .expect("collection_master_edition_account is not set"),
203 collection_authority_record: self.collection_authority_record,
204 };
205
206 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
207 }
208}
209
210pub struct VerifyCollectionCpiAccounts<'a, 'b> {
212 pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
214 pub collection_authority: &'b solana_program::account_info::AccountInfo<'a>,
216 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
218 pub collection_mint: &'b solana_program::account_info::AccountInfo<'a>,
220 pub collection: &'b solana_program::account_info::AccountInfo<'a>,
222 pub collection_master_edition_account: &'b solana_program::account_info::AccountInfo<'a>,
224 pub collection_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
226}
227
228pub struct VerifyCollectionCpi<'a, 'b> {
230 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
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 collection_mint: &'b solana_program::account_info::AccountInfo<'a>,
240 pub collection: &'b solana_program::account_info::AccountInfo<'a>,
242 pub collection_master_edition_account: &'b solana_program::account_info::AccountInfo<'a>,
244 pub collection_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
246}
247
248impl<'a, 'b> VerifyCollectionCpi<'a, 'b> {
249 pub fn new(
250 program: &'b solana_program::account_info::AccountInfo<'a>,
251 accounts: VerifyCollectionCpiAccounts<'a, 'b>,
252 ) -> Self {
253 Self {
254 __program: program,
255 metadata: accounts.metadata,
256 collection_authority: accounts.collection_authority,
257 payer: accounts.payer,
258 collection_mint: accounts.collection_mint,
259 collection: accounts.collection,
260 collection_master_edition_account: accounts.collection_master_edition_account,
261 collection_authority_record: accounts.collection_authority_record,
262 }
263 }
264 #[inline(always)]
265 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
266 self.invoke_signed_with_remaining_accounts(&[], &[])
267 }
268 #[inline(always)]
269 pub fn invoke_with_remaining_accounts(
270 &self,
271 remaining_accounts: &[(
272 &'b solana_program::account_info::AccountInfo<'a>,
273 bool,
274 bool,
275 )],
276 ) -> solana_program::entrypoint::ProgramResult {
277 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
278 }
279 #[inline(always)]
280 pub fn invoke_signed(
281 &self,
282 signers_seeds: &[&[&[u8]]],
283 ) -> solana_program::entrypoint::ProgramResult {
284 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
285 }
286 #[allow(clippy::clone_on_copy)]
287 #[allow(clippy::vec_init_then_push)]
288 pub fn invoke_signed_with_remaining_accounts(
289 &self,
290 signers_seeds: &[&[&[u8]]],
291 remaining_accounts: &[(
292 &'b solana_program::account_info::AccountInfo<'a>,
293 bool,
294 bool,
295 )],
296 ) -> solana_program::entrypoint::ProgramResult {
297 let mut accounts = Vec::with_capacity(7 + remaining_accounts.len());
298 accounts.push(solana_program::instruction::AccountMeta::new(
299 *self.metadata.key,
300 false,
301 ));
302 accounts.push(solana_program::instruction::AccountMeta::new(
303 *self.collection_authority.key,
304 true,
305 ));
306 accounts.push(solana_program::instruction::AccountMeta::new(
307 *self.payer.key,
308 true,
309 ));
310 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
311 *self.collection_mint.key,
312 false,
313 ));
314 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
315 *self.collection.key,
316 false,
317 ));
318 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
319 *self.collection_master_edition_account.key,
320 false,
321 ));
322 if let Some(collection_authority_record) = self.collection_authority_record {
323 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
324 *collection_authority_record.key,
325 false,
326 ));
327 }
328 remaining_accounts.iter().for_each(|remaining_account| {
329 accounts.push(solana_program::instruction::AccountMeta {
330 pubkey: *remaining_account.0.key,
331 is_signer: remaining_account.1,
332 is_writable: remaining_account.2,
333 })
334 });
335 let data = VerifyCollectionInstructionData::new().try_to_vec().unwrap();
336
337 let instruction = solana_program::instruction::Instruction {
338 program_id: crate::MPL_TOKEN_METADATA_ID,
339 accounts,
340 data,
341 };
342 let mut account_infos = Vec::with_capacity(7 + 1 + remaining_accounts.len());
343 account_infos.push(self.__program.clone());
344 account_infos.push(self.metadata.clone());
345 account_infos.push(self.collection_authority.clone());
346 account_infos.push(self.payer.clone());
347 account_infos.push(self.collection_mint.clone());
348 account_infos.push(self.collection.clone());
349 account_infos.push(self.collection_master_edition_account.clone());
350 if let Some(collection_authority_record) = self.collection_authority_record {
351 account_infos.push(collection_authority_record.clone());
352 }
353 remaining_accounts
354 .iter()
355 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
356
357 if signers_seeds.is_empty() {
358 solana_program::program::invoke(&instruction, &account_infos)
359 } else {
360 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
361 }
362 }
363}
364
365pub struct VerifyCollectionCpiBuilder<'a, 'b> {
377 instruction: Box<VerifyCollectionCpiBuilderInstruction<'a, 'b>>,
378}
379
380impl<'a, 'b> VerifyCollectionCpiBuilder<'a, 'b> {
381 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
382 let instruction = Box::new(VerifyCollectionCpiBuilderInstruction {
383 __program: program,
384 metadata: None,
385 collection_authority: None,
386 payer: None,
387 collection_mint: None,
388 collection: None,
389 collection_master_edition_account: None,
390 collection_authority_record: None,
391 __remaining_accounts: Vec::new(),
392 });
393 Self { instruction }
394 }
395 #[inline(always)]
397 pub fn metadata(
398 &mut self,
399 metadata: &'b solana_program::account_info::AccountInfo<'a>,
400 ) -> &mut Self {
401 self.instruction.metadata = Some(metadata);
402 self
403 }
404 #[inline(always)]
406 pub fn collection_authority(
407 &mut self,
408 collection_authority: &'b solana_program::account_info::AccountInfo<'a>,
409 ) -> &mut Self {
410 self.instruction.collection_authority = Some(collection_authority);
411 self
412 }
413 #[inline(always)]
415 pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
416 self.instruction.payer = Some(payer);
417 self
418 }
419 #[inline(always)]
421 pub fn collection_mint(
422 &mut self,
423 collection_mint: &'b solana_program::account_info::AccountInfo<'a>,
424 ) -> &mut Self {
425 self.instruction.collection_mint = Some(collection_mint);
426 self
427 }
428 #[inline(always)]
430 pub fn collection(
431 &mut self,
432 collection: &'b solana_program::account_info::AccountInfo<'a>,
433 ) -> &mut Self {
434 self.instruction.collection = Some(collection);
435 self
436 }
437 #[inline(always)]
439 pub fn collection_master_edition_account(
440 &mut self,
441 collection_master_edition_account: &'b solana_program::account_info::AccountInfo<'a>,
442 ) -> &mut Self {
443 self.instruction.collection_master_edition_account =
444 Some(collection_master_edition_account);
445 self
446 }
447 #[inline(always)]
450 pub fn collection_authority_record(
451 &mut self,
452 collection_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
453 ) -> &mut Self {
454 self.instruction.collection_authority_record = collection_authority_record;
455 self
456 }
457 #[inline(always)]
459 pub fn add_remaining_account(
460 &mut self,
461 account: &'b solana_program::account_info::AccountInfo<'a>,
462 is_writable: bool,
463 is_signer: bool,
464 ) -> &mut Self {
465 self.instruction
466 .__remaining_accounts
467 .push((account, is_writable, is_signer));
468 self
469 }
470 #[inline(always)]
475 pub fn add_remaining_accounts(
476 &mut self,
477 accounts: &[(
478 &'b solana_program::account_info::AccountInfo<'a>,
479 bool,
480 bool,
481 )],
482 ) -> &mut Self {
483 self.instruction
484 .__remaining_accounts
485 .extend_from_slice(accounts);
486 self
487 }
488 #[inline(always)]
489 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
490 self.invoke_signed(&[])
491 }
492 #[allow(clippy::clone_on_copy)]
493 #[allow(clippy::vec_init_then_push)]
494 pub fn invoke_signed(
495 &self,
496 signers_seeds: &[&[&[u8]]],
497 ) -> solana_program::entrypoint::ProgramResult {
498 let instruction = VerifyCollectionCpi {
499 __program: self.instruction.__program,
500
501 metadata: self.instruction.metadata.expect("metadata is not set"),
502
503 collection_authority: self
504 .instruction
505 .collection_authority
506 .expect("collection_authority is not set"),
507
508 payer: self.instruction.payer.expect("payer is not set"),
509
510 collection_mint: self
511 .instruction
512 .collection_mint
513 .expect("collection_mint is not set"),
514
515 collection: self.instruction.collection.expect("collection is not set"),
516
517 collection_master_edition_account: self
518 .instruction
519 .collection_master_edition_account
520 .expect("collection_master_edition_account is not set"),
521
522 collection_authority_record: self.instruction.collection_authority_record,
523 };
524 instruction.invoke_signed_with_remaining_accounts(
525 signers_seeds,
526 &self.instruction.__remaining_accounts,
527 )
528 }
529}
530
531struct VerifyCollectionCpiBuilderInstruction<'a, 'b> {
532 __program: &'b solana_program::account_info::AccountInfo<'a>,
533 metadata: Option<&'b solana_program::account_info::AccountInfo<'a>>,
534 collection_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
535 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
536 collection_mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
537 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
538 collection_master_edition_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
539 collection_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
540 __remaining_accounts: Vec<(
542 &'b solana_program::account_info::AccountInfo<'a>,
543 bool,
544 bool,
545 )>,
546}