Skip to main content

mpl_token_metadata/state/
collection.rs

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