12345678910111213141516171819use super::*;202122pub fn last_collection_idx<T: Config>() -> Result<RmrkCollectionId, DispatchError> {23 Ok(<Pallet<T>>::last_collection_idx())24}252627pub fn collection_by_id<T: Config>(28 collection_id: RmrkCollectionId,29) -> Result<Option<RmrkCollectionInfo<T::AccountId>>, DispatchError> {30 let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(31 collection_id,32 misc::CollectionType::Regular,33 ) {34 Ok(c) => c,35 Err(_) => return Ok(None),36 };3738 let nfts_count = collection.total_supply();3940 Ok(Some(RmrkCollectionInfo {41 issuer: collection.owner.clone(),42 metadata: <Pallet<T>>::get_collection_property_decoded(43 collection_id,44 RmrkProperty::Metadata,45 )?,46 max: collection.limits.token_limit,47 symbol: <Pallet<T>>::rebind(&collection.token_prefix)?,48 nfts_count,49 }))50}515253pub fn nft_by_id<T: Config>(54 collection_id: RmrkCollectionId,55 nft_by_id: RmrkNftId,56) -> Result<Option<RmrkInstanceInfo<T::AccountId>>, DispatchError> {57 let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(58 collection_id,59 misc::CollectionType::Regular,60 ) {61 Ok(c) => c,62 Err(_) => return Ok(None),63 };6465 let nft_id = TokenId(nft_by_id);66 if !<Pallet<T>>::nft_exists(collection_id, nft_id) {67 return Ok(None);68 }6970 let owner = match collection.token_owner(nft_id) {71 Ok(owner) => match T::CrossTokenAddressMapping::address_to_token(&owner) {72 Some((col, tok)) => {73 let rmrk_collection = <Pallet<T>>::rmrk_collection_id(col)?;7475 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(rmrk_collection, tok.0)76 }77 None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone()),78 },79 _ => return Ok(None),80 };8182 Ok(Some(RmrkInstanceInfo {83 owner: owner,84 royalty: <Pallet<T>>::get_nft_property_decoded(85 collection_id,86 nft_id,87 RmrkProperty::RoyaltyInfo,88 )?,89 metadata: <Pallet<T>>::get_nft_property_decoded(90 collection_id,91 nft_id,92 RmrkProperty::Metadata,93 )?,94 equipped: <Pallet<T>>::get_nft_property_decoded(95 collection_id,96 nft_id,97 RmrkProperty::Equipped,98 )?,99 pending: <Pallet<T>>::get_nft_property_decoded(100 collection_id,101 nft_id,102 RmrkProperty::PendingNftAccept,103 )?,104 }))105}106107108pub fn account_tokens<T: Config>(109 account_id: T::AccountId,110 collection_id: RmrkCollectionId,111) -> Result<Vec<RmrkNftId>, DispatchError> {112 let cross_account_id = CrossAccountId::from_sub(account_id);113114 let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(115 collection_id,116 misc::CollectionType::Regular,117 ) {118 Ok(c) => c,119 Err(_) => return Ok(Vec::new()),120 };121122 let tokens = collection123 .account_tokens(cross_account_id)124 .into_iter()125 .filter(|token| {126 let is_pending = <Pallet<T>>::get_nft_property_decoded(127 collection_id,128 *token,129 RmrkProperty::PendingNftAccept,130 )131 .unwrap_or(true);132133 !is_pending134 })135 .map(|token| token.0)136 .collect();137138 Ok(tokens)139}140141142pub fn nft_children<T: Config>(143 collection_id: RmrkCollectionId,144 nft_id: RmrkNftId,145) -> Result<Vec<RmrkNftChild>, DispatchError> {146 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {147 Ok(id) => id,148 Err(_) => return Ok(Vec::new()),149 };150 let nft_id = TokenId(nft_id);151 if !<Pallet<T>>::nft_exists(collection_id, nft_id) {152 return Ok(Vec::new());153 }154155 Ok(156 pallet_nonfungible::TokenChildren::<T>::iter_prefix((collection_id, nft_id))157 .filter_map(|((child_collection, child_token), _)| {158 let rmrk_child_collection =159 <Pallet<T>>::rmrk_collection_id(child_collection).ok()?;160161 Some(RmrkNftChild {162 collection_id: rmrk_child_collection,163 nft_id: child_token.0,164 })165 })166 .chain(167 <Pallet<T>>::iterate_pending_children(collection_id, nft_id)?.map(168 |(child_collection, child_nft_id)| RmrkNftChild {169 collection_id: child_collection,170 nft_id: child_nft_id,171 },172 ),173 )174 .collect(),175 )176}177178179pub fn collection_properties<T: Config>(180 collection_id: RmrkCollectionId,181 filter_keys: Option<Vec<RmrkPropertyKey>>,182) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {183 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {184 Ok(id) => id,185 Err(_) => return Ok(Vec::new()),186 };187 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {188 return Ok(Vec::new());189 }190191 let properties = <Pallet<T>>::filter_user_properties(192 collection_id,193 None,194 filter_keys,195 |key, value| RmrkPropertyInfo { key, value },196 )?;197198 Ok(properties)199}200201202pub fn nft_properties<T: Config>(203 collection_id: RmrkCollectionId,204 nft_id: RmrkNftId,205 filter_keys: Option<Vec<RmrkPropertyKey>>,206) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {207 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {208 Ok(id) => id,209 Err(_) => return Ok(Vec::new()),210 };211 let token_id = TokenId(nft_id);212213 if <Pallet<T>>::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {214 return Ok(Vec::new());215 }216217 let properties = <Pallet<T>>::filter_user_properties(218 collection_id,219 Some(token_id),220 filter_keys,221 |key, value| RmrkPropertyInfo { key, value },222 )?;223224 Ok(properties)225}226227228pub fn nft_resources<T: Config>(229 collection_id: RmrkCollectionId,230 nft_id: RmrkNftId,231) -> Result<Vec<RmrkResourceInfo>, DispatchError> {232 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {233 Ok(id) => id,234 Err(_) => return Ok(Vec::new()),235 };236 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {237 return Ok(Vec::new());238 }239240 let nft_id = TokenId(nft_id);241 if <Pallet<T>>::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() {242 return Ok(Vec::new());243 }244245 let resources = <pallet_nonfungible::Pallet<T>>::iterate_token_aux_properties(246 collection_id,247 nft_id,248 PropertyScope::Rmrk,249 )250 .filter_map(|(key, value)| {251 if !is_valid_key_prefix(&key, RESOURCE_ID_PREFIX) {252 return None;253 }254255 let resource_info: RmrkResourceInfo = <Pallet<T>>::decode_property_value(&value).ok()?;256257 Some(resource_info)258 })259 .collect();260261 Ok(resources)262}263264265pub fn nft_resource_priority<T: Config>(266 collection_id: RmrkCollectionId,267 nft_id: RmrkNftId,268 resource_id: RmrkResourceId,269) -> Result<Option<u32>, DispatchError> {270 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {271 Ok(id) => id,272 Err(_) => return Ok(None),273 };274 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {275 return Ok(None);276 }277278 let nft_id = TokenId(nft_id);279 if <Pallet<T>>::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() {280 return Ok(None);281 }282283 let priorities: Vec<_> = <Pallet<T>>::get_nft_property_decoded(284 collection_id,285 nft_id,286 RmrkProperty::ResourcePriorities,287 )?;288 Ok(priorities289 .into_iter()290 .enumerate()291 .find(|(_, id)| *id == resource_id)292 .map(|(priority, _): (usize, RmrkResourceId)| priority as u32))293}