Skip to main content

metaboss_lib/
convert.rs

1use anyhow::{anyhow, Result};
2use mpl_token_metadata::types::{Creator, DataV2};
3use solana_sdk::pubkey::Pubkey;
4use std::str::FromStr;
5
6use crate::data::{NftCreator, NftData};
7
8pub fn convert_local_to_remote_data(local: NftData) -> Result<DataV2> {
9    let creators = local
10        .creators
11        .ok_or_else(|| anyhow!("No creators specified in json file!"))?
12        .iter()
13        .map(convert_creator)
14        .collect::<Result<Vec<Creator>>>()?;
15
16    let data = DataV2 {
17        name: local.name,
18        symbol: local.symbol,
19        uri: local.uri,
20        seller_fee_basis_points: local.seller_fee_basis_points,
21        creators: Some(creators),
22        collection: None,
23        uses: None,
24    };
25    Ok(data)
26}
27
28fn convert_creator(c: &NftCreator) -> Result<Creator> {
29    Ok(Creator {
30        address: Pubkey::from_str(&c.address)?,
31        verified: c.verified,
32        share: c.share,
33    })
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    fn make_creator(address: &str, verified: bool, share: u8) -> NftCreator {
41        NftCreator {
42            address: address.to_string(),
43            verified,
44            share,
45        }
46    }
47
48    fn make_nft_data(creators: Option<Vec<NftCreator>>) -> NftData {
49        NftData {
50            name: "Test NFT".to_string(),
51            symbol: "TNFT".to_string(),
52            uri: "https://example.com/nft.json".to_string(),
53            seller_fee_basis_points: 500,
54            creators,
55        }
56    }
57
58    #[test]
59    fn test_convert_local_to_remote_data_valid() {
60        let pubkey_str = "11111111111111111111111111111111";
61        let creators = vec![make_creator(pubkey_str, true, 100)];
62        let nft_data = make_nft_data(Some(creators));
63
64        let result = convert_local_to_remote_data(nft_data).unwrap();
65
66        assert_eq!(result.name, "Test NFT");
67        assert_eq!(result.symbol, "TNFT");
68        assert_eq!(result.uri, "https://example.com/nft.json");
69        assert_eq!(result.seller_fee_basis_points, 500);
70        assert!(result.collection.is_none());
71        assert!(result.uses.is_none());
72
73        let creators = result.creators.unwrap();
74        assert_eq!(creators.len(), 1);
75        assert_eq!(creators[0].address, Pubkey::from_str(pubkey_str).unwrap());
76        assert!(creators[0].verified);
77        assert_eq!(creators[0].share, 100);
78    }
79
80    #[test]
81    fn test_convert_local_to_remote_data_none_creators() {
82        let nft_data = make_nft_data(None);
83        let result = convert_local_to_remote_data(nft_data);
84        assert!(result.is_err());
85    }
86
87    #[test]
88    fn test_convert_local_to_remote_data_invalid_pubkey() {
89        let creators = vec![make_creator("not-a-pubkey", false, 100)];
90        let nft_data = make_nft_data(Some(creators));
91        let result = convert_local_to_remote_data(nft_data);
92        assert!(result.is_err());
93    }
94
95    #[test]
96    fn test_convert_local_to_remote_data_multiple_creators() {
97        let pubkey_str = "11111111111111111111111111111111";
98        let creators = vec![
99            make_creator(pubkey_str, true, 50),
100            make_creator(pubkey_str, false, 30),
101            make_creator(pubkey_str, true, 20),
102        ];
103        let nft_data = make_nft_data(Some(creators));
104
105        let result = convert_local_to_remote_data(nft_data).unwrap();
106        let creators = result.creators.unwrap();
107
108        assert_eq!(creators.len(), 3);
109
110        assert!(creators[0].verified);
111        assert_eq!(creators[0].share, 50);
112
113        assert!(!creators[1].verified);
114        assert_eq!(creators[1].share, 30);
115
116        assert!(creators[2].verified);
117        assert_eq!(creators[2].share, 20);
118    }
119}