mpl_testing_utils/utils/
master_edition_v2.rs

1use crate::utils::*;
2use borsh::ser::BorshSerialize;
3use mpl_token_metadata::{
4    id,
5    instruction::{self, CreateMasterEditionArgs, MetadataInstruction},
6    state::{EDITION, PREFIX},
7};
8use solana_program::{
9    borsh::try_from_slice_unchecked,
10    instruction::{AccountMeta, Instruction},
11    sysvar,
12};
13use solana_program_test::*;
14use solana_sdk::{
15    pubkey::Pubkey,
16    signature::{Keypair, Signer},
17    transaction::Transaction,
18};
19
20#[derive(Debug)]
21pub struct MasterEditionV2 {
22    pub pubkey: Pubkey,
23    pub metadata_pubkey: Pubkey,
24    pub mint_pubkey: Pubkey,
25}
26
27impl MasterEditionV2 {
28    pub fn new(metadata: &Metadata) -> Self {
29        let program_id = id();
30        let mint_pubkey = metadata.mint.pubkey();
31
32        let master_edition_seeds = &[
33            PREFIX.as_bytes(),
34            program_id.as_ref(),
35            mint_pubkey.as_ref(),
36            EDITION.as_bytes(),
37        ];
38        let (pubkey, _) = Pubkey::find_program_address(master_edition_seeds, &id());
39
40        MasterEditionV2 {
41            pubkey,
42            metadata_pubkey: metadata.pubkey,
43            mint_pubkey,
44        }
45    }
46
47    pub async fn get_data(
48        &self,
49        context: &mut ProgramTestContext,
50    ) -> mpl_token_metadata::state::MasterEditionV2 {
51        let account = get_account(context, &self.pubkey).await;
52        try_from_slice_unchecked(&account.data).unwrap()
53    }
54
55    pub async fn get_data_from_account(
56        context: &mut ProgramTestContext,
57        pubkey: &Pubkey,
58    ) -> mpl_token_metadata::state::MasterEditionV2 {
59        let account = get_account(context, pubkey).await;
60        try_from_slice_unchecked(&account.data).unwrap()
61    }
62
63    pub async fn create_with_invalid_token_program(
64        &self,
65        context: &mut ProgramTestContext,
66        max_supply: Option<u64>,
67    ) -> Result<(), BanksClientError> {
68        let fake_token_program = Keypair::new();
69
70        let fake_instruction = Instruction {
71            program_id: mpl_token_metadata::id(),
72            accounts: vec![
73                AccountMeta::new(self.pubkey, false),
74                AccountMeta::new(self.mint_pubkey, false),
75                AccountMeta::new_readonly(context.payer.pubkey(), true),
76                AccountMeta::new_readonly(context.payer.pubkey(), true),
77                AccountMeta::new_readonly(context.payer.pubkey(), true),
78                AccountMeta::new_readonly(self.metadata_pubkey, false),
79                AccountMeta::new_readonly(fake_token_program.pubkey(), false),
80                AccountMeta::new_readonly(solana_program::system_program::id(), false),
81                AccountMeta::new_readonly(sysvar::rent::id(), false),
82            ],
83            data: MetadataInstruction::CreateMasterEdition(CreateMasterEditionArgs { max_supply })
84                .try_to_vec()
85                .unwrap(),
86        };
87
88        let tx = Transaction::new_signed_with_payer(
89            &[fake_instruction],
90            Some(&context.payer.pubkey()),
91            &[&context.payer],
92            context.last_blockhash,
93        );
94
95        context.banks_client.process_transaction(tx).await
96    }
97
98    pub async fn create(
99        &self,
100        context: &mut ProgramTestContext,
101        max_supply: Option<u64>,
102    ) -> Result<(), BanksClientError> {
103        let tx = Transaction::new_signed_with_payer(
104            &[instruction::create_master_edition(
105                id(),
106                self.pubkey,
107                self.mint_pubkey,
108                context.payer.pubkey(),
109                context.payer.pubkey(),
110                self.metadata_pubkey,
111                context.payer.pubkey(),
112                max_supply,
113            )],
114            Some(&context.payer.pubkey()),
115            &[&context.payer],
116            context.last_blockhash,
117        );
118
119        context.banks_client.process_transaction(tx).await
120    }
121
122    pub async fn create_v3(
123        &self,
124        context: &mut ProgramTestContext,
125        max_supply: Option<u64>,
126    ) -> Result<(), BanksClientError> {
127        let tx = Transaction::new_signed_with_payer(
128            &[instruction::create_master_edition_v3(
129                id(),
130                self.pubkey,
131                self.mint_pubkey,
132                context.payer.pubkey(),
133                context.payer.pubkey(),
134                self.metadata_pubkey,
135                context.payer.pubkey(),
136                max_supply,
137            )],
138            Some(&context.payer.pubkey()),
139            &[&context.payer],
140            context.last_blockhash,
141        );
142
143        context.banks_client.process_transaction(tx).await
144    }
145}