aptos_network_sdk/
nft.rs

1/// Implementation of NFT function for aptos 0x3 system library.
2use crate::{
3    Aptos,
4    global::mainnet::{
5        sys_address::X_3,
6        sys_module::{
7            self,
8            token::{
9                collections, create_collection_script, create_token_script, token_store,
10                transfer_script,
11            },
12        },
13    },
14    types::ContractCall,
15    wallet::Wallet,
16};
17use serde_json::{Value, json};
18use std::sync::Arc;
19
20pub struct NFTManager;
21
22impl NFTManager {
23    /// create nft collection
24    pub async fn create_nft_collection(
25        client: Arc<Aptos>,
26        wallet: Arc<Wallet>,
27        name: &str,
28        description: &str,
29        uri: &str,
30        max_amount: Option<u64>,
31    ) -> Result<Value, String> {
32        let contract_call = ContractCall {
33            module_address: X_3.to_string(),
34            module_name: sys_module::token::name.to_string(),
35            function_name: create_collection_script.to_string(),
36            type_arguments: vec![],
37            arguments: vec![
38                json!(name),
39                json!(description),
40                json!(uri),
41                json!(max_amount.unwrap_or(u64::MAX).to_string()),
42                json!(false), // mutable
43            ],
44        };
45        crate::contract::Contract::write(client, wallet, contract_call)
46            .await
47            .map(|result| json!(result))
48    }
49
50    /// create nft
51    pub async fn create_nft(
52        client: Arc<Aptos>,
53        wallet: Arc<Wallet>,
54        collection: &str,
55        name: &str,
56        description: &str,
57        supply: u64,
58        uri: &str,
59        royalty_points_per_million: u64,
60    ) -> Result<Value, String> {
61        let contract_call = ContractCall {
62            module_address: X_3.to_string(),
63            module_name: sys_module::token::name.to_string(),
64            function_name: create_token_script.to_string(),
65            type_arguments: vec![],
66            arguments: vec![
67                json!(collection),
68                json!(name),
69                json!(description),
70                json!(supply.to_string()),
71                json!(supply.to_string()), // max supply
72                json!(uri),
73                json!(wallet.address().map_err(|e| e.to_string())?), // royalty payee
74                json!(royalty_points_per_million.to_string()),
75                json!(0u64.to_string()),     // royalty denominator
76                json!(vec![] as Vec<Value>), // property keys
77                json!(vec![] as Vec<Value>), // property values
78                json!(vec![] as Vec<Value>), // property types
79            ],
80        };
81        crate::contract::Contract::write(client, wallet, contract_call)
82            .await
83            .map(|result| json!(result))
84    }
85
86    /// transfer nft
87    pub async fn transfer_nft(
88        client: Arc<Aptos>,
89        wallet: Arc<Wallet>,
90        token_id: &str,
91        recipient: &str,
92    ) -> Result<Value, String> {
93        let contract_call = ContractCall {
94            module_address: X_3.to_string(),
95            module_name: sys_module::token::name.to_string(),
96            function_name: transfer_script.to_string(),
97            type_arguments: vec![],
98            arguments: vec![
99                json!(recipient),
100                json!(token_id),
101                json!(1u64.to_string()), // amount
102            ],
103        };
104        crate::contract::Contract::write(client, wallet, contract_call)
105            .await
106            .map(|result| json!(result))
107    }
108
109    /// get nft balance
110    pub async fn get_nft_balance(
111        client: Arc<Aptos>,
112        address: &str,
113        token_id: &str,
114    ) -> Result<u64, String> {
115        let resource_type = format!("{}", token_store);
116        if let Some(resource) = client.get_account_resource(address, &resource_type).await? {
117            Ok(resource
118                .data
119                .get("tokens")
120                .and_then(|t| t.as_object())
121                .and_then(|t| t.get(token_id))
122                .and_then(|t| t.get("amount"))
123                .and_then(|a| a.as_str())
124                .and_then(|a| a.parse().ok())
125                .unwrap_or(0))
126        } else {
127            Ok(0)
128        }
129    }
130
131    /// get nft metedata
132    pub async fn get_nft_metedata(
133        client: Arc<Aptos>,
134        creator: &str,
135        collection: &str,
136        name: &str,
137    ) -> Result<Value, String> {
138        let resource_type = format!("{}", collections);
139        if let Some(resource) = client.get_account_resource(creator, &resource_type).await? {
140            Ok(resource
141                .data
142                .get("token_data")
143                .cloned()
144                .unwrap_or(Value::Null))
145        } else {
146            Ok(Value::Null)
147        }
148    }
149}