carbon_mpl_token_metadata_decoder/instructions/
mod.rs

1use crate::PROGRAM_ID;
2
3use super::TokenMetadataDecoder;
4pub mod _use;
5pub mod approve_collection_authority;
6pub mod approve_use_authority;
7pub mod bubblegum_set_collection_size;
8pub mod burn;
9pub mod burn_edition_nft;
10pub mod burn_nft;
11pub mod close_accounts;
12pub mod close_escrow_account;
13pub mod collect;
14pub mod convert_master_edition_v1_to_v2;
15pub mod create;
16pub mod create_escrow_account;
17pub mod create_master_edition;
18pub mod create_master_edition_v3;
19pub mod create_metadata_account;
20pub mod create_metadata_account_v2;
21pub mod create_metadata_account_v3;
22pub mod delegate;
23pub mod deprecated_create_master_edition;
24pub mod deprecated_create_reservation_list;
25pub mod deprecated_mint_new_edition_from_master_edition_via_printing_token;
26pub mod deprecated_mint_printing_tokens;
27pub mod deprecated_mint_printing_tokens_via_token;
28pub mod deprecated_set_reservation_list;
29pub mod freeze_delegated_account;
30pub mod lock;
31pub mod migrate;
32pub mod mint;
33pub mod mint_new_edition_from_master_edition_via_token;
34pub mod mint_new_edition_from_master_edition_via_vault_proxy;
35pub mod print;
36pub mod puff_metadata;
37pub mod remove_creator_verification;
38pub mod resize;
39pub mod revoke;
40pub mod revoke_collection_authority;
41pub mod revoke_use_authority;
42pub mod set_and_verify_collection;
43pub mod set_and_verify_sized_collection_item;
44pub mod set_collection_size;
45pub mod set_token_standard;
46pub mod sign_metadata;
47pub mod thaw_delegated_account;
48pub mod transfer;
49pub mod transfer_out_of_escrow;
50pub mod unlock;
51pub mod unverify;
52pub mod unverify_collection;
53pub mod unverify_sized_collection_item;
54pub mod update;
55pub mod update_metadata_account;
56pub mod update_metadata_account_v2;
57pub mod update_primary_sale_happened_via_token;
58pub mod utilize;
59pub mod verify;
60pub mod verify_collection;
61pub mod verify_sized_collection_item;
62
63#[derive(
64    carbon_core::InstructionType,
65    serde::Serialize,
66    serde::Deserialize,
67    PartialEq,
68    Eq,
69    Debug,
70    Clone,
71    Hash,
72)]
73pub enum TokenMetadataInstruction {
74    CreateMetadataAccount(create_metadata_account::CreateMetadataAccount),
75    UpdateMetadataAccount(update_metadata_account::UpdateMetadataAccount),
76    DeprecatedCreateMasterEdition(deprecated_create_master_edition::DeprecatedCreateMasterEdition),
77    DeprecatedMintNewEditionFromMasterEditionViaPrintingToken(deprecated_mint_new_edition_from_master_edition_via_printing_token::DeprecatedMintNewEditionFromMasterEditionViaPrintingToken),
78    UpdatePrimarySaleHappenedViaToken(update_primary_sale_happened_via_token::UpdatePrimarySaleHappenedViaToken),
79    DeprecatedSetReservationList(deprecated_set_reservation_list::DeprecatedSetReservationList),
80    DeprecatedCreateReservationList(deprecated_create_reservation_list::DeprecatedCreateReservationList),
81    SignMetadata(sign_metadata::SignMetadata),
82    DeprecatedMintPrintingTokensViaToken(deprecated_mint_printing_tokens_via_token::DeprecatedMintPrintingTokensViaToken),
83    DeprecatedMintPrintingTokens(deprecated_mint_printing_tokens::DeprecatedMintPrintingTokens),
84    CreateMasterEdition(create_master_edition::CreateMasterEdition),
85    MintNewEditionFromMasterEditionViaToken(mint_new_edition_from_master_edition_via_token::MintNewEditionFromMasterEditionViaToken),
86    ConvertMasterEditionV1ToV2(convert_master_edition_v1_to_v2::ConvertMasterEditionV1ToV2),
87    MintNewEditionFromMasterEditionViaVaultProxy(mint_new_edition_from_master_edition_via_vault_proxy::MintNewEditionFromMasterEditionViaVaultProxy),
88    PuffMetadata(puff_metadata::PuffMetadata),
89    UpdateMetadataAccountV2(update_metadata_account_v2::UpdateMetadataAccountV2),
90    CreateMetadataAccountV2(create_metadata_account_v2::CreateMetadataAccountV2),
91    CreateMasterEditionV3(create_master_edition_v3::CreateMasterEditionV3),
92    VerifyCollection(verify_collection::VerifyCollection),
93    Utilize(utilize::Utilize),
94    ApproveUseAuthority(approve_use_authority::ApproveUseAuthority),
95    RevokeUseAuthority(revoke_use_authority::RevokeUseAuthority),
96    UnverifyCollection(unverify_collection::UnverifyCollection),
97    ApproveCollectionAuthority(approve_collection_authority::ApproveCollectionAuthority),
98    RevokeCollectionAuthority(revoke_collection_authority::RevokeCollectionAuthority),
99    SetAndVerifyCollection(set_and_verify_collection::SetAndVerifyCollection),
100    FreezeDelegatedAccount(freeze_delegated_account::FreezeDelegatedAccount),
101    ThawDelegatedAccount(thaw_delegated_account::ThawDelegatedAccount),
102    RemoveCreatorVerification(remove_creator_verification::RemoveCreatorVerification),
103    BurnNft(burn_nft::BurnNft),
104    VerifySizedCollectionItem(verify_sized_collection_item::VerifySizedCollectionItem),
105    UnverifySizedCollectionItem(unverify_sized_collection_item::UnverifySizedCollectionItem),
106    SetAndVerifySizedCollectionItem(set_and_verify_sized_collection_item::SetAndVerifySizedCollectionItem),
107    CreateMetadataAccountV3(create_metadata_account_v3::CreateMetadataAccountV3),
108    SetCollectionSize(set_collection_size::SetCollectionSize),
109    SetTokenStandard(set_token_standard::SetTokenStandard),
110    BubblegumSetCollectionSize(bubblegum_set_collection_size::BubblegumSetCollectionSize),
111    BurnEditionNft(burn_edition_nft::BurnEditionNft),
112    CreateEscrowAccount(create_escrow_account::CreateEscrowAccount),
113    CloseEscrowAccount(close_escrow_account::CloseEscrowAccount),
114    TransferOutOfEscrow(transfer_out_of_escrow::TransferOutOfEscrow),
115    Burn(burn::Burn),
116    Create(create::Create),
117    Mint(mint::Mint),
118    Delegate(delegate::Delegate),
119    Revoke(revoke::Revoke),
120    Lock(lock::Lock),
121    Unlock(unlock::Unlock),
122    Migrate(migrate::Migrate),
123    Transfer(transfer::Transfer),
124    Update(update::Update),
125    Use(_use::Use),
126    Verify(verify::Verify),
127    Unverify(unverify::Unverify),
128    Collect(collect::Collect),
129    Print(print::Print),
130    Resize(resize::Resize),
131    CloseAccounts(close_accounts::CloseAccounts),
132}
133
134impl carbon_core::instruction::InstructionDecoder<'_> for TokenMetadataDecoder {
135    type InstructionType = TokenMetadataInstruction;
136
137    fn decode_instruction(
138        &self,
139        instruction: &solana_instruction::Instruction,
140    ) -> Option<carbon_core::instruction::DecodedInstruction<Self::InstructionType>> {
141        if !instruction.program_id.eq(&PROGRAM_ID) {
142            return None;
143        }
144
145        carbon_core::try_decode_instructions!(instruction,
146            TokenMetadataInstruction::CreateMetadataAccount => create_metadata_account::CreateMetadataAccount,
147            TokenMetadataInstruction::UpdateMetadataAccount => update_metadata_account::UpdateMetadataAccount,
148            TokenMetadataInstruction::DeprecatedCreateMasterEdition => deprecated_create_master_edition::DeprecatedCreateMasterEdition,
149            TokenMetadataInstruction::DeprecatedMintNewEditionFromMasterEditionViaPrintingToken => deprecated_mint_new_edition_from_master_edition_via_printing_token::DeprecatedMintNewEditionFromMasterEditionViaPrintingToken,
150            TokenMetadataInstruction::UpdatePrimarySaleHappenedViaToken => update_primary_sale_happened_via_token::UpdatePrimarySaleHappenedViaToken,
151            TokenMetadataInstruction::DeprecatedSetReservationList => deprecated_set_reservation_list::DeprecatedSetReservationList,
152            TokenMetadataInstruction::DeprecatedCreateReservationList => deprecated_create_reservation_list::DeprecatedCreateReservationList,
153            TokenMetadataInstruction::SignMetadata => sign_metadata::SignMetadata,
154            TokenMetadataInstruction::DeprecatedMintPrintingTokensViaToken => deprecated_mint_printing_tokens_via_token::DeprecatedMintPrintingTokensViaToken,
155            TokenMetadataInstruction::DeprecatedMintPrintingTokens => deprecated_mint_printing_tokens::DeprecatedMintPrintingTokens,
156            TokenMetadataInstruction::CreateMasterEdition => create_master_edition::CreateMasterEdition,
157            TokenMetadataInstruction::MintNewEditionFromMasterEditionViaToken => mint_new_edition_from_master_edition_via_token::MintNewEditionFromMasterEditionViaToken,
158            TokenMetadataInstruction::ConvertMasterEditionV1ToV2 => convert_master_edition_v1_to_v2::ConvertMasterEditionV1ToV2,
159            TokenMetadataInstruction::MintNewEditionFromMasterEditionViaVaultProxy => mint_new_edition_from_master_edition_via_vault_proxy::MintNewEditionFromMasterEditionViaVaultProxy,
160            TokenMetadataInstruction::PuffMetadata => puff_metadata::PuffMetadata,
161            TokenMetadataInstruction::UpdateMetadataAccountV2 => update_metadata_account_v2::UpdateMetadataAccountV2,
162            TokenMetadataInstruction::CreateMetadataAccountV2 => create_metadata_account_v2::CreateMetadataAccountV2,
163            TokenMetadataInstruction::CreateMasterEditionV3 => create_master_edition_v3::CreateMasterEditionV3,
164            TokenMetadataInstruction::VerifyCollection => verify_collection::VerifyCollection,
165            TokenMetadataInstruction::Utilize => utilize::Utilize,
166            TokenMetadataInstruction::ApproveUseAuthority => approve_use_authority::ApproveUseAuthority,
167            TokenMetadataInstruction::RevokeUseAuthority => revoke_use_authority::RevokeUseAuthority,
168            TokenMetadataInstruction::UnverifyCollection => unverify_collection::UnverifyCollection,
169            TokenMetadataInstruction::ApproveCollectionAuthority => approve_collection_authority::ApproveCollectionAuthority,
170            TokenMetadataInstruction::RevokeCollectionAuthority => revoke_collection_authority::RevokeCollectionAuthority,
171            TokenMetadataInstruction::SetAndVerifyCollection => set_and_verify_collection::SetAndVerifyCollection,
172            TokenMetadataInstruction::FreezeDelegatedAccount => freeze_delegated_account::FreezeDelegatedAccount,
173            TokenMetadataInstruction::ThawDelegatedAccount => thaw_delegated_account::ThawDelegatedAccount,
174            TokenMetadataInstruction::RemoveCreatorVerification => remove_creator_verification::RemoveCreatorVerification,
175            TokenMetadataInstruction::BurnNft => burn_nft::BurnNft,
176            TokenMetadataInstruction::VerifySizedCollectionItem => verify_sized_collection_item::VerifySizedCollectionItem,
177            TokenMetadataInstruction::UnverifySizedCollectionItem => unverify_sized_collection_item::UnverifySizedCollectionItem,
178            TokenMetadataInstruction::SetAndVerifySizedCollectionItem => set_and_verify_sized_collection_item::SetAndVerifySizedCollectionItem,
179            TokenMetadataInstruction::CreateMetadataAccountV3 => create_metadata_account_v3::CreateMetadataAccountV3,
180            TokenMetadataInstruction::SetCollectionSize => set_collection_size::SetCollectionSize,
181            TokenMetadataInstruction::SetTokenStandard => set_token_standard::SetTokenStandard,
182            TokenMetadataInstruction::BubblegumSetCollectionSize => bubblegum_set_collection_size::BubblegumSetCollectionSize,
183            TokenMetadataInstruction::BurnEditionNft => burn_edition_nft::BurnEditionNft,
184            TokenMetadataInstruction::CreateEscrowAccount => create_escrow_account::CreateEscrowAccount,
185            TokenMetadataInstruction::CloseEscrowAccount => close_escrow_account::CloseEscrowAccount,
186            TokenMetadataInstruction::TransferOutOfEscrow => transfer_out_of_escrow::TransferOutOfEscrow,
187            TokenMetadataInstruction::Burn => burn::Burn,
188            TokenMetadataInstruction::Create => create::Create,
189            TokenMetadataInstruction::Mint => mint::Mint,
190            TokenMetadataInstruction::Delegate => delegate::Delegate,
191            TokenMetadataInstruction::Revoke => revoke::Revoke,
192            TokenMetadataInstruction::Lock => lock::Lock,
193            TokenMetadataInstruction::Unlock => unlock::Unlock,
194            TokenMetadataInstruction::Migrate => migrate::Migrate,
195            TokenMetadataInstruction::Transfer => transfer::Transfer,
196            TokenMetadataInstruction::Update => update::Update,
197            TokenMetadataInstruction::Use => _use::Use,
198            TokenMetadataInstruction::Verify => verify::Verify,
199            TokenMetadataInstruction::Unverify => unverify::Unverify,
200            TokenMetadataInstruction::Collect => collect::Collect,
201            TokenMetadataInstruction::Print => print::Print,
202            TokenMetadataInstruction::Resize => resize::Resize,
203            TokenMetadataInstruction::CloseAccounts => close_accounts::CloseAccounts,
204        )
205    }
206}
207
208#[cfg(test)]
209mod tests {
210    use super::*;
211    use crate::{
212        instructions::{
213            create_metadata_account_v3::{
214                CreateMetadataAccountV3, CreateMetadataAccountV3InstructionAccounts,
215            },
216            TokenMetadataInstruction,
217        },
218        types::{CreateMetadataAccountArgsV3, Creator, DataV2},
219        TokenMetadataDecoder,
220    };
221    use carbon_core::{deserialize::ArrangeAccounts, instruction::InstructionDecoder};
222    use carbon_test_utils::read_instruction;
223    use solana_instruction::AccountMeta;
224    use solana_pubkey::pubkey;
225
226    #[test]
227    fn test_decode_create_metadata_v3_without_rent() {
228        let expected_ix = TokenMetadataInstruction::CreateMetadataAccountV3(CreateMetadataAccountV3 {
229            create_metadata_account_args_v3: CreateMetadataAccountArgsV3 {
230                data: DataV2 {
231                    name: "スキズー".to_owned(),
232                    symbol: "SKZOO".to_owned(),
233                    uri: "https://ipfs.io/ipfs/bafkreigwusbaqy7cgbh3mvij5gu4c2m4msaceoutpw5fyisypych7glzjm".to_owned(),
234                    seller_fee_basis_points: 0,
235                    creators: Some(
236                        vec![
237                            Creator {
238                            address: pubkey!("WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh"),
239                            verified: true,
240                            share: 100,
241                        }
242                        ]
243                    ),
244                    collection: None,
245                    uses: None,
246                },
247                is_mutable: false,
248                collection_details: None,
249            }
250        });
251
252        let expected_accounts = vec![
253            AccountMeta::new(
254                pubkey!("FURfzvnjVPdjrfMBRzeSgahzS1xietCqiv8SG9pCS8ke"),
255                false,
256            ),
257            AccountMeta::new(
258                pubkey!("A3p836DWHzDA3DY73QfJSLCqekkhGohNXVAHAa1Qbonk"),
259                true,
260            ),
261            AccountMeta::new_readonly(
262                pubkey!("WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh"),
263                false,
264            ),
265            AccountMeta::new(
266                pubkey!("5f5BPCCNeMkekfjFZi18kAYU95rRdM2jToGaNZZwYZX6"),
267                true,
268            ),
269            AccountMeta::new_readonly(
270                pubkey!("WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh"),
271                false,
272            ),
273            AccountMeta::new_readonly(pubkey!("11111111111111111111111111111111"), false),
274        ];
275
276        let expected_arranged_accounts = CreateMetadataAccountV3InstructionAccounts {
277            metadata: pubkey!("FURfzvnjVPdjrfMBRzeSgahzS1xietCqiv8SG9pCS8ke"),
278            mint: pubkey!("A3p836DWHzDA3DY73QfJSLCqekkhGohNXVAHAa1Qbonk"),
279            mint_authority: pubkey!("WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh"),
280            payer: pubkey!("5f5BPCCNeMkekfjFZi18kAYU95rRdM2jToGaNZZwYZX6"),
281            update_authority: pubkey!("WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh"),
282            system_program: pubkey!("11111111111111111111111111111111"),
283            rent: None,
284        };
285
286        let decoder = TokenMetadataDecoder;
287
288        const FIXTURE_PATH: &str = "tests/fixtures/create_metadata_v3_ix.json";
289        let instruction = read_instruction(FIXTURE_PATH).expect("read fixture");
290
291        let decoded_instruction = decoder
292            .decode_instruction(&instruction)
293            .expect("decode instruction");
294
295        let decoded_arranged_accounts =
296            CreateMetadataAccountV3::arrange_accounts(&instruction.accounts)
297                .expect("arrange accounts");
298
299        assert_eq!(decoded_instruction.data, expected_ix);
300        assert_eq!(decoded_instruction.accounts, expected_accounts);
301        assert_eq!(decoded_instruction.program_id, PROGRAM_ID);
302        assert!(decoded_arranged_accounts.rent.is_none());
303        assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
304    }
305}