1use super::*;23pub fn last_collection_idx<T: Config>() -> Result<RmrkCollectionId, DispatchError> {4 Ok(<Pallet<T>>::last_collection_idx())5}67pub fn collection_by_id<T: Config>(8 collection_id: RmrkCollectionId,9) -> Result<Option<RmrkCollectionInfo<T::AccountId>>, DispatchError> {10 let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(11 collection_id,12 misc::CollectionType::Regular,13 ) {14 Ok(c) => c,15 Err(_) => return Ok(None),16 };1718 let nfts_count = collection.total_supply();1920 Ok(Some(RmrkCollectionInfo {21 issuer: collection.owner.clone(),22 metadata: <Pallet<T>>::get_collection_property_decoded(23 collection_id,24 RmrkProperty::Metadata,25 )?,26 max: collection.limits.token_limit,27 symbol: <Pallet<T>>::rebind(&collection.token_prefix)?,28 nfts_count,29 }))30}3132pub fn nft_by_id<T: Config>(33 collection_id: RmrkCollectionId,34 nft_by_id: RmrkNftId,35) -> Result<Option<RmrkInstanceInfo<T::AccountId>>, DispatchError> {36 let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(37 collection_id,38 misc::CollectionType::Regular,39 ) {40 Ok(c) => c,41 Err(_) => return Ok(None),42 };4344 let nft_id = TokenId(nft_by_id);45 if !<Pallet<T>>::nft_exists(collection_id, nft_id) {46 return Ok(None);47 }4849 let owner = match collection.token_owner(nft_id) {50 Some(owner) => match T::CrossTokenAddressMapping::address_to_token(&owner) {51 Some((col, tok)) => {52 let rmrk_collection = <Pallet<T>>::rmrk_collection_id(col)?;5354 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(rmrk_collection, tok.0)55 }56 None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone()),57 },58 None => return Ok(None),59 };6061 Ok(Some(RmrkInstanceInfo {62 owner: owner,63 royalty: <Pallet<T>>::get_nft_property_decoded(64 collection_id,65 nft_id,66 RmrkProperty::RoyaltyInfo,67 )?,68 metadata: <Pallet<T>>::get_nft_property_decoded(69 collection_id,70 nft_id,71 RmrkProperty::Metadata,72 )?,73 equipped: <Pallet<T>>::get_nft_property_decoded(74 collection_id,75 nft_id,76 RmrkProperty::Equipped,77 )?,78 pending: <Pallet<T>>::get_nft_property_decoded(79 collection_id,80 nft_id,81 RmrkProperty::PendingNftAccept,82 )?,83 }))84}8586pub fn account_tokens<T: Config>(87 account_id: T::AccountId,88 collection_id: RmrkCollectionId,89) -> Result<Vec<RmrkNftId>, DispatchError> {90 let cross_account_id = CrossAccountId::from_sub(account_id);9192 let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(93 collection_id,94 misc::CollectionType::Regular,95 ) {96 Ok(c) => c,97 Err(_) => return Ok(Vec::new()),98 };99100 let tokens = collection101 .account_tokens(cross_account_id)102 .into_iter()103 .filter(|token| {104 let is_pending = <Pallet<T>>::get_nft_property_decoded(105 collection_id,106 *token,107 RmrkProperty::PendingNftAccept,108 )109 .unwrap_or(true);110111 !is_pending112 })113 .map(|token| token.0)114 .collect();115116 Ok(tokens)117}118119pub fn nft_children<T: Config>(120 collection_id: RmrkCollectionId,121 nft_id: RmrkNftId,122) -> Result<Vec<RmrkNftChild>, DispatchError> {123 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {124 Ok(id) => id,125 Err(_) => return Ok(Vec::new()),126 };127 let nft_id = TokenId(nft_id);128 if !<Pallet<T>>::nft_exists(collection_id, nft_id) {129 return Ok(Vec::new());130 }131132 Ok(133 pallet_nonfungible::TokenChildren::<T>::iter_prefix((collection_id, nft_id))134 .filter_map(|((child_collection, child_token), _)| {135 let rmrk_child_collection =136 <Pallet<T>>::rmrk_collection_id(child_collection).ok()?;137138 Some(RmrkNftChild {139 collection_id: rmrk_child_collection,140 nft_id: child_token.0,141 })142 })143 .chain(144 <Pallet<T>>::iterate_pending_children(collection_id, nft_id)?.map(145 |(child_collection, child_nft_id)| RmrkNftChild {146 collection_id: child_collection,147 nft_id: child_nft_id,148 },149 ),150 )151 .collect(),152 )153}154155pub fn collection_properties<T: Config>(156 collection_id: RmrkCollectionId,157 filter_keys: Option<Vec<RmrkPropertyKey>>,158) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {159 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {160 Ok(id) => id,161 Err(_) => return Ok(Vec::new()),162 };163 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {164 return Ok(Vec::new());165 }166167 let properties = <Pallet<T>>::filter_user_properties(168 collection_id,169 None,170 filter_keys,171 |key, value| RmrkPropertyInfo { key, value },172 )?;173174 Ok(properties)175}176177pub fn nft_properties<T: Config>(178 collection_id: RmrkCollectionId,179 nft_id: RmrkNftId,180 filter_keys: Option<Vec<RmrkPropertyKey>>,181) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {182 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {183 Ok(id) => id,184 Err(_) => return Ok(Vec::new()),185 };186 let token_id = TokenId(nft_id);187188 if <Pallet<T>>::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {189 return Ok(Vec::new());190 }191192 let properties = <Pallet<T>>::filter_user_properties(193 collection_id,194 Some(token_id),195 filter_keys,196 |key, value| RmrkPropertyInfo { key, value },197 )?;198199 Ok(properties)200}201202pub fn nft_resources<T: Config>(203 collection_id: RmrkCollectionId,204 nft_id: RmrkNftId,205) -> Result<Vec<RmrkResourceInfo>, DispatchError> {206 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {207 Ok(id) => id,208 Err(_) => return Ok(Vec::new()),209 };210 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {211 return Ok(Vec::new());212 }213214 let nft_id = TokenId(nft_id);215 if <Pallet<T>>::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() {216 return Ok(Vec::new());217 }218219 let resources = <pallet_nonfungible::Pallet<T>>::iterate_token_aux_properties(220 collection_id,221 nft_id,222 PropertyScope::Rmrk,223 )224 .filter_map(|(key, value)| {225 if !is_valid_key_prefix(&key, RESOURCE_ID_PREFIX) {226 return None;227 }228229 let resource_info: RmrkResourceInfo = <Pallet<T>>::decode_property(&value).ok()?;230231 Some(resource_info)232 })233 .collect();234235 Ok(resources)236}237238pub fn nft_resource_priority<T: Config>(239 collection_id: RmrkCollectionId,240 nft_id: RmrkNftId,241 resource_id: RmrkResourceId,242) -> Result<Option<u32>, DispatchError> {243 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {244 Ok(id) => id,245 Err(_) => return Ok(None),246 };247 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {248 return Ok(None);249 }250251 let nft_id = TokenId(nft_id);252 if <Pallet<T>>::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() {253 return Ok(None);254 }255256 let priorities: Vec<_> = <Pallet<T>>::get_nft_property_decoded(257 collection_id,258 nft_id,259 RmrkProperty::ResourcePriorities,260 )?;261 Ok(priorities262 .into_iter()263 .enumerate()264 .find(|(_, id)| *id == resource_id)265 .map(|(priority, _): (usize, RmrkResourceId)| priority as u32))266}