frc53_nft/
types.rs

1//! Interfaces and types for the frc53 NFT standard
2use cid::Cid;
3use fvm_actor_utils::receiver::RecipientData;
4use fvm_ipld_bitfield::BitField;
5use fvm_ipld_encoding::tuple::*;
6use fvm_ipld_encoding::RawBytes;
7use fvm_shared::address::Address;
8use fvm_shared::ActorID;
9
10#[cfg(doc)]
11use super::state::Cursor;
12
13pub type TokenID = u64;
14
15/// Multiple token IDs are represented as a BitField encoded with RLE+ the index of each set bit
16/// corresponds to a TokenID.
17pub type TokenSet = BitField;
18
19/// Multiple actor IDs are represented as a BitField encoded with RLE+ the index of each set bit
20/// corresponds to a ActorID.
21pub type ActorIDSet = BitField;
22
23/// A trait to be implemented by FRC-0053 compliant actors.
24pub trait FRC53NFT {
25    /// A descriptive name for the collection of NFTs in this actor.
26    fn name(&self) -> String;
27
28    /// An abbreviated name for NFTs in this contract.
29    fn symbol(&self) -> String;
30
31    /// Gets a link to associated metadata for a given NFT.
32    fn metadata(&self, params: TokenID) -> Cid;
33
34    /// Gets the total number of NFTs in this actor.
35    fn total_supply(&self) -> u64;
36
37    /// Burns a given NFT, removing it from the total supply and preventing new NFTs from being
38    /// minted with the same ID.
39    fn burn(&self, token_id: TokenID);
40
41    /// Gets a list of all the tokens in the collection.
42    // FIXME: make this paginated
43    fn list_tokens(&self) -> Vec<TokenID>;
44
45    /// Gets the number of tokens held by a particular address (if it exists).
46    fn balance_of(&self, owner: Address) -> u64;
47
48    /// Returns the owner of the NFT specified by `token_id`.
49    fn owner_of(&self, token_id: TokenID) -> ActorID;
50
51    /// Transfers specific NFTs from the caller to another account.
52    fn transfer(&self, params: TransferParams);
53
54    /// Transfers specific NFTs between the [`from`][`TransferFromParams::from`] and
55    /// [`to`][`TransferFromParams::to`] addresses.
56    fn transfer_from(&self, params: TransferFromParams);
57
58    /// Change or reaffirm the approved address for a set of NFTs, setting to zero means there is no
59    /// approved address.
60    fn approve(&self, params: ApproveParams);
61
62    /// Set approval for all, allowing an operator to control all of the caller's tokens (including
63    /// future tokens) until approval is revoked.
64    fn set_approval_for_all(&self, params: ApproveForAllParams);
65
66    /// Get the approved address for a single NFT.
67    fn get_approved(&self, params: TokenID) -> ActorID;
68
69    /// Query if the address is the approved operator for another address.
70    fn is_approved_for_all(&self, params: IsApprovedForAllParams) -> bool;
71}
72
73/// Return value after a successful mint.
74///
75/// The mint method is not standardised, so this is merely a useful library-level type, and
76/// recommendation for token implementations.
77#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
78pub struct MintReturn {
79    /// The new balance of the owner address.
80    pub balance: u64,
81    /// The new total supply.
82    pub supply: u64,
83    /// List of the tokens that were minted successfully (some may have been burned during hook
84    /// execution).
85    pub token_ids: Vec<TokenID>,
86    /// (Optional) data returned from the receiver hook.
87    pub recipient_data: RawBytes,
88}
89
90/// Intermediate data used by mint_return to construct the return data.
91#[derive(Clone, Debug)]
92pub struct MintIntermediate {
93    /// Receiving address used for querying balance.
94    pub to: ActorID,
95    /// List of the newly minted tokens.
96    pub token_ids: Vec<TokenID>,
97    /// (Optional) data returned from the receiver hook.
98    pub recipient_data: RawBytes,
99}
100
101impl RecipientData for MintIntermediate {
102    fn set_recipient_data(&mut self, data: RawBytes) {
103        self.recipient_data = data;
104    }
105}
106
107/// Intermediate data used by [`NFT::transfer_return`][`super::NFT::transfer_return`] to construct
108/// the return data.
109#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
110pub struct TransferIntermediate {
111    pub token_ids: Vec<TokenID>,
112    pub from: ActorID,
113    pub to: ActorID,
114    /// (Optional) data returned from the receiver hook.
115    pub recipient_data: RawBytes,
116}
117
118impl RecipientData for TransferIntermediate {
119    fn set_recipient_data(&mut self, data: RawBytes) {
120        self.recipient_data = data;
121    }
122}
123
124#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
125pub struct TransferParams {
126    pub to: Address,
127    pub token_ids: Vec<TokenID>,
128    pub operator_data: RawBytes,
129}
130
131#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
132pub struct TransferReturn {
133    pub from_balance: u64,
134    pub to_balance: u64,
135    pub token_ids: Vec<TokenID>,
136}
137
138#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
139pub struct TransferFromParams {
140    pub from: Address,
141    pub to: Address,
142    pub token_ids: Vec<TokenID>,
143    pub operator_data: RawBytes,
144}
145
146#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
147pub struct BurnFromParams {
148    pub from: Address,
149    pub token_ids: Vec<TokenID>,
150}
151
152#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
153pub struct ApproveParams {
154    pub operator: Address,
155    pub token_ids: Vec<TokenID>,
156}
157
158#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
159pub struct ApproveForAllParams {
160    pub operator: Address,
161}
162
163#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
164pub struct IsApprovedForAllParams {
165    pub owner: Address,
166    pub operator: Address,
167}
168
169#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
170pub struct RevokeParams {
171    pub operator: Address,
172    pub token_ids: Vec<TokenID>,
173}
174
175#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
176pub struct RevokeForAllParams {
177    pub operator: Address,
178}
179
180#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
181pub struct ListTokensParams {
182    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
183    pub cursor: RawBytes,
184    pub limit: u64,
185}
186
187#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
188pub struct ListTokensReturn {
189    pub tokens: BitField,
190    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
191    pub next_cursor: Option<RawBytes>,
192}
193
194#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
195pub struct ListOwnedTokensParams {
196    pub owner: Address,
197    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
198    pub cursor: RawBytes,
199    pub limit: u64,
200}
201
202#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
203pub struct ListOwnedTokensReturn {
204    pub tokens: TokenSet,
205    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
206    pub next_cursor: Option<RawBytes>,
207}
208
209#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
210pub struct ListTokenOperatorsParams {
211    pub token_id: TokenID,
212    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
213    pub cursor: RawBytes,
214    pub limit: u64,
215}
216
217#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
218pub struct ListTokenOperatorsReturn {
219    pub operators: ActorIDSet,
220    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
221    pub next_cursor: Option<RawBytes>,
222}
223
224#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
225pub struct ListOperatorTokensParams {
226    pub operator: Address,
227    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
228    pub cursor: RawBytes,
229    pub limit: u64,
230}
231
232#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
233pub struct ListOperatorTokensReturn {
234    pub tokens: TokenSet,
235    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
236    pub next_cursor: Option<RawBytes>,
237}
238
239#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
240pub struct ListAccountOperatorsParams {
241    pub owner: Address,
242    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
243    pub cursor: RawBytes,
244    pub limit: u64,
245}
246
247#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
248pub struct ListAccountOperatorsReturn {
249    pub operators: ActorIDSet,
250    /// Opaque serialisation of [`Cursor`], with empty cursor meaning start of list.
251    pub next_cursor: Option<RawBytes>,
252}