Skip to main content

mpl_token_metadata/
utils.rs

1use borsh::BorshDeserialize;
2
3use crate::{
4    errors::MplTokenMetadataError,
5    types::{Key, TokenStandard},
6};
7
8/// The offset of the token standard byte in the master edition
9/// from the end of the account data.
10const TOKEN_STANDARD_OFFSET: usize = 1;
11
12/// Removes all null bytes from a string.
13pub fn clean(value: String) -> String {
14    value.replace('\0', "")
15}
16
17/// Checks that the `master_edition` is Programmable NFT master edition.
18pub fn assert_edition_is_programmable(edition_data: &[u8]) -> Result<(), MplTokenMetadataError> {
19    if edition_data.len() > TOKEN_STANDARD_OFFSET {
20        // the first byte is the account key
21        let key = Key::deserialize(&mut &edition_data[0..1])
22            .map_err(|_error| MplTokenMetadataError::InvalidEditionKey)?;
23
24        return match key {
25            Key::MasterEditionV1 | Key::MasterEditionV2 => {
26                // the last byte is the token standard
27                let standard = TokenStandard::deserialize(
28                    &mut &edition_data[edition_data.len() - TOKEN_STANDARD_OFFSET..],
29                )
30                .map_err(|_error| MplTokenMetadataError::InvalidTokenStandard)?;
31
32                return match standard {
33                    TokenStandard::ProgrammableNonFungible
34                    | TokenStandard::ProgrammableNonFungibleEdition => Ok(()),
35                    _ => Err(MplTokenMetadataError::InvalidTokenStandard),
36                };
37            }
38            _ => Err(MplTokenMetadataError::InvalidEditionKey),
39        };
40    }
41
42    Err(MplTokenMetadataError::InvalidMasterEditionAccountLength)
43}