carbon_mpl_token_metadata_decoder/accounts/
mod.rs

1use {
2    super::TokenMetadataDecoder,
3    crate::types::Key,
4    carbon_core::{account::AccountDecoder, deserialize::CarbonDeserialize},
5    solana_pubkey::{pubkey, Pubkey},
6};
7pub mod collection_authority_record;
8pub mod edition;
9pub mod edition_marker;
10pub mod edition_marker_v2;
11pub mod holder_delegate_record;
12pub mod master_edition_v1;
13pub mod master_edition_v2;
14pub mod metadata;
15pub mod metadata_delegate_record;
16pub mod reservation_list_v1;
17pub mod reservation_list_v2;
18pub mod token_owned_escrow;
19pub mod token_record;
20pub mod use_authority_record;
21
22pub enum TokenMetadataAccount {
23    CollectionAuthorityRecord(collection_authority_record::CollectionAuthorityRecord),
24    MetadataDelegateRecord(metadata_delegate_record::MetadataDelegateRecord),
25    HolderDelegateRecord(holder_delegate_record::HolderDelegateRecord),
26    Edition(edition::Edition),
27    EditionMarker(edition_marker::EditionMarker),
28    EditionMarkerV2(edition_marker_v2::EditionMarkerV2),
29    TokenOwnedEscrow(token_owned_escrow::TokenOwnedEscrow),
30    MasterEditionV2(master_edition_v2::MasterEditionV2),
31    MasterEditionV1(master_edition_v1::MasterEditionV1),
32    Metadata(metadata::Metadata),
33    TokenRecord(token_record::TokenRecord),
34    ReservationListV2(reservation_list_v2::ReservationListV2),
35    ReservationListV1(reservation_list_v1::ReservationListV1),
36    UseAuthorityRecord(use_authority_record::UseAuthorityRecord),
37}
38
39impl AccountDecoder<'_> for TokenMetadataDecoder {
40    type AccountType = TokenMetadataAccount;
41    fn decode_account(
42        &self,
43        account: &solana_account::Account,
44    ) -> Option<carbon_core::account::DecodedAccount<Self::AccountType>> {
45        // Guard
46        let mpl_token_metadata_id: Pubkey = pubkey!("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s");
47        if account.owner != mpl_token_metadata_id {
48            return None;
49        }
50
51        let tag = account.data.first().copied()?;
52
53        let data_enum = match tag {
54            x if x == Key::MetadataV1 as u8 => {
55                let slice = account.data.as_slice();
56                metadata::Metadata::deserialize(slice).map(TokenMetadataAccount::Metadata)
57            }
58            x if x == Key::CollectionAuthorityRecord as u8 => {
59                let slice = account.data.as_slice();
60                collection_authority_record::CollectionAuthorityRecord::deserialize(slice)
61                    .map(TokenMetadataAccount::CollectionAuthorityRecord)
62            }
63            x if x == Key::MetadataDelegate as u8 => {
64                let slice = account.data.as_slice();
65                metadata_delegate_record::MetadataDelegateRecord::deserialize(slice)
66                    .map(TokenMetadataAccount::MetadataDelegateRecord)
67            }
68            x if x == Key::HolderDelegate as u8 => {
69                let slice = account.data.as_slice();
70                holder_delegate_record::HolderDelegateRecord::deserialize(slice)
71                    .map(TokenMetadataAccount::HolderDelegateRecord)
72            }
73            x if x == Key::EditionV1 as u8 => {
74                let slice = account.data.as_slice();
75                edition::Edition::deserialize(slice).map(TokenMetadataAccount::Edition)
76            }
77            x if x == Key::EditionMarker as u8 => {
78                let slice = account.data.as_slice();
79                edition_marker::EditionMarker::deserialize(slice)
80                    .map(TokenMetadataAccount::EditionMarker)
81            }
82            x if x == Key::EditionMarkerV2 as u8 => {
83                let slice = account.data.as_slice();
84                edition_marker_v2::EditionMarkerV2::deserialize(slice)
85                    .map(TokenMetadataAccount::EditionMarkerV2)
86            }
87            x if x == Key::TokenOwnedEscrow as u8 => {
88                let slice = account.data.as_slice();
89                token_owned_escrow::TokenOwnedEscrow::deserialize(slice)
90                    .map(TokenMetadataAccount::TokenOwnedEscrow)
91            }
92            x if x == Key::MasterEditionV2 as u8 => {
93                let slice = account.data.as_slice();
94                master_edition_v2::MasterEditionV2::deserialize(slice)
95                    .map(TokenMetadataAccount::MasterEditionV2)
96            }
97            x if x == Key::MasterEditionV1 as u8 => {
98                let slice = account.data.as_slice();
99                master_edition_v1::MasterEditionV1::deserialize(slice)
100                    .map(TokenMetadataAccount::MasterEditionV1)
101            }
102            x if x == Key::TokenRecord as u8 => {
103                let slice = account.data.as_slice();
104                token_record::TokenRecord::deserialize(slice).map(TokenMetadataAccount::TokenRecord)
105            }
106            x if x == Key::ReservationListV2 as u8 => {
107                let slice = account.data.as_slice();
108                reservation_list_v2::ReservationListV2::deserialize(slice)
109                    .map(TokenMetadataAccount::ReservationListV2)
110            }
111            x if x == Key::ReservationListV1 as u8 => {
112                let slice = account.data.as_slice();
113                reservation_list_v1::ReservationListV1::deserialize(slice)
114                    .map(TokenMetadataAccount::ReservationListV1)
115            }
116            x if x == Key::UseAuthorityRecord as u8 => {
117                let slice = account.data.as_slice();
118                use_authority_record::UseAuthorityRecord::deserialize(slice)
119                    .map(TokenMetadataAccount::UseAuthorityRecord)
120            }
121            _ => None,
122        }?;
123
124        Some(carbon_core::account::DecodedAccount {
125            lamports: account.lamports,
126            data: data_enum,
127            owner: account.owner,
128            executable: account.executable,
129            rent_epoch: account.rent_epoch,
130        })
131    }
132}