spl_simplified/
metadata.rs

1use anchor_lang::context::CpiContext;
2use anchor_lang::error::ErrorCode;
3use anchor_lang::{system_program, Accounts, Result, ToAccountInfos};
4use solana_program::account_info::AccountInfo;
5use solana_program::pubkey::Pubkey;
6use solana_program::sysvar;
7use std::ops::Deref;
8
9pub use mpl_token_metadata;
10pub use mpl_token_metadata::ID;
11
12pub fn approve_collection_authority<'info>(
13    ctx: CpiContext<'_, '_, '_, 'info, ApproveCollectionAuthority<'info>>,
14) -> Result<()> {
15    let ix = mpl_token_metadata::instructions::ApproveCollectionAuthority {
16        collection_authority_record: *ctx.accounts.collection_authority_record.key,
17        metadata: *ctx.accounts.metadata.key,
18        mint: *ctx.accounts.mint.key,
19        new_collection_authority: *ctx.accounts.new_collection_authority.key,
20        payer: *ctx.accounts.payer.key,
21        rent: None,
22        system_program: system_program::ID,
23        update_authority: *ctx.accounts.update_authority.key,
24    }
25    .instruction();
26    solana_program::program::invoke_signed(
27        &ix,
28        &ToAccountInfos::to_account_infos(&ctx),
29        ctx.signer_seeds,
30    )
31    .map_err(Into::into)
32}
33
34pub fn bubblegum_set_collection_size<'info>(
35    ctx: CpiContext<'_, '_, '_, 'info, BubblegumSetCollectionSize<'info>>,
36    collection_authority_record: Option<Pubkey>,
37    size: u64,
38) -> Result<()> {
39    let ix = mpl_token_metadata::instructions::BubblegumSetCollectionSize {
40        collection_metadata: *ctx.accounts.metadata_account.key,
41        collection_authority: *ctx.accounts.update_authority.key,
42        collection_mint: *ctx.accounts.mint.key,
43        bubblegum_signer: *ctx.accounts.bubblegum_signer.key,
44        collection_authority_record,
45    }
46    .instruction(
47        mpl_token_metadata::instructions::BubblegumSetCollectionSizeInstructionArgs {
48            set_collection_size_args: mpl_token_metadata::types::SetCollectionSizeArgs { size },
49        },
50    );
51    solana_program::program::invoke_signed(
52        &ix,
53        &ToAccountInfos::to_account_infos(&ctx),
54        ctx.signer_seeds,
55    )
56    .map_err(Into::into)
57}
58
59pub fn burn_edition_nft<'info>(
60    ctx: CpiContext<'_, '_, '_, 'info, BurnEditionNft<'info>>,
61) -> Result<()> {
62    let ix = mpl_token_metadata::instructions::BurnEditionNft {
63        edition_marker_account: *ctx.accounts.edition_marker.key,
64        master_edition_account: *ctx.accounts.master_edition.key,
65        master_edition_mint: *ctx.accounts.master_edition_mint.key,
66        master_edition_token_account: *ctx.accounts.master_edition_token.key,
67        metadata: *ctx.accounts.metadata.key,
68        owner: *ctx.accounts.owner.key,
69        print_edition_account: *ctx.accounts.print_edition.key,
70        print_edition_mint: *ctx.accounts.print_edition_mint.key,
71        print_edition_token_account: *ctx.accounts.print_edition_token.key,
72        spl_token_program: *ctx.accounts.spl_token.key,
73    }
74    .instruction();
75    solana_program::program::invoke_signed(
76        &ix,
77        &ToAccountInfos::to_account_infos(&ctx),
78        ctx.signer_seeds,
79    )
80    .map_err(Into::into)
81}
82
83pub fn burn_nft<'info>(
84    ctx: CpiContext<'_, '_, '_, 'info, BurnNft<'info>>,
85    collection_metadata: Option<Pubkey>,
86) -> Result<()> {
87    let ix = mpl_token_metadata::instructions::BurnNft {
88        collection_metadata,
89        master_edition_account: *ctx.accounts.edition.key,
90        metadata: *ctx.accounts.metadata.key,
91        mint: *ctx.accounts.mint.key,
92        owner: *ctx.accounts.owner.key,
93        spl_token_program: *ctx.accounts.spl_token.key,
94        token_account: *ctx.accounts.token.key,
95    }
96    .instruction();
97    solana_program::program::invoke_signed(
98        &ix,
99        &ToAccountInfos::to_account_infos(&ctx),
100        ctx.signer_seeds,
101    )
102    .map_err(Into::into)
103}
104
105pub fn create_metadata_accounts_v3<'info>(
106    ctx: CpiContext<'_, '_, '_, 'info, CreateMetadataAccountsV3<'info>>,
107    data: mpl_token_metadata::types::DataV2,
108    is_mutable: bool,
109    update_authority_is_signer: bool,
110    collection_details: Option<mpl_token_metadata::types::CollectionDetails>,
111) -> Result<()> {
112    let ix = mpl_token_metadata::instructions::CreateMetadataAccountV3 {
113        metadata: *ctx.accounts.metadata.key,
114        mint: *ctx.accounts.mint.key,
115        mint_authority: *ctx.accounts.mint_authority.key,
116        payer: *ctx.accounts.payer.key,
117        rent: None,
118        system_program: system_program::ID,
119        update_authority: (
120            *ctx.accounts.update_authority.key,
121            update_authority_is_signer,
122        ),
123    }
124    .instruction(
125        mpl_token_metadata::instructions::CreateMetadataAccountV3InstructionArgs {
126            collection_details,
127            data,
128            is_mutable,
129        },
130    );
131    solana_program::program::invoke_signed(
132        &ix,
133        &ToAccountInfos::to_account_infos(&ctx),
134        ctx.signer_seeds,
135    )
136    .map_err(Into::into)
137}
138
139pub fn update_metadata_accounts_v2<'info>(
140    ctx: CpiContext<'_, '_, '_, 'info, UpdateMetadataAccountsV2<'info>>,
141    new_update_authority: Option<Pubkey>,
142    data: Option<mpl_token_metadata::types::DataV2>,
143    primary_sale_happened: Option<bool>,
144    is_mutable: Option<bool>,
145) -> Result<()> {
146    let ix = mpl_token_metadata::instructions::UpdateMetadataAccountV2 {
147        metadata: *ctx.accounts.metadata.key,
148        update_authority: *ctx.accounts.update_authority.key,
149    }
150    .instruction(
151        mpl_token_metadata::instructions::UpdateMetadataAccountV2InstructionArgs {
152            new_update_authority,
153            data,
154            primary_sale_happened,
155            is_mutable,
156        },
157    );
158    solana_program::program::invoke_signed(
159        &ix,
160        &ToAccountInfos::to_account_infos(&ctx),
161        ctx.signer_seeds,
162    )
163    .map_err(Into::into)
164}
165
166pub fn create_master_edition_v3<'info>(
167    ctx: CpiContext<'_, '_, '_, 'info, CreateMasterEditionV3<'info>>,
168    max_supply: Option<u64>,
169) -> Result<()> {
170    let ix = mpl_token_metadata::instructions::CreateMasterEditionV3 {
171        edition: *ctx.accounts.edition.key,
172        metadata: *ctx.accounts.metadata.key,
173        mint: *ctx.accounts.mint.key,
174        mint_authority: *ctx.accounts.mint_authority.key,
175        payer: *ctx.accounts.payer.key,
176        rent: None,
177        system_program: system_program::ID,
178        token_program: spl_token::ID,
179        update_authority: *ctx.accounts.update_authority.key,
180    }
181    .instruction(
182        mpl_token_metadata::instructions::CreateMasterEditionV3InstructionArgs { max_supply },
183    );
184    solana_program::program::invoke_signed(
185        &ix,
186        &ToAccountInfos::to_account_infos(&ctx),
187        ctx.signer_seeds,
188    )
189    .map_err(Into::into)
190}
191
192pub fn mint_new_edition_from_master_edition_via_token<'info>(
193    ctx: CpiContext<'_, '_, '_, 'info, MintNewEditionFromMasterEditionViaToken<'info>>,
194    edition: u64,
195) -> Result<()> {
196    let ix = mpl_token_metadata::instructions::MintNewEditionFromMasterEditionViaToken {
197        edition_mark_pda: *ctx.accounts.edition_mark_pda.key,
198        master_edition: *ctx.accounts.master_edition.key,
199        metadata: *ctx.accounts.metadata.key,
200        new_edition: *ctx.accounts.new_edition.key,
201        new_metadata: *ctx.accounts.new_metadata.key,
202        new_metadata_update_authority: *ctx.accounts.new_metadata_update_authority.key,
203        new_mint: *ctx.accounts.new_mint.key,
204        new_mint_authority: *ctx.accounts.new_mint_authority.key,
205        payer: *ctx.accounts.payer.key,
206        rent: None,
207        system_program: system_program::ID,
208        token_account: *ctx.accounts.token_account.key,
209        token_account_owner: *ctx.accounts.token_account_owner.key,
210        token_program: spl_token::ID,
211    }
212    .instruction(
213        mpl_token_metadata::instructions::MintNewEditionFromMasterEditionViaTokenInstructionArgs {
214            mint_new_edition_from_master_edition_via_token_args:
215                mpl_token_metadata::types::MintNewEditionFromMasterEditionViaTokenArgs { edition },
216        },
217    );
218    solana_program::program::invoke_signed(
219        &ix,
220        &ToAccountInfos::to_account_infos(&ctx),
221        ctx.signer_seeds,
222    )
223    .map_err(Into::into)
224}
225
226pub fn revoke_collection_authority<'info>(
227    ctx: CpiContext<'_, '_, '_, 'info, RevokeCollectionAuthority<'info>>,
228) -> Result<()> {
229    let ix = mpl_token_metadata::instructions::RevokeCollectionAuthority {
230        collection_authority_record: *ctx.accounts.collection_authority_record.key,
231        delegate_authority: *ctx.accounts.delegate_authority.key,
232        metadata: *ctx.accounts.metadata.key,
233        mint: *ctx.accounts.mint.key,
234        revoke_authority: *ctx.accounts.revoke_authority.key,
235    }
236    .instruction();
237    solana_program::program::invoke_signed(
238        &ix,
239        &ToAccountInfos::to_account_infos(&ctx),
240        ctx.signer_seeds,
241    )
242    .map_err(Into::into)
243}
244
245pub fn set_collection_size<'info>(
246    ctx: CpiContext<'_, '_, '_, 'info, SetCollectionSize<'info>>,
247    collection_authority_record: Option<Pubkey>,
248    size: u64,
249) -> Result<()> {
250    let ix = mpl_token_metadata::instructions::SetCollectionSize {
251        collection_authority: *ctx.accounts.update_authority.key,
252        collection_authority_record,
253        collection_metadata: *ctx.accounts.metadata.key,
254        collection_mint: *ctx.accounts.mint.key,
255    }
256    .instruction(
257        mpl_token_metadata::instructions::SetCollectionSizeInstructionArgs {
258            set_collection_size_args: mpl_token_metadata::types::SetCollectionSizeArgs { size },
259        },
260    );
261    solana_program::program::invoke_signed(
262        &ix,
263        &ToAccountInfos::to_account_infos(&ctx),
264        ctx.signer_seeds,
265    )
266    .map_err(Into::into)
267}
268
269pub fn verify_collection<'info>(
270    ctx: CpiContext<'_, '_, '_, 'info, VerifyCollection<'info>>,
271    collection_authority_record: Option<Pubkey>,
272) -> Result<()> {
273    let ix = mpl_token_metadata::instructions::VerifyCollection {
274        collection: *ctx.accounts.collection_metadata.key,
275        collection_authority: *ctx.accounts.collection_authority.key,
276        collection_authority_record,
277        collection_master_edition_account: *ctx.accounts.collection_master_edition.key,
278        collection_mint: *ctx.accounts.collection_mint.key,
279        metadata: *ctx.accounts.metadata.key,
280        payer: *ctx.accounts.payer.key,
281    }
282    .instruction();
283    solana_program::program::invoke_signed(
284        &ix,
285        &ToAccountInfos::to_account_infos(&ctx),
286        ctx.signer_seeds,
287    )
288    .map_err(Into::into)
289}
290
291pub fn verify_sized_collection_item<'info>(
292    ctx: CpiContext<'_, '_, '_, 'info, VerifySizedCollectionItem<'info>>,
293    collection_authority_record: Option<Pubkey>,
294) -> Result<()> {
295    let ix = mpl_token_metadata::instructions::VerifySizedCollectionItem {
296        collection: *ctx.accounts.collection_metadata.key,
297        collection_authority: *ctx.accounts.collection_authority.key,
298        collection_authority_record,
299        collection_master_edition_account: *ctx.accounts.collection_master_edition.key,
300        collection_mint: *ctx.accounts.collection_mint.key,
301        metadata: *ctx.accounts.metadata.key,
302        payer: *ctx.accounts.payer.key,
303    }
304    .instruction();
305    solana_program::program::invoke_signed(
306        &ix,
307        &ToAccountInfos::to_account_infos(&ctx),
308        ctx.signer_seeds,
309    )
310    .map_err(Into::into)
311}
312
313pub fn set_and_verify_collection<'info>(
314    ctx: CpiContext<'_, '_, '_, 'info, SetAndVerifyCollection<'info>>,
315    collection_authority_record: Option<Pubkey>,
316) -> Result<()> {
317    let ix = mpl_token_metadata::instructions::SetAndVerifyCollection {
318        collection: *ctx.accounts.collection_metadata.key,
319        collection_authority: *ctx.accounts.collection_authority.key,
320        collection_authority_record,
321        collection_master_edition_account: *ctx.accounts.collection_master_edition.key,
322        collection_mint: *ctx.accounts.collection_mint.key,
323        metadata: *ctx.accounts.metadata.key,
324        payer: *ctx.accounts.payer.key,
325        update_authority: *ctx.accounts.update_authority.key,
326    }
327    .instruction();
328    solana_program::program::invoke_signed(
329        &ix,
330        &ToAccountInfos::to_account_infos(&ctx),
331        ctx.signer_seeds,
332    )
333    .map_err(Into::into)
334}
335
336pub fn set_and_verify_sized_collection_item<'info>(
337    ctx: CpiContext<'_, '_, '_, 'info, SetAndVerifySizedCollectionItem<'info>>,
338    collection_authority_record: Option<Pubkey>,
339) -> Result<()> {
340    let ix = mpl_token_metadata::instructions::SetAndVerifySizedCollectionItem {
341        collection: *ctx.accounts.collection_metadata.key,
342        collection_authority: *ctx.accounts.collection_authority.key,
343        collection_authority_record,
344        collection_master_edition_account: *ctx.accounts.collection_master_edition.key,
345        collection_mint: *ctx.accounts.collection_mint.key,
346        metadata: *ctx.accounts.metadata.key,
347        payer: *ctx.accounts.payer.key,
348        update_authority: *ctx.accounts.update_authority.key,
349    }
350    .instruction();
351    solana_program::program::invoke_signed(
352        &ix,
353        &ToAccountInfos::to_account_infos(&ctx),
354        ctx.signer_seeds,
355    )
356    .map_err(Into::into)
357}
358
359pub fn freeze_delegated_account<'info>(
360    ctx: CpiContext<'_, '_, '_, 'info, FreezeDelegatedAccount<'info>>,
361) -> Result<()> {
362    let ix = mpl_token_metadata::instructions::FreezeDelegatedAccount {
363        delegate: *ctx.accounts.delegate.key,
364        edition: *ctx.accounts.edition.key,
365        mint: *ctx.accounts.mint.key,
366        token_account: *ctx.accounts.token_account.key,
367        token_program: *ctx.accounts.token_program.key,
368    }
369    .instruction();
370    solana_program::program::invoke_signed(
371        &ix,
372        &ToAccountInfos::to_account_infos(&ctx),
373        ctx.signer_seeds,
374    )
375    .map_err(Into::into)
376}
377
378pub fn thaw_delegated_account<'info>(
379    ctx: CpiContext<'_, '_, '_, 'info, ThawDelegatedAccount<'info>>,
380) -> Result<()> {
381    let ix = mpl_token_metadata::instructions::ThawDelegatedAccount {
382        delegate: *ctx.accounts.delegate.key,
383        edition: *ctx.accounts.edition.key,
384        mint: *ctx.accounts.mint.key,
385        token_account: *ctx.accounts.token_account.key,
386        token_program: *ctx.accounts.token_program.key,
387    }
388    .instruction();
389    solana_program::program::invoke_signed(
390        &ix,
391        &ToAccountInfos::to_account_infos(&ctx),
392        ctx.signer_seeds,
393    )
394    .map_err(Into::into)
395}
396
397pub fn update_primary_sale_happened_via_token<'info>(
398    ctx: CpiContext<'_, '_, '_, 'info, UpdatePrimarySaleHappenedViaToken<'info>>,
399) -> Result<()> {
400    let ix = mpl_token_metadata::instructions::UpdatePrimarySaleHappenedViaToken {
401        metadata: *ctx.accounts.metadata.key,
402        owner: *ctx.accounts.owner.key,
403        token: *ctx.accounts.token.key,
404    }
405    .instruction();
406    solana_program::program::invoke_signed(
407        &ix,
408        &ToAccountInfos::to_account_infos(&ctx),
409        ctx.signer_seeds,
410    )?;
411    Ok(())
412}
413
414pub fn set_token_standard<'info>(
415    ctx: CpiContext<'_, '_, '_, 'info, SetTokenStandard<'info>>,
416    edition_account: Option<Pubkey>,
417) -> Result<()> {
418    let ix = mpl_token_metadata::instructions::SetTokenStandard {
419        edition: edition_account,
420        metadata: *ctx.accounts.metadata_account.key,
421        mint: *ctx.accounts.mint_account.key,
422        update_authority: *ctx.accounts.update_authority.key,
423    }
424    .instruction();
425    solana_program::program::invoke_signed(
426        &ix,
427        &ToAccountInfos::to_account_infos(&ctx),
428        ctx.signer_seeds,
429    )
430    .map_err(Into::into)
431}
432
433pub fn sign_metadata<'info>(ctx: CpiContext<'_, '_, '_, 'info, SignMetadata<'info>>) -> Result<()> {
434    let ix = mpl_token_metadata::instructions::SignMetadata {
435        creator: *ctx.accounts.creator.key,
436        metadata: *ctx.accounts.metadata.key,
437    }
438    .instruction();
439    solana_program::program::invoke_signed(
440        &ix,
441        &ToAccountInfos::to_account_infos(&ctx),
442        ctx.signer_seeds,
443    )?;
444    Ok(())
445}
446
447pub fn remove_creator_verification<'info>(
448    ctx: CpiContext<'_, '_, '_, 'info, RemoveCreatorVerification<'info>>,
449) -> Result<()> {
450    let ix = mpl_token_metadata::instructions::RemoveCreatorVerification {
451        creator: *ctx.accounts.creator.key,
452        metadata: *ctx.accounts.metadata.key,
453    }
454    .instruction();
455    solana_program::program::invoke_signed(
456        &ix,
457        &ToAccountInfos::to_account_infos(&ctx),
458        ctx.signer_seeds,
459    )?;
460    Ok(())
461}
462
463pub fn utilize<'info>(
464    ctx: CpiContext<'_, '_, '_, 'info, Utilize<'info>>,
465    use_authority_record: Option<Pubkey>,
466    burner: Option<Pubkey>,
467    number_of_uses: u64,
468) -> Result<()> {
469    let ix = mpl_token_metadata::instructions::Utilize {
470        ata_program: spl_associated_token_account::ID,
471        burner,
472        metadata: *ctx.accounts.metadata.key,
473        mint: *ctx.accounts.mint.key,
474        owner: *ctx.accounts.owner.key,
475        rent: sysvar::rent::ID,
476        system_program: system_program::ID,
477        token_account: *ctx.accounts.token_account.key,
478        token_program: spl_token::ID,
479        use_authority: *ctx.accounts.use_authority.key,
480        use_authority_record,
481    }
482    .instruction(mpl_token_metadata::instructions::UtilizeInstructionArgs { number_of_uses });
483    solana_program::program::invoke_signed(
484        &ix,
485        &ToAccountInfos::to_account_infos(&ctx),
486        ctx.signer_seeds,
487    )
488    .map_err(Into::into)
489}
490
491pub fn unverify_collection<'info>(
492    ctx: CpiContext<'_, '_, '_, 'info, UnverifyCollection<'info>>,
493    collection_authority_record: Option<Pubkey>,
494) -> Result<()> {
495    let ix = mpl_token_metadata::instructions::UnverifyCollection {
496        collection: *ctx.accounts.metadata.key,
497        collection_authority: *ctx.accounts.collection_authority.key,
498        collection_authority_record,
499        collection_master_edition_account: *ctx.accounts.collection_master_edition_account.key,
500        collection_mint: *ctx.accounts.collection_mint.key,
501        metadata: *ctx.accounts.metadata.key,
502    }
503    .instruction();
504    solana_program::program::invoke_signed(
505        &ix,
506        &ToAccountInfos::to_account_infos(&ctx),
507        ctx.signer_seeds,
508    )
509    .map_err(Into::into)
510}
511
512pub fn unverify_sized_collection_item<'info>(
513    ctx: CpiContext<'_, '_, '_, 'info, UnverifySizedCollectionItem<'info>>,
514    collection_authority_record: Option<Pubkey>,
515) -> Result<()> {
516    let ix = mpl_token_metadata::instructions::UnverifySizedCollectionItem {
517        collection: *ctx.accounts.metadata.key,
518        collection_authority: *ctx.accounts.collection_authority.key,
519        collection_authority_record,
520        collection_master_edition_account: *ctx.accounts.collection_master_edition_account.key,
521        collection_mint: *ctx.accounts.collection_mint.key,
522        metadata: *ctx.accounts.metadata.key,
523        payer: *ctx.accounts.payer.key,
524    }
525    .instruction();
526    solana_program::program::invoke_signed(
527        &ix,
528        &ToAccountInfos::to_account_infos(&ctx),
529        ctx.signer_seeds,
530    )
531    .map_err(Into::into)
532}
533
534#[derive(Accounts)]
535pub struct ApproveCollectionAuthority<'info> {
536    pub collection_authority_record: AccountInfo<'info>,
537    pub new_collection_authority: AccountInfo<'info>,
538    pub update_authority: AccountInfo<'info>,
539    pub payer: AccountInfo<'info>,
540    pub metadata: AccountInfo<'info>,
541    pub mint: AccountInfo<'info>,
542}
543
544#[derive(Accounts)]
545pub struct BubblegumSetCollectionSize<'info> {
546    pub metadata_account: AccountInfo<'info>,
547    pub update_authority: AccountInfo<'info>,
548    pub mint: AccountInfo<'info>,
549    pub bubblegum_signer: AccountInfo<'info>,
550}
551
552#[derive(Accounts)]
553pub struct BurnEditionNft<'info> {
554    pub metadata: AccountInfo<'info>,
555    pub owner: AccountInfo<'info>,
556    pub print_edition_mint: AccountInfo<'info>,
557    pub master_edition_mint: AccountInfo<'info>,
558    pub print_edition_token: AccountInfo<'info>,
559    pub master_edition_token: AccountInfo<'info>,
560    pub master_edition: AccountInfo<'info>,
561    pub print_edition: AccountInfo<'info>,
562    pub edition_marker: AccountInfo<'info>,
563    pub spl_token: AccountInfo<'info>,
564}
565
566#[derive(Accounts)]
567pub struct BurnNft<'info> {
568    pub metadata: AccountInfo<'info>,
569    pub owner: AccountInfo<'info>,
570    pub mint: AccountInfo<'info>,
571    pub token: AccountInfo<'info>,
572    pub edition: AccountInfo<'info>,
573    pub spl_token: AccountInfo<'info>,
574}
575
576#[derive(Accounts)]
577pub struct CreateMetadataAccountsV3<'info> {
578    pub metadata: AccountInfo<'info>,
579    pub mint: AccountInfo<'info>,
580    pub mint_authority: AccountInfo<'info>,
581    pub payer: AccountInfo<'info>,
582    pub update_authority: AccountInfo<'info>,
583    pub system_program: AccountInfo<'info>,
584    pub rent: AccountInfo<'info>,
585}
586
587#[derive(Accounts)]
588pub struct UpdateMetadataAccountsV2<'info> {
589    pub metadata: AccountInfo<'info>,
590    pub update_authority: AccountInfo<'info>,
591}
592
593#[derive(Accounts)]
594pub struct CreateMasterEditionV3<'info> {
595    pub edition: AccountInfo<'info>,
596    pub mint: AccountInfo<'info>,
597    pub update_authority: AccountInfo<'info>,
598    pub mint_authority: AccountInfo<'info>,
599    pub payer: AccountInfo<'info>,
600    pub metadata: AccountInfo<'info>,
601    pub token_program: AccountInfo<'info>,
602    pub system_program: AccountInfo<'info>,
603    pub rent: AccountInfo<'info>,
604}
605
606#[derive(Accounts)]
607pub struct MintNewEditionFromMasterEditionViaToken<'info> {
608    pub new_metadata: AccountInfo<'info>,
609    pub new_edition: AccountInfo<'info>,
610    pub master_edition: AccountInfo<'info>,
611    pub new_mint: AccountInfo<'info>,
612    pub edition_mark_pda: AccountInfo<'info>,
613    pub new_mint_authority: AccountInfo<'info>,
614    pub payer: AccountInfo<'info>,
615    pub token_account_owner: AccountInfo<'info>,
616    pub token_account: AccountInfo<'info>,
617    pub new_metadata_update_authority: AccountInfo<'info>,
618    pub metadata: AccountInfo<'info>,
619    pub token_program: AccountInfo<'info>,
620    pub system_program: AccountInfo<'info>,
621    pub rent: AccountInfo<'info>,
622    //
623    // Not actually used by the program but still needed because it's needed
624    // for the pda calculation in the helper. :/
625    //
626    // The better thing to do would be to remove this and have the instruction
627    // helper pass in the `edition_mark_pda` directly.
628    //
629    pub metadata_mint: AccountInfo<'info>,
630}
631
632#[derive(Accounts)]
633pub struct RevokeCollectionAuthority<'info> {
634    pub collection_authority_record: AccountInfo<'info>,
635    pub delegate_authority: AccountInfo<'info>,
636    pub revoke_authority: AccountInfo<'info>,
637    pub metadata: AccountInfo<'info>,
638    pub mint: AccountInfo<'info>,
639}
640
641#[derive(Accounts)]
642pub struct SetCollectionSize<'info> {
643    pub metadata: AccountInfo<'info>,
644    pub mint: AccountInfo<'info>,
645    pub update_authority: AccountInfo<'info>,
646    pub system_program: AccountInfo<'info>,
647}
648
649#[derive(Accounts)]
650pub struct SetTokenStandard<'info> {
651    pub metadata_account: AccountInfo<'info>,
652    pub update_authority: AccountInfo<'info>,
653    pub mint_account: AccountInfo<'info>,
654}
655
656#[derive(Accounts)]
657pub struct VerifyCollection<'info> {
658    pub payer: AccountInfo<'info>,
659    pub metadata: AccountInfo<'info>,
660    pub collection_authority: AccountInfo<'info>,
661    pub collection_mint: AccountInfo<'info>,
662    pub collection_metadata: AccountInfo<'info>,
663    pub collection_master_edition: AccountInfo<'info>,
664}
665
666#[derive(Accounts)]
667pub struct VerifySizedCollectionItem<'info> {
668    pub payer: AccountInfo<'info>,
669    pub metadata: AccountInfo<'info>,
670    pub collection_authority: AccountInfo<'info>,
671    pub collection_mint: AccountInfo<'info>,
672    pub collection_metadata: AccountInfo<'info>,
673    pub collection_master_edition: AccountInfo<'info>,
674}
675
676#[derive(Accounts)]
677pub struct SetAndVerifyCollection<'info> {
678    pub metadata: AccountInfo<'info>,
679    pub collection_authority: AccountInfo<'info>,
680    pub payer: AccountInfo<'info>,
681    pub update_authority: AccountInfo<'info>,
682    pub collection_mint: AccountInfo<'info>,
683    pub collection_metadata: AccountInfo<'info>,
684    pub collection_master_edition: AccountInfo<'info>,
685}
686
687#[derive(Accounts)]
688pub struct SetAndVerifySizedCollectionItem<'info> {
689    pub metadata: AccountInfo<'info>,
690    pub collection_authority: AccountInfo<'info>,
691    pub payer: AccountInfo<'info>,
692    pub update_authority: AccountInfo<'info>,
693    pub collection_mint: AccountInfo<'info>,
694    pub collection_metadata: AccountInfo<'info>,
695    pub collection_master_edition: AccountInfo<'info>,
696}
697
698#[derive(Accounts)]
699pub struct FreezeDelegatedAccount<'info> {
700    pub metadata: AccountInfo<'info>,
701    pub delegate: AccountInfo<'info>,
702    pub token_account: AccountInfo<'info>,
703    pub edition: AccountInfo<'info>,
704    pub mint: AccountInfo<'info>,
705    pub token_program: AccountInfo<'info>,
706}
707
708#[derive(Accounts)]
709pub struct ThawDelegatedAccount<'info> {
710    pub metadata: AccountInfo<'info>,
711    pub delegate: AccountInfo<'info>,
712    pub token_account: AccountInfo<'info>,
713    pub edition: AccountInfo<'info>,
714    pub mint: AccountInfo<'info>,
715    pub token_program: AccountInfo<'info>,
716}
717
718#[derive(Accounts)]
719pub struct UpdatePrimarySaleHappenedViaToken<'info> {
720    pub metadata: AccountInfo<'info>,
721    pub owner: AccountInfo<'info>,
722    pub token: AccountInfo<'info>,
723}
724
725#[derive(Accounts)]
726pub struct SignMetadata<'info> {
727    pub creator: AccountInfo<'info>,
728    pub metadata: AccountInfo<'info>,
729}
730
731#[derive(Accounts)]
732pub struct RemoveCreatorVerification<'info> {
733    pub creator: AccountInfo<'info>,
734    pub metadata: AccountInfo<'info>,
735}
736
737#[derive(Accounts)]
738pub struct Utilize<'info> {
739    pub metadata: AccountInfo<'info>,
740    pub token_account: AccountInfo<'info>,
741    pub mint: AccountInfo<'info>,
742    pub use_authority: AccountInfo<'info>,
743    pub owner: AccountInfo<'info>,
744}
745
746#[derive(Accounts)]
747pub struct UnverifyCollection<'info> {
748    pub metadata: AccountInfo<'info>,
749    pub collection_authority: AccountInfo<'info>,
750    pub collection_mint: AccountInfo<'info>,
751    pub collection: AccountInfo<'info>,
752    pub collection_master_edition_account: AccountInfo<'info>,
753}
754
755#[derive(Accounts)]
756pub struct UnverifySizedCollectionItem<'info> {
757    pub metadata: AccountInfo<'info>,
758    pub collection_authority: AccountInfo<'info>,
759    pub payer: AccountInfo<'info>,
760    pub collection_mint: AccountInfo<'info>,
761    pub collection: AccountInfo<'info>,
762    pub collection_master_edition_account: AccountInfo<'info>,
763}
764
765#[derive(Clone, Debug, PartialEq)]
766pub struct MetadataAccount(mpl_token_metadata::accounts::Metadata);
767
768impl anchor_lang::AccountDeserialize for MetadataAccount {
769    fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
770        let md = Self::try_deserialize_unchecked(buf)?;
771        if md.key != mpl_token_metadata::types::Key::MetadataV1 {
772            return Err(ErrorCode::AccountNotInitialized.into());
773        }
774        Ok(md)
775    }
776
777    fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
778        let md = mpl_token_metadata::accounts::Metadata::safe_deserialize(buf)?;
779        Ok(Self(md))
780    }
781}
782
783impl anchor_lang::AccountSerialize for MetadataAccount {}
784
785impl anchor_lang::Owner for MetadataAccount {
786    fn owner() -> Pubkey {
787        ID
788    }
789}
790
791impl Deref for MetadataAccount {
792    type Target = mpl_token_metadata::accounts::Metadata;
793    fn deref(&self) -> &Self::Target {
794        &self.0
795    }
796}
797
798#[cfg(feature = "idl-build")]
799impl anchor_lang::IdlBuild for MetadataAccount {}
800
801#[derive(Clone, Debug, PartialEq)]
802pub struct MasterEditionAccount(mpl_token_metadata::accounts::MasterEdition);
803
804impl anchor_lang::AccountDeserialize for MasterEditionAccount {
805    fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
806        let me = Self::try_deserialize_unchecked(buf)?;
807        if me.key != mpl_token_metadata::types::Key::MasterEditionV2 {
808            return Err(ErrorCode::AccountNotInitialized.into());
809        }
810        Ok(me)
811    }
812
813    fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
814        let result = mpl_token_metadata::accounts::MasterEdition::safe_deserialize(buf)?;
815        Ok(Self(result))
816    }
817}
818
819impl Deref for MasterEditionAccount {
820    type Target = mpl_token_metadata::accounts::MasterEdition;
821    fn deref(&self) -> &Self::Target {
822        &self.0
823    }
824}
825
826impl anchor_lang::AccountSerialize for MasterEditionAccount {}
827
828impl anchor_lang::Owner for MasterEditionAccount {
829    fn owner() -> Pubkey {
830        ID
831    }
832}
833
834#[cfg(feature = "idl-build")]
835impl anchor_lang::IdlBuild for MasterEditionAccount {}
836
837#[derive(Clone, Debug, PartialEq)]
838pub struct TokenRecordAccount(mpl_token_metadata::accounts::TokenRecord);
839
840impl TokenRecordAccount {
841    pub const LEN: usize = mpl_token_metadata::accounts::TokenRecord::LEN;
842}
843impl anchor_lang::AccountDeserialize for TokenRecordAccount {
844    fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
845        let tr = Self::try_deserialize_unchecked(buf)?;
846        if tr.key != mpl_token_metadata::types::Key::TokenRecord {
847            return Err(ErrorCode::AccountNotInitialized.into());
848        }
849        Ok(tr)
850    }
851
852    fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
853        let tr = mpl_token_metadata::accounts::TokenRecord::safe_deserialize(buf)?;
854        Ok(Self(tr))
855    }
856}
857
858impl anchor_lang::AccountSerialize for TokenRecordAccount {}
859
860impl anchor_lang::Owner for TokenRecordAccount {
861    fn owner() -> Pubkey {
862        ID
863    }
864}
865
866impl Deref for TokenRecordAccount {
867    type Target = mpl_token_metadata::accounts::TokenRecord;
868    fn deref(&self) -> &Self::Target {
869        &self.0
870    }
871}
872
873#[cfg(feature = "idl-build")]
874impl anchor_lang::IdlBuild for TokenRecordAccount {}
875
876#[derive(Clone)]
877pub struct Metadata;
878
879impl anchor_lang::Id for Metadata {
880    fn id() -> Pubkey {
881        ID
882    }
883}