git.delta.rocks / unique-network / refs/commits / a66e7a4819dc

difftreelog

Add properties RPC

Daniel Shiposha2022-05-05parent: #a7c09a3.patch.diff
in: master

8 files changed

modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
20use jsonrpc_core::{Error as RpcError, ErrorCode, Result};20use jsonrpc_core::{Error as RpcError, ErrorCode, Result};
21use jsonrpc_derive::rpc;21use jsonrpc_derive::rpc;
22use up_data_structs::{RpcCollection, CollectionId, CollectionStats, CollectionLimits, TokenId};22use up_data_structs::{
23 RpcCollection, CollectionId, CollectionStats, CollectionLimits, TokenId, Property, PropertyKey,
24 PropertyKeyPermission,
25};
23use sp_api::{BlockId, BlockT, ProvideRuntimeApi, ApiExt};26use sp_api::{BlockId, BlockT, ProvideRuntimeApi, ApiExt};
24use sp_blockchain::HeaderBackend;27use sp_blockchain::HeaderBackend;
76 at: Option<BlockHash>,79 at: Option<BlockHash>,
77 ) -> Result<Vec<u8>>;80 ) -> Result<Vec<u8>>;
81
82 #[rpc(name = "unique_collectionProperties")]
83 fn collection_properties(
84 &self,
85 collection: CollectionId,
86 keys: Vec<String>,
87 at: Option<BlockHash>,
88 ) -> Result<Vec<Property>>;
89
90 #[rpc(name = "unique_tokenProperties")]
91 fn token_properties(
92 &self,
93 collection: CollectionId,
94 token_id: TokenId,
95 properties: Vec<String>,
96 at: Option<BlockHash>,
97 ) -> Result<Vec<Property>>;
98
99 #[rpc(name = "unique_propertyPermissions")]
100 fn property_permissions(
101 &self,
102 collection: CollectionId,
103 keys: Vec<String>,
104 at: Option<BlockHash>,
105 ) -> Result<Vec<PropertyKeyPermission>>;
78106
79 #[rpc(name = "unique_totalSupply")]107 #[rpc(name = "unique_totalSupply")]
80 fn total_supply(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<u32>;108 fn total_supply(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<u32>;
178macro_rules! pass_method {206macro_rules! pass_method {
179 (207 (
180 $method_name:ident($($name:ident: $ty:ty),* $(,)?) -> $result:ty $(=> $mapper:expr)?208 $method_name:ident(
209 $($(#[map(|$map_arg:ident| $map:expr)])? $name:ident: $ty:ty),* $(,)?
210 ) -> $result:ty $(=> $mapper:expr)?
181 $(; changed_in $ver:expr, $changed_method_name:ident ($($changed_name:expr), * $(,)?) => $fixer:expr)*211 $(; changed_in $ver:expr, $changed_method_name:ident ($($changed_name:expr), * $(,)?) => $fixer:expr)*
182 ) => {212 ) => {
205 let result = $(if _api_version < $ver {235 let result = $(if _api_version < $ver {
206 api.$changed_method_name(&at, $($changed_name),*).map(|r| r.map($fixer))236 api.$changed_method_name(&at, $($changed_name),*).map(|r| r.map($fixer))
207 } else)*237 } else)*
208 { api.$method_name(&at, $($name),*) };238 { api.$method_name(&at, $($((|$map_arg: $ty| $map))? ($name)),*) };
209239
210 let result = result.map_err(|e| RpcError {240 let result = result.map_err(|e| RpcError {
211 code: ErrorCode::ServerError(Error::RuntimeError.into()),241 code: ErrorCode::ServerError(Error::RuntimeError.into()),
242 pass_method!(const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);272 pass_method!(const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);
243 pass_method!(variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);273 pass_method!(variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);
274
275 pass_method!(collection_properties(
276 collection: CollectionId,
277
278 #[map(|keys| string_keys_to_bytes_keys(keys))]
279 keys: Vec<String>
280 ) -> Vec<Property>);
281
282 pass_method!(token_properties(
283 collection: CollectionId,
284 token_id: TokenId,
285
286 #[map(|keys| string_keys_to_bytes_keys(keys))]
287 properties: Vec<String>
288 ) -> Vec<Property>);
289
290 pass_method!(property_permissions(
291 collection: CollectionId,
292
293 #[map(|keys| string_keys_to_bytes_keys(keys))]
294 keys: Vec<String>
295 ) -> Vec<PropertyKeyPermission>);
244296
245 pass_method!(total_supply(collection: CollectionId) -> u32);297 pass_method!(total_supply(collection: CollectionId) -> u32);
246 pass_method!(account_balance(collection: CollectionId, account: CrossAccountId) -> u32);298 pass_method!(account_balance(collection: CollectionId, account: CrossAccountId) -> u32);
257 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>);309 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>);
258}310}
311
312fn string_keys_to_bytes_keys(keys: Vec<String>) -> Vec<Vec<u8>> {
313 keys.into_iter().map(|key| key.into_bytes()).collect()
314}
259315
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
388388
389 /// Collection properties389 /// Collection properties
390 #[pallet::storage]390 #[pallet::storage]
391 #[pallet::getter(fn collection_properties)]
391 pub type CollectionProperties<T> = StorageMap<392 pub type CollectionProperties<T> = StorageMap<
392 Hasher = Blake2_128Concat,393 Hasher = Blake2_128Concat,
393 Key = CollectionId,394 Key = CollectionId,
397 >;398 >;
398399
399 #[pallet::storage]400 #[pallet::storage]
400 #[pallet::getter(fn property_permission)]401 #[pallet::getter(fn property_permissions)]
401 pub type CollectionPropertyPermissions<T> = StorageMap<402 pub type CollectionPropertyPermissions<T> = StorageMap<
402 Hasher = Blake2_128Concat,403 Hasher = Blake2_128Concat,
403 Key = CollectionId,404 Key = CollectionId,
656 CollectionProperties::<T>::insert(657 CollectionProperties::<T>::insert(
657 id,658 id,
658 Properties::from_collection_props_vec(data.properties)659 Properties::from_collection_props_vec(data.properties)
659 .map_err(|e| -> Error::<T> {660 .map_err(|e| -> Error<T> { e.into() })?,
660 e.into()
661 })?,
662 );661 );
667 .map(|property| (property.key, property.permission))666 .map(|property| (property.key, property.permission))
668 .collect::<BTreeMap<_, _>>()667 .collect::<BTreeMap<_, _>>()
669 .try_into()668 .try_into()
670 .map_err(|_| -> Error::<T> {669 .map_err(|_| -> Error<T> { PropertiesError::PropertyLimitReached.into() })?;
671 PropertiesError::PropertyLimitReached.into()
672 })?;
673670
754 CollectionProperties::<T>::try_mutate(collection.id, |properties| {751 CollectionProperties::<T>::try_mutate(collection.id, |properties| {
755 properties.try_set_property(property.clone())752 properties.try_set_property(property.clone())
756 })753 })
757 .map_err(|e| -> Error::<T> {754 .map_err(|e| -> Error<T> { e.into() })?;
758 e.into()
759 })?;
760755
823 let property_permission = property_permission.clone();821 let property_permission = property_permission.clone();
824 permissions.try_insert(property_permission.key, property_permission.permission)822 permissions.try_insert(property_permission.key, property_permission.permission)
825 })823 })
826 .map_err(|_| -> Error::<T> {824 .map_err(|_| -> Error<T> { PropertiesError::PropertyLimitReached.into() })?;
827 PropertiesError::PropertyLimitReached.into()
828 })?;
829825
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth

no syntactic changes

modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
96 >;96 >;
9797
98 #[pallet::storage]98 #[pallet::storage]
99 #[pallet::getter(fn token_properties)]
99 pub type TokenProperties<T: Config> = StorageNMap<100 pub type TokenProperties<T: Config> = StorageNMap<
100 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),101 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
101 Value = up_data_structs::Properties,102 Value = up_data_structs::Properties,
265266
266 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {267 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {
267 properties.try_set_property(property.clone())268 properties.try_set_property(property.clone())
268 }).map_err(|e| -> CommonError::<T> {269 })
269 e.into()270 .map_err(|e| -> CommonError<T> { e.into() })?;
270 })?;
271271
318 token_id: TokenId,318 token_id: TokenId,
319 property_key: &PropertyKey,319 property_key: &PropertyKey,
320 ) -> DispatchResult {320 ) -> DispatchResult {
321 let permission = <PalletCommon<T>>::property_permission(collection.id)321 let permission = <PalletCommon<T>>::property_permissions(collection.id)
322 .get(property_key)322 .get(property_key)
323 .map(|p| p.clone())323 .map(|p| p.clone())
324 .unwrap_or(PropertyPermission::None);324 .unwrap_or(PropertyPermission::None);
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
634pub type PropertyValue = BoundedVec<u8, ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;634pub type PropertyValue = BoundedVec<u8, ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;
635635
636#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]636#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]
637#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
637pub enum PropertyPermission {638pub enum PropertyPermission {
638 None,639 None,
639 AdminConst,640 AdminConst,
644}645}
645646
646#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, MaxEncodedLen)]647#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, MaxEncodedLen)]
648#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
647pub struct Property {649pub struct Property {
650 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
648 pub key: PropertyKey,651 pub key: PropertyKey,
652
653 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
649 pub value: PropertyValue,654 pub value: PropertyValue,
650}655}
651656
652#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]657#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]
658#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
653pub struct PropertyKeyPermission {659pub struct PropertyKeyPermission {
660 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
654 pub key: PropertyKey,661 pub key: PropertyKey,
662
655 pub permission: PropertyPermission,663 pub permission: PropertyPermission,
724 self.map.get(key)732 self.map.get(key)
725 }733 }
734
735 pub fn iter(&self) -> impl Iterator<Item = (&PropertyKey, &PropertyValue)> {
736 self.map.iter()
737 }
726}738}
727739
728pub struct CollectionProperties;740pub struct CollectionProperties;
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
17#![cfg_attr(not(feature = "std"), no_std)]17#![cfg_attr(not(feature = "std"), no_std)]
1818
19use up_data_structs::{CollectionId, TokenId, RpcCollection, CollectionStats, CollectionLimits};19use up_data_structs::{
20 CollectionId, TokenId, RpcCollection, CollectionStats, CollectionLimits, Property, PropertyKey,
21 PropertyKeyPermission,
22};
20use sp_std::vec::Vec;23use sp_std::vec::Vec;
21use codec::Decode;24use codec::Decode;
41 fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;44 fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;
42 fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;45 fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;
46
47 fn collection_properties(collection: CollectionId, properties: Vec<Vec<u8>>) -> Result<Vec<Property>>;
48
49 fn token_properties(
50 collection: CollectionId,
51 token_id: TokenId,
52 properties: Vec<Vec<u8>>
53 ) -> Result<Vec<Property>>;
54
55 fn property_permissions(
56 collection: CollectionId,
57 properties: Vec<Vec<u8>>
58 ) -> Result<Vec<PropertyKeyPermission>>;
4359
44 fn total_supply(collection: CollectionId) -> Result<u32>;60 fn total_supply(collection: CollectionId) -> Result<u32>;
45 fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32>;61 fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32>;
modifiedruntime/common/src/runtime_apis.rsdiffbeforeafterboth
7 $($custom_apis:tt)+7 $($custom_apis:tt)+
8 )?8 )?
9 ) => {9 ) => {
10 fn bytes_keys_to_property_keys(keys: Vec<Vec<u8>>) -> Result<Vec<PropertyKey>, DispatchError> {
11 keys.into_iter()
12 .map(|key| -> Result<PropertyKey, DispatchError> {
13 key.try_into().map_err(|_| DispatchError::Other("Can't read property key"))
14 })
15 .collect::<Result<Vec<PropertyKey>, DispatchError>>()
16 }
17
10 impl_runtime_apis! {18 impl_runtime_apis! {
11 $($($custom_apis)+)?19 $($($custom_apis)+)?
36 dispatch_unique_runtime!(collection.variable_metadata(token))44 dispatch_unique_runtime!(collection.variable_metadata(token))
37 }45 }
46
47 fn collection_properties(
48 collection: CollectionId,
49 keys: Vec<Vec<u8>>
50 ) -> Result<Vec<Property>, DispatchError> {
51 let keys = bytes_keys_to_property_keys(keys)?;
52
53 let properties = pallet_common::Pallet::<Runtime>::collection_properties(collection);
54
55 let properties = keys.into_iter()
56 .filter_map(|key| {
57 properties.get_property(&key)
58 .map(|value| {
59 Property {
60 key,
61 value: value.clone()
62 }
63 })
64 })
65 .collect();
66
67 Ok(properties)
68 }
69
70 fn token_properties(
71 collection: CollectionId,
72 token_id: TokenId,
73 keys: Vec<Vec<u8>>
74 ) -> Result<Vec<Property>, DispatchError> {
75 let keys = bytes_keys_to_property_keys(keys)?;
76
77 let properties = pallet_nonfungible::Pallet::<Runtime>::token_properties((collection, token_id));
78
79 let properties = keys.into_iter()
80 .filter_map(|key| {
81 properties.get_property(&key)
82 .map(|value| {
83 Property {
84 key,
85 value: value.clone()
86 }
87 })
88 })
89 .collect();
90
91 Ok(properties)
92 }
93
94 fn property_permissions(
95 collection: CollectionId,
96 keys: Vec<Vec<u8>>
97 ) -> Result<Vec<PropertyKeyPermission>, DispatchError> {
98 let keys = bytes_keys_to_property_keys(keys)?;
99
100 let permissions = pallet_common::Pallet::<Runtime>::property_permissions(collection);
101
102 let key_permissions = keys.into_iter()
103 .filter_map(|key| {
104 permissions.get(&key)
105 .map(|permission| {
106 PropertyKeyPermission {
107 key,
108 permission: permission.clone()
109 }
110 })
111 })
112 .collect();
113
114 Ok(key_permissions)
115 }
38116
39 fn total_supply(collection: CollectionId) -> Result<u32, DispatchError> {117 fn total_supply(collection: CollectionId) -> Result<u32, DispatchError> {
40 dispatch_unique_runtime!(collection.total_supply())118 dispatch_unique_runtime!(collection.total_supply())
modifiedruntime/opal/src/lib.rsdiffbeforeafterboth
67 },67 },
68};68};
69use up_data_structs::mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping};69use up_data_structs::mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping};
70use up_data_structs::{CollectionId, TokenId, CollectionStats, CollectionLimits, RpcCollection};70use up_data_structs::*;
71// use pallet_contracts::weights::WeightInfo;71// use pallet_contracts::weights::WeightInfo;
72// #[cfg(any(feature = "std", test))]72// #[cfg(any(feature = "std", test))]
73use frame_system::{73use frame_system::{