difftreelog
feat set/get tokenPropertyPermissions for NFT
in: master
5 files changed
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -34,7 +34,7 @@
CollectionPropertiesVec,
};
use pallet_evm_coder_substrate::dispatch_to_evm;
-use sp_std::vec::Vec;
+use sp_std::{vec::Vec, vec};
use pallet_common::{
CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},
@@ -70,10 +70,10 @@
token_owner: bool,
) -> Result<()> {
let caller = T::CrossAccountId::from_eth(caller);
- <Pallet<T>>::set_property_permissions(
+ <Pallet<T>>::set_token_property_permissions(
self,
&caller,
- [PropertyKeyPermission {
+ vec![PropertyKeyPermission {
key: <Vec<u8>>::from(key)
.try_into()
.map_err(|_| "too long key")?,
@@ -82,8 +82,7 @@
collection_admin,
token_owner,
},
- }]
- .into(),
+ }],
)
.map_err(dispatch_to_evm::<T>)
}
@@ -137,7 +136,8 @@
});
}
- <Pallet<T>>::set_property_permissions(self, &caller, perms).map_err(dispatch_to_evm::<T>)
+ <Pallet<T>>::set_token_property_permissions(self, &caller, perms)
+ .map_err(dispatch_to_evm::<T>)
}
fn token_property_permissions(
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -824,17 +824,6 @@
)
}
- /// Set property permissions for the collection.
- ///
- /// Sender should be the owner or admin of the collection.
- pub fn set_property_permissions(
- collection: &CollectionHandle<T>,
- sender: &T::CrossAccountId,
- permission: Vec<PropertyKeyPermission>,
- ) -> DispatchResult {
- <PalletCommon<T>>::set_token_property_permissions(collection, sender, permission)
- }
-
pub fn token_property_permission(collection_id: CollectionId) -> PropertiesPermissionMap {
<PalletCommon<T>>::property_permissions(collection_id)
}
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -33,7 +33,7 @@
use pallet_common::{
CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
erc::{CommonEvmHandler, CollectionCall, static_property::key},
- eth::EthCrossAccount,
+ eth::{EthCrossAccount, EthTokenPermissions},
Error as CommonError,
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
@@ -63,6 +63,7 @@
/// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
/// @param tokenOwner Permission to mutate property by token owner if property is mutable.
#[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]
+ #[solidity(hide)]
fn set_token_property_permission(
&mut self,
caller: caller,
@@ -89,6 +90,76 @@
.map_err(dispatch_to_evm::<T>)
}
+ /// @notice Set permissions for token property.
+ /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
+ /// @param permissions Permissions for keys.
+ fn set_token_property_permissions(
+ &mut self,
+ caller: caller,
+ permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>,
+ ) -> Result<()> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ const PERMISSIONS_FIELDS_COUNT: usize = 3;
+
+ let mut perms = <Vec<_>>::new();
+
+ for (key, pp) in permissions {
+ if pp.len() > PERMISSIONS_FIELDS_COUNT {
+ return Err(alloc::format!(
+ "Actual number of fields {} for {}, which exceeds the maximum value of {}",
+ pp.len(),
+ stringify!(EthTokenPermissions),
+ PERMISSIONS_FIELDS_COUNT
+ )
+ .as_str()
+ .into());
+ }
+
+ let mut token_permission = PropertyPermission {
+ mutable: false,
+ collection_admin: false,
+ token_owner: false,
+ };
+
+ for (perm, value) in pp {
+ match perm {
+ EthTokenPermissions::Mutable => token_permission.mutable = value,
+ EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
+ EthTokenPermissions::CollectionAdmin => {
+ token_permission.collection_admin = value
+ }
+ }
+ }
+
+ perms.push(PropertyKeyPermission {
+ key: <Vec<u8>>::from(key)
+ .try_into()
+ .map_err(|_| "too long key")?,
+ permission: token_permission,
+ });
+ }
+
+ <Pallet<T>>::set_token_property_permissions(self, &caller, perms)
+ .map_err(dispatch_to_evm::<T>)
+ }
+
+ fn token_property_permissions(
+ &self,
+ ) -> Result<Vec<(string, Vec<(EthTokenPermissions, bool)>)>> {
+ let mut res = <Vec<_>>::new();
+ for (key, pp) in <Pallet<T>>::token_property_permission(self.id) {
+ let key = string::from_utf8(key.into_inner()).unwrap();
+ let pp = [
+ (EthTokenPermissions::Mutable, pp.mutable),
+ (EthTokenPermissions::TokenOwner, pp.token_owner),
+ (EthTokenPermissions::CollectionAdmin, pp.collection_admin),
+ ]
+ .into();
+ res.push((key, pp));
+ }
+ Ok(res)
+ }
+
/// @notice Set token property value.
/// @dev Throws error if `msg.sender` has no permission to edit the property.
/// @param tokenId ID of the token.
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -113,7 +113,7 @@
AccessMode, budget::Budget, CollectionId, CollectionFlags, CollectionPropertiesVec,
CreateCollectionData, CustomDataLimit, mapping::TokenAddressMapping, MAX_ITEMS_PER_BATCH,
MAX_REFUNGIBLE_PIECES, Property, PropertyKey, PropertyKeyPermission, PropertyPermission,
- PropertyScope, PropertyValue, TokenId, TrySetProperty,
+ PropertyScope, PropertyValue, TokenId, TrySetProperty, PropertiesPermissionMap,
};
pub use pallet::*;
@@ -1378,6 +1378,10 @@
<PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)
}
+ pub fn token_property_permission(collection_id: CollectionId) -> PropertiesPermissionMap {
+ <PalletCommon<T>>::property_permissions(collection_id)
+ }
+
pub fn set_scoped_token_property_permissions(
collection: &RefungibleHandle<T>,
sender: &T::CrossAccountId,
tests/src/eth/tokenProperties.test.tsdiffbeforeafterboth32 });32 });33 });33 });343435 itEth.only('Can be reconfigured', async({helper}) => {35 itEth('Can be reconfigured', async({helper}) => {36 const caller = await helper.eth.createAccountWithBalance(donor);36 const caller = await helper.eth.createAccountWithBalance(donor);37 for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {37 for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {38 const collection = await helper.nft.mintCollection(alice);38 const collection = await helper.nft.mintCollection(alice);