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 Some(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 None => 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}106107108109pub fn account_tokens<T: Config>(110 account_id: T::AccountId,111 collection_id: RmrkCollectionId,112) -> Result<Vec<RmrkNftId>, DispatchError> {113 let cross_account_id = CrossAccountId::from_sub(account_id);114115 let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(116 collection_id,117 misc::CollectionType::Regular,118 ) {119 Ok(c) => c,120 Err(_) => return Ok(Vec::new()),121 };122123 let tokens = collection124 .account_tokens(cross_account_id)125 .into_iter()126 .filter(|token| {127 let is_pending = <Pallet<T>>::get_nft_property_decoded(128 collection_id,129 *token,130 RmrkProperty::PendingNftAccept,131 )132 .unwrap_or(true);133134 !is_pending135 })136 .map(|token| token.0)137 .collect();138139 Ok(tokens)140}141142143pub fn nft_children<T: Config>(144 collection_id: RmrkCollectionId,145 nft_id: RmrkNftId,146) -> Result<Vec<RmrkNftChild>, DispatchError> {147 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {148 Ok(id) => id,149 Err(_) => return Ok(Vec::new()),150 };151 let nft_id = TokenId(nft_id);152 if !<Pallet<T>>::nft_exists(collection_id, nft_id) {153 return Ok(Vec::new());154 }155156 Ok(157 pallet_nonfungible::TokenChildren::<T>::iter_prefix((collection_id, nft_id))158 .filter_map(|((child_collection, child_token), _)| {159 let rmrk_child_collection =160 <Pallet<T>>::rmrk_collection_id(child_collection).ok()?;161162 Some(RmrkNftChild {163 collection_id: rmrk_child_collection,164 nft_id: child_token.0,165 })166 })167 .chain(168 <Pallet<T>>::iterate_pending_children(collection_id, nft_id)?.map(169 |(child_collection, child_nft_id)| RmrkNftChild {170 collection_id: child_collection,171 nft_id: child_nft_id,172 },173 ),174 )175 .collect(),176 )177}178179180pub fn collection_properties<T: Config>(181 collection_id: RmrkCollectionId,182 filter_keys: Option<Vec<RmrkPropertyKey>>,183) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {184 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {185 Ok(id) => id,186 Err(_) => return Ok(Vec::new()),187 };188 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {189 return Ok(Vec::new());190 }191192 let properties = <Pallet<T>>::filter_user_properties(193 collection_id,194 None,195 filter_keys,196 |key, value| RmrkPropertyInfo { key, value },197 )?;198199 Ok(properties)200}201202203pub fn nft_properties<T: Config>(204 collection_id: RmrkCollectionId,205 nft_id: RmrkNftId,206 filter_keys: Option<Vec<RmrkPropertyKey>>,207) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {208 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {209 Ok(id) => id,210 Err(_) => return Ok(Vec::new()),211 };212 let token_id = TokenId(nft_id);213214 if <Pallet<T>>::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {215 return Ok(Vec::new());216 }217218 let properties = <Pallet<T>>::filter_user_properties(219 collection_id,220 Some(token_id),221 filter_keys,222 |key, value| RmrkPropertyInfo { key, value },223 )?;224225 Ok(properties)226}227228229pub fn nft_resources<T: Config>(230 collection_id: RmrkCollectionId,231 nft_id: RmrkNftId,232) -> Result<Vec<RmrkResourceInfo>, DispatchError> {233 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {234 Ok(id) => id,235 Err(_) => return Ok(Vec::new()),236 };237 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {238 return Ok(Vec::new());239 }240241 let nft_id = TokenId(nft_id);242 if <Pallet<T>>::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() {243 return Ok(Vec::new());244 }245246 let resources = <pallet_nonfungible::Pallet<T>>::iterate_token_aux_properties(247 collection_id,248 nft_id,249 PropertyScope::Rmrk,250 )251 .filter_map(|(key, value)| {252 if !is_valid_key_prefix(&key, RESOURCE_ID_PREFIX) {253 return None;254 }255256 let resource_info: RmrkResourceInfo = <Pallet<T>>::decode_property_value(&value).ok()?;257258 Some(resource_info)259 })260 .collect();261262 Ok(resources)263}264265266pub fn nft_resource_priority<T: Config>(267 collection_id: RmrkCollectionId,268 nft_id: RmrkNftId,269 resource_id: RmrkResourceId,270) -> Result<Option<u32>, DispatchError> {271 let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {272 Ok(id) => id,273 Err(_) => return Ok(None),274 };275 if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {276 return Ok(None);277 }278279 let nft_id = TokenId(nft_id);280 if <Pallet<T>>::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() {281 return Ok(None);282 }283284 let priorities: Vec<_> = <Pallet<T>>::get_nft_property_decoded(285 collection_id,286 nft_id,287 RmrkProperty::ResourcePriorities,288 )?;289 Ok(priorities290 .into_iter()291 .enumerate()292 .find(|(_, id)| *id == resource_id)293 .map(|(priority, _): (usize, RmrkResourceId)| priority as u32))294}