mpl_token_metadata/state/
uses.rs

1use super::*;
2
3pub const USE_AUTHORITY_RECORD_SIZE: usize = 18; //8 byte padding
4
5#[repr(C)]
6#[cfg_attr(feature = "serde-feature", derive(Serialize, Deserialize))]
7#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone, FromPrimitive)]
8pub enum UseMethod {
9    Burn,
10    Multiple,
11    Single,
12}
13
14#[repr(C)]
15#[cfg_attr(feature = "serde-feature", derive(Serialize, Deserialize))]
16#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone)]
17pub struct Uses {
18    // 17 bytes + Option byte
19    pub use_method: UseMethod, //1
20    pub remaining: u64,        //8
21    pub total: u64,            //8
22}
23
24#[repr(C)]
25#[cfg_attr(feature = "serde-feature", derive(Serialize, Deserialize))]
26#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone, ShankAccount)]
27pub struct UseAuthorityRecord {
28    pub key: Key,          //1
29    pub allowed_uses: u64, //8
30    pub bump: u8,
31}
32
33impl Default for UseAuthorityRecord {
34    fn default() -> Self {
35        UseAuthorityRecord {
36            key: Key::UseAuthorityRecord,
37            allowed_uses: 0,
38            bump: 255,
39        }
40    }
41}
42
43impl TokenMetadataAccount for UseAuthorityRecord {
44    fn key() -> Key {
45        Key::UseAuthorityRecord
46    }
47
48    fn size() -> usize {
49        USE_AUTHORITY_RECORD_SIZE
50    }
51}
52
53impl UseAuthorityRecord {
54    pub fn from_bytes(b: &[u8]) -> Result<UseAuthorityRecord, ProgramError> {
55        let ua: UseAuthorityRecord =
56            try_from_slice_checked(b, Key::UseAuthorityRecord, USE_AUTHORITY_RECORD_SIZE)?;
57        Ok(ua)
58    }
59
60    pub fn bump_empty(&self) -> bool {
61        self.bump == 0 && self.key == Key::UseAuthorityRecord
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use borsh::BorshSerialize;
68    use solana_program::account_info::AccountInfo;
69    use solana_sdk::{signature::Keypair, signer::Signer};
70
71    use crate::{
72        error::MetadataError,
73        state::{CollectionAuthorityRecord, Key, TokenMetadataAccount, UseAuthorityRecord},
74        ID,
75    };
76
77    #[test]
78    fn successfully_deserialize() {
79        let expected_data = UseAuthorityRecord::default();
80
81        let mut buf = Vec::new();
82        expected_data.serialize(&mut buf).unwrap();
83        UseAuthorityRecord::pad_length(&mut buf).unwrap();
84
85        let pubkey = Keypair::new().pubkey();
86        let owner = &ID;
87        let mut lamports = 1_000_000_000;
88        let mut data = buf.clone();
89
90        let account_info = AccountInfo::new(
91            &pubkey,
92            false,
93            true,
94            &mut lamports,
95            &mut data,
96            owner,
97            false,
98            1_000_000_000,
99        );
100
101        let data = UseAuthorityRecord::from_account_info(&account_info).unwrap();
102        assert_eq!(data.key, Key::UseAuthorityRecord);
103        assert_eq!(data, expected_data);
104    }
105
106    #[test]
107    fn deserializing_wrong_account_type_fails() {
108        let wrong_type = CollectionAuthorityRecord::default();
109
110        let mut buf = Vec::new();
111        wrong_type.serialize(&mut buf).unwrap();
112
113        let pubkey = Keypair::new().pubkey();
114        let owner = &ID;
115        let mut lamports = 1_000_000_000;
116        let mut data = buf.clone();
117
118        let account_info = AccountInfo::new(
119            &pubkey,
120            false,
121            true,
122            &mut lamports,
123            &mut data,
124            owner,
125            false,
126            1_000_000_000,
127        );
128
129        let error = UseAuthorityRecord::from_account_info(&account_info).unwrap_err();
130        assert_eq!(error, MetadataError::DataTypeMismatch.into());
131    }
132}