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

difftreelog

Merge pull request #776 from UniqueNetwork/feature/evm_set-get_tokenPropertyPermissions

ut-akuznetsov2022-12-16parents: #3f0dc65 #0ade15e.patch.diff
in: master
Feature/evm_set-get_tokenPropertyPermissions

22 files changed

modifiedCargo.lockdiffbeforeafterboth
63426342
6343[[package]]6343[[package]]
6344name = "pallet-nonfungible"6344name = "pallet-nonfungible"
6345version = "0.1.9"6345version = "0.1.11"
6346dependencies = [6346dependencies = [
6347 "ethereum 0.14.0",6347 "ethereum 0.14.0",
6348 "evm-coder",6348 "evm-coder",
65016501
6502[[package]]6502[[package]]
6503name = "pallet-refungible"6503name = "pallet-refungible"
6504version = "0.2.8"6504version = "0.2.10"
6505dependencies = [6505dependencies = [
6506 "derivative",6506 "derivative",
6507 "ethereum 0.14.0",6507 "ethereum 0.14.0",
modifiedcrates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth
740 /// Some docs740 /// Some docs
741 /// At multi741 /// At multi
742 /// line742 /// line
743 #[derive(AbiCoder, Debug, PartialEq, Default)]743 #[derive(AbiCoder, Debug, PartialEq, Default, Clone, Copy)]
744 #[repr(u8)]744 #[repr(u8)]
745 enum Color {745 enum Color {
746 /// Docs for Red746 /// Docs for Red
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
163 TokenOwner,163 TokenOwner,
164}164}
165
166/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
167#[derive(AbiCoder, Copy, Clone, Default, Debug)]
168#[repr(u8)]
169pub enum EthTokenPermissions {
170 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
171 #[default]
172 Mutable,
173
174 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
175 TokenOwner,
176
177 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
178 CollectionAdmin,
179}
165180
modifiedpallets/nonfungible/CHANGELOG.mddiffbeforeafterboth
44
5<!-- bureaucrate goes here -->5<!-- bureaucrate goes here -->
66
7## [0.1.11] - 2022-12-16
8
9### Added
10
11- The function `tokenPropertyPermissions` and `setTokenPropertyPermissions` to `TokenProperties` interface.
12
13### Changed
14
15- Hide `setTokenPropertyPermission` function in `TokenProperties` interface.
16
7## [0.1.10] - 2022-11-1817## [0.1.10] - 2022-11-18
818
9### Added19### Added
modifiedpallets/nonfungible/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "pallet-nonfungible"2name = "pallet-nonfungible"
3version = "0.1.9"3version = "0.1.11"
4license = "GPLv3"4license = "GPLv3"
5edition = "2021"5edition = "2021"
66
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
34 CollectionPropertiesVec,34 CollectionPropertiesVec,
35};35};
36use pallet_evm_coder_substrate::dispatch_to_evm;36use pallet_evm_coder_substrate::dispatch_to_evm;
37use sp_std::vec::Vec;37use sp_std::{vec::Vec, vec};
38use pallet_common::{38use pallet_common::{
39 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,39 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
40 erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},40 erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},
41 eth::EthCrossAccount,41 eth::{EthCrossAccount, EthTokenPermissions},
42};42};
43use pallet_evm::{account::CrossAccountId, PrecompileHandle};43use pallet_evm::{account::CrossAccountId, PrecompileHandle};
44use pallet_evm_coder_substrate::call;44use pallet_evm_coder_substrate::call;
60 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.60 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
61 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.61 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
62 #[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]62 #[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]
63 #[solidity(hide)]
63 fn set_token_property_permission(64 fn set_token_property_permission(
64 &mut self,65 &mut self,
65 caller: caller,66 caller: caller,
69 token_owner: bool,70 token_owner: bool,
70 ) -> Result<()> {71 ) -> Result<()> {
71 let caller = T::CrossAccountId::from_eth(caller);72 let caller = T::CrossAccountId::from_eth(caller);
72 <Pallet<T>>::set_property_permission(73 <Pallet<T>>::set_token_property_permissions(
73 self,74 self,
74 &caller,75 &caller,
75 PropertyKeyPermission {76 vec![PropertyKeyPermission {
76 key: <Vec<u8>>::from(key)77 key: <Vec<u8>>::from(key)
77 .try_into()78 .try_into()
78 .map_err(|_| "too long key")?,79 .map_err(|_| "too long key")?,
79 permission: PropertyPermission {80 permission: PropertyPermission {
80 mutable: is_mutable,81 mutable: is_mutable,
81 collection_admin,82 collection_admin,
82 token_owner,83 token_owner,
83 },84 },
84 },85 }],
85 )86 )
86 .map_err(dispatch_to_evm::<T>)87 .map_err(dispatch_to_evm::<T>)
87 }88 }
89
90 /// @notice Set permissions for token property.
91 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
92 /// @param permissions Permissions for keys.
93 #[weight(<SelfWeightOf<T>>::set_token_property_permissions(permissions.len() as u32))]
94 fn set_token_property_permissions(
95 &mut self,
96 caller: caller,
97 permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>,
98 ) -> Result<()> {
99 let caller = T::CrossAccountId::from_eth(caller);
100 const PERMISSIONS_FIELDS_COUNT: usize = 3;
101
102 let mut perms = Vec::new();
103
104 for (key, pp) in permissions {
105 if pp.len() > PERMISSIONS_FIELDS_COUNT {
106 return Err(alloc::format!(
107 "Actual number of fields {} for {}, which exceeds the maximum value of {}",
108 pp.len(),
109 stringify!(EthTokenPermissions),
110 PERMISSIONS_FIELDS_COUNT
111 )
112 .as_str()
113 .into());
114 }
115
116 let mut token_permission = PropertyPermission::default();
117
118 for (perm, value) in pp {
119 match perm {
120 EthTokenPermissions::Mutable => token_permission.mutable = value,
121 EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
122 EthTokenPermissions::CollectionAdmin => {
123 token_permission.collection_admin = value
124 }
125 }
126 }
127
128 perms.push(PropertyKeyPermission {
129 key: key.into_bytes().try_into().map_err(|_| "too long key")?,
130 permission: token_permission,
131 });
132 }
133
134 <Pallet<T>>::set_token_property_permissions(self, &caller, perms)
135 .map_err(dispatch_to_evm::<T>)
136 }
137
138 /// @notice Get permissions for token properties.
139 fn token_property_permissions(
140 &self,
141 ) -> Result<Vec<(string, Vec<(EthTokenPermissions, bool)>)>> {
142 let perms = <Pallet<T>>::token_property_permission(self.id);
143 Ok(perms
144 .into_iter()
145 .map(|(key, pp)| {
146 let key = string::from_utf8(key.into_inner()).expect("Stored key must be valid");
147 let pp = vec![
148 (EthTokenPermissions::Mutable, pp.mutable),
149 (EthTokenPermissions::TokenOwner, pp.token_owner),
150 (EthTokenPermissions::CollectionAdmin, pp.collection_admin),
151 ];
152 (key, pp)
153 })
154 .collect())
155 }
88156
89 /// @notice Set token property value.157 /// @notice Set token property value.
90 /// @dev Throws error if `msg.sender` has no permission to edit the property.158 /// @dev Throws error if `msg.sender` has no permission to edit the property.
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
103 AccessMode, CollectionId, CollectionFlags, CustomDataLimit, TokenId, CreateCollectionData,103 AccessMode, CollectionId, CollectionFlags, CustomDataLimit, TokenId, CreateCollectionData,
104 CreateNftExData, mapping::TokenAddressMapping, budget::Budget, Property, PropertyPermission,104 CreateNftExData, mapping::TokenAddressMapping, budget::Budget, Property, PropertyPermission,
105 PropertyKey, PropertyValue, PropertyKeyPermission, Properties, PropertyScope, TrySetProperty,105 PropertyKey, PropertyValue, PropertyKeyPermission, Properties, PropertyScope, TrySetProperty,
106 TokenChild, AuxPropertyValue,106 TokenChild, AuxPropertyValue, PropertiesPermissionMap,
107};107};
108use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};108use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
109use pallet_common::{109use pallet_common::{
824 )824 )
825 }825 }
826826
827 /// Set property permissions for the collection.
828 ///
829 /// Sender should be the owner or admin of the collection.
830 pub fn set_property_permission(827 pub fn token_property_permission(collection_id: CollectionId) -> PropertiesPermissionMap {
831 collection: &CollectionHandle<T>,
832 sender: &T::CrossAccountId,
833 permission: PropertyKeyPermission,
834 ) -> DispatchResult {
835 <PalletCommon<T>>::set_property_permission(collection, sender, permission)828 <PalletCommon<T>>::property_permissions(collection_id)
836 }829 }
837830
838 pub fn check_token_immediate_ownership(831 pub fn check_token_immediate_ownership(
modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
18}18}
1919
20/// @title A contract that allows to set and delete token properties and change token property permissions.20/// @title A contract that allows to set and delete token properties and change token property permissions.
21/// @dev the ERC-165 identifier for this interface is 0x91a97a6821/// @dev the ERC-165 identifier for this interface is 0xde0695c2
22contract TokenProperties is Dummy, ERC165 {22contract TokenProperties is Dummy, ERC165 {
23 // /// @notice Set permissions for token property.
24 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
25 // /// @param key Property key.
26 // /// @param isMutable Permission to mutate property.
27 // /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
28 // /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
29 // /// @dev EVM selector for this function is: 0x222d97fa,
30 // /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
31 // function setTokenPropertyPermission(string memory key, bool isMutable, bool collectionAdmin, bool tokenOwner) public {
32 // require(false, stub_error);
33 // key;
34 // isMutable;
35 // collectionAdmin;
36 // tokenOwner;
37 // dummy = 0;
38 // }
39
23 /// @notice Set permissions for token property.40 /// @notice Set permissions for token property.
24 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.41 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
25 /// @param key Property key.42 /// @param permissions Permissions for keys.
26 /// @param isMutable Permission to mutate property.
27 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
28 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
29 /// @dev EVM selector for this function is: 0x222d97fa,43 /// @dev EVM selector for this function is: 0xbd92983a,
30 /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)44 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
31 function setTokenPropertyPermission(45 function setTokenPropertyPermissions(Tuple48[] memory permissions) public {
32 string memory key,
33 bool isMutable,
34 bool collectionAdmin,
35 bool tokenOwner
36 ) public {
37 require(false, stub_error);46 require(false, stub_error);
38 key;47 permissions;
39 isMutable;
40 collectionAdmin;
41 tokenOwner;
42 dummy = 0;48 dummy = 0;
43 }49 }
50
51 /// @dev EVM selector for this function is: 0xf23d7790,
52 /// or in textual repr: tokenPropertyPermissions()
53 function tokenPropertyPermissions() public view returns (Tuple48[] memory) {
54 require(false, stub_error);
55 dummy;
56 return new Tuple48[](0);
57 }
4458
45 // /// @notice Set token property value.59 // /// @notice Set token property value.
46 // /// @dev Throws error if `msg.sender` has no permission to edit the property.60 // /// @dev Throws error if `msg.sender` has no permission to edit the property.
118 bytes value;132 bytes value;
119}133}
134
135enum EthTokenPermissions {
136 Mutable,
137 TokenOwner,
138 CollectionAdmin
139}
140
141/// @dev anonymous struct
142struct Tuple48 {
143 string field_0;
144 Tuple46[] field_1;
145}
146
147/// @dev anonymous struct
148struct Tuple46 {
149 EthTokenPermissions field_0;
150 bool field_1;
151}
120152
121/// @title A contract that allows you to work with collections.153/// @title A contract that allows you to work with collections.
122/// @dev the ERC-165 identifier for this interface is 0xb5e1747f154/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
modifiedpallets/refungible/CHANGELOG.mddiffbeforeafterboth
44
5<!-- bureaucrate goes here -->5<!-- bureaucrate goes here -->
66
7## [0.2.10] - 2022-12-16
8
9### Added
10
11- The function `tokenPropertyPermissions` and `setTokenPropertyPermissions` to `TokenProperties` interface.
12
13### Changed
14
15- Hide `setTokenPropertyPermission` function in `TokenProperties` interface.
16
7## [0.2.9] - 2022-11-1817## [0.2.9] - 2022-11-18
818
9### Added19### Added
modifiedpallets/refungible/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "pallet-refungible"2name = "pallet-refungible"
3version = "0.2.8"3version = "0.2.10"
4license = "GPLv3"4license = "GPLv3"
5edition = "2021"5edition = "2021"
66
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
33use pallet_common::{33use pallet_common::{
34 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,34 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
35 erc::{CommonEvmHandler, CollectionCall, static_property::key},35 erc::{CommonEvmHandler, CollectionCall, static_property::key},
36 eth::EthCrossAccount,36 eth::{EthCrossAccount, EthTokenPermissions},
37 Error as CommonError,37 Error as CommonError,
38};38};
39use pallet_evm::{account::CrossAccountId, PrecompileHandle};39use pallet_evm::{account::CrossAccountId, PrecompileHandle};
63 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.63 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
64 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.64 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
65 #[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]65 #[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]
66 #[solidity(hide)]
66 fn set_token_property_permission(67 fn set_token_property_permission(
67 &mut self,68 &mut self,
68 caller: caller,69 caller: caller,
89 .map_err(dispatch_to_evm::<T>)90 .map_err(dispatch_to_evm::<T>)
90 }91 }
92
93 /// @notice Set permissions for token property.
94 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
95 /// @param permissions Permissions for keys.
96 #[weight(<SelfWeightOf<T>>::set_token_property_permissions(permissions.len() as u32))]
97 fn set_token_property_permissions(
98 &mut self,
99 caller: caller,
100 permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>,
101 ) -> Result<()> {
102 let caller = T::CrossAccountId::from_eth(caller);
103 const PERMISSIONS_FIELDS_COUNT: usize = 3;
104
105 let mut perms = Vec::new();
106
107 for (key, pp) in permissions {
108 if pp.len() > PERMISSIONS_FIELDS_COUNT {
109 return Err(alloc::format!(
110 "Actual number of fields {} for {}, which exceeds the maximum value of {}",
111 pp.len(),
112 stringify!(EthTokenPermissions),
113 PERMISSIONS_FIELDS_COUNT
114 )
115 .as_str()
116 .into());
117 }
118
119 let mut token_permission = PropertyPermission {
120 mutable: false,
121 collection_admin: false,
122 token_owner: false,
123 };
124
125 for (perm, value) in pp {
126 match perm {
127 EthTokenPermissions::Mutable => token_permission.mutable = value,
128 EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
129 EthTokenPermissions::CollectionAdmin => {
130 token_permission.collection_admin = value
131 }
132 }
133 }
134
135 perms.push(PropertyKeyPermission {
136 key: key.into_bytes().try_into().map_err(|_| "too long key")?,
137 permission: token_permission,
138 });
139 }
140
141 <Pallet<T>>::set_token_property_permissions(self, &caller, perms)
142 .map_err(dispatch_to_evm::<T>)
143 }
144
145 /// @notice Get permissions for token properties.
146 fn token_property_permissions(
147 &self,
148 ) -> Result<Vec<(string, Vec<(EthTokenPermissions, bool)>)>> {
149 let perms = <Pallet<T>>::token_property_permission(self.id);
150 Ok(perms
151 .into_iter()
152 .map(|(key, pp)| {
153 let key = string::from_utf8(key.into_inner()).expect("Stored key must be valid");
154 let pp = vec![
155 (EthTokenPermissions::Mutable, pp.mutable),
156 (EthTokenPermissions::TokenOwner, pp.token_owner),
157 (EthTokenPermissions::CollectionAdmin, pp.collection_admin),
158 ];
159 (key, pp)
160 })
161 .collect())
162 }
91163
92 /// @notice Set token property value.164 /// @notice Set token property value.
93 /// @dev Throws error if `msg.sender` has no permission to edit the property.165 /// @dev Throws error if `msg.sender` has no permission to edit the property.
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
113 AccessMode, budget::Budget, CollectionId, CollectionFlags, CollectionPropertiesVec,113 AccessMode, budget::Budget, CollectionId, CollectionFlags, CollectionPropertiesVec,
114 CreateCollectionData, CustomDataLimit, mapping::TokenAddressMapping, MAX_ITEMS_PER_BATCH,114 CreateCollectionData, CustomDataLimit, mapping::TokenAddressMapping, MAX_ITEMS_PER_BATCH,
115 MAX_REFUNGIBLE_PIECES, Property, PropertyKey, PropertyKeyPermission, PropertyPermission,115 MAX_REFUNGIBLE_PIECES, Property, PropertyKey, PropertyKeyPermission, PropertyPermission,
116 PropertyScope, PropertyValue, TokenId, TrySetProperty,116 PropertyScope, PropertyValue, TokenId, TrySetProperty, PropertiesPermissionMap,
117};117};
118118
119pub use pallet::*;119pub use pallet::*;
1378 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)1378 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)
1379 }1379 }
1380
1381 pub fn token_property_permission(collection_id: CollectionId) -> PropertiesPermissionMap {
1382 <PalletCommon<T>>::property_permissions(collection_id)
1383 }
13801384
1381 pub fn set_scoped_token_property_permissions(1385 pub fn set_scoped_token_property_permissions(
1382 collection: &RefungibleHandle<T>,1386 collection: &RefungibleHandle<T>,
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
18}18}
1919
20/// @title A contract that allows to set and delete token properties and change token property permissions.20/// @title A contract that allows to set and delete token properties and change token property permissions.
21/// @dev the ERC-165 identifier for this interface is 0x91a97a6821/// @dev the ERC-165 identifier for this interface is 0xde0695c2
22contract TokenProperties is Dummy, ERC165 {22contract TokenProperties is Dummy, ERC165 {
23 // /// @notice Set permissions for token property.
24 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
25 // /// @param key Property key.
26 // /// @param isMutable Permission to mutate property.
27 // /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
28 // /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
29 // /// @dev EVM selector for this function is: 0x222d97fa,
30 // /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
31 // function setTokenPropertyPermission(string memory key, bool isMutable, bool collectionAdmin, bool tokenOwner) public {
32 // require(false, stub_error);
33 // key;
34 // isMutable;
35 // collectionAdmin;
36 // tokenOwner;
37 // dummy = 0;
38 // }
39
23 /// @notice Set permissions for token property.40 /// @notice Set permissions for token property.
24 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.41 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
25 /// @param key Property key.42 /// @param permissions Permissions for keys.
26 /// @param isMutable Permission to mutate property.
27 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
28 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
29 /// @dev EVM selector for this function is: 0x222d97fa,43 /// @dev EVM selector for this function is: 0xbd92983a,
30 /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)44 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
31 function setTokenPropertyPermission(45 function setTokenPropertyPermissions(Tuple53[] memory permissions) public {
32 string memory key,
33 bool isMutable,
34 bool collectionAdmin,
35 bool tokenOwner
36 ) public {
37 require(false, stub_error);46 require(false, stub_error);
38 key;47 permissions;
39 isMutable;
40 collectionAdmin;
41 tokenOwner;
42 dummy = 0;48 dummy = 0;
43 }49 }
50
51 /// @notice Get permissions for token properties.
52 /// @dev EVM selector for this function is: 0xf23d7790,
53 /// or in textual repr: tokenPropertyPermissions()
54 function tokenPropertyPermissions() public view returns (Tuple53[] memory) {
55 require(false, stub_error);
56 dummy;
57 return new Tuple53[](0);
58 }
4459
45 // /// @notice Set token property value.60 // /// @notice Set token property value.
46 // /// @dev Throws error if `msg.sender` has no permission to edit the property.61 // /// @dev Throws error if `msg.sender` has no permission to edit the property.
118 bytes value;133 bytes value;
119}134}
135
136enum EthTokenPermissions {
137 Mutable,
138 TokenOwner,
139 CollectionAdmin
140}
141
142/// @dev anonymous struct
143struct Tuple53 {
144 string field_0;
145 Tuple51[] field_1;
146}
147
148/// @dev anonymous struct
149struct Tuple51 {
150 EthTokenPermissions field_0;
151 bool field_1;
152}
120153
121/// @title A contract that allows you to work with collections.154/// @title A contract that allows you to work with collections.
122/// @dev the ERC-165 identifier for this interface is 0xb5e1747f155/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
1010pub type PropertyValue = BoundedBytes<ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;1010pub type PropertyValue = BoundedBytes<ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;
10111011
1012/// Property permission.1012/// Property permission.
1013#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]1013#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone, Default)]
1014#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]1014#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
1015pub struct PropertyPermission {1015pub struct PropertyPermission {
1016 /// Permission to change the property and property permission.1016 /// Permission to change the property and property permission.
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
697 },697 },
698 {698 {
699 "inputs": [699 "inputs": [
700 {
701 "components": [
700 { "internalType": "string", "name": "key", "type": "string" },702 { "internalType": "string", "name": "field_0", "type": "string" },
703 {
704 "components": [
701 { "internalType": "bool", "name": "isMutable", "type": "bool" },705 {
706 "internalType": "enum EthTokenPermissions",
707 "name": "field_0",
708 "type": "uint8"
709 },
702 { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },710 { "internalType": "bool", "name": "field_1", "type": "bool" }
711 ],
712 "internalType": "struct Tuple46[]",
713 "name": "field_1",
714 "type": "tuple[]"
715 }
716 ],
703 { "internalType": "bool", "name": "tokenOwner", "type": "bool" }717 "internalType": "struct Tuple48[]",
718 "name": "permissions",
719 "type": "tuple[]"
720 }
704 ],721 ],
705 "name": "setTokenPropertyPermission",722 "name": "setTokenPropertyPermissions",
706 "outputs": [],723 "outputs": [],
707 "stateMutability": "nonpayable",724 "stateMutability": "nonpayable",
708 "type": "function"725 "type": "function"
742 "stateMutability": "view",759 "stateMutability": "view",
743 "type": "function"760 "type": "function"
744 },761 },
762 {
763 "inputs": [],
764 "name": "tokenPropertyPermissions",
765 "outputs": [
766 {
767 "components": [
768 { "internalType": "string", "name": "field_0", "type": "string" },
769 {
770 "components": [
771 {
772 "internalType": "enum EthTokenPermissions",
773 "name": "field_0",
774 "type": "uint8"
775 },
776 { "internalType": "bool", "name": "field_1", "type": "bool" }
777 ],
778 "internalType": "struct Tuple46[]",
779 "name": "field_1",
780 "type": "tuple[]"
781 }
782 ],
783 "internalType": "struct Tuple48[]",
784 "name": "",
785 "type": "tuple[]"
786 }
787 ],
788 "stateMutability": "view",
789 "type": "function"
790 },
745 {791 {
746 "inputs": [792 "inputs": [
747 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }793 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
679 },679 },
680 {680 {
681 "inputs": [681 "inputs": [
682 {
683 "components": [
682 { "internalType": "string", "name": "key", "type": "string" },684 { "internalType": "string", "name": "field_0", "type": "string" },
685 {
686 "components": [
683 { "internalType": "bool", "name": "isMutable", "type": "bool" },687 {
688 "internalType": "enum EthTokenPermissions",
689 "name": "field_0",
690 "type": "uint8"
691 },
684 { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },692 { "internalType": "bool", "name": "field_1", "type": "bool" }
693 ],
694 "internalType": "struct Tuple51[]",
695 "name": "field_1",
696 "type": "tuple[]"
697 }
698 ],
685 { "internalType": "bool", "name": "tokenOwner", "type": "bool" }699 "internalType": "struct Tuple53[]",
700 "name": "permissions",
701 "type": "tuple[]"
702 }
686 ],703 ],
687 "name": "setTokenPropertyPermission",704 "name": "setTokenPropertyPermissions",
688 "outputs": [],705 "outputs": [],
689 "stateMutability": "nonpayable",706 "stateMutability": "nonpayable",
690 "type": "function"707 "type": "function"
733 "stateMutability": "view",750 "stateMutability": "view",
734 "type": "function"751 "type": "function"
735 },752 },
753 {
754 "inputs": [],
755 "name": "tokenPropertyPermissions",
756 "outputs": [
757 {
758 "components": [
759 { "internalType": "string", "name": "field_0", "type": "string" },
760 {
761 "components": [
762 {
763 "internalType": "enum EthTokenPermissions",
764 "name": "field_0",
765 "type": "uint8"
766 },
767 { "internalType": "bool", "name": "field_1", "type": "bool" }
768 ],
769 "internalType": "struct Tuple51[]",
770 "name": "field_1",
771 "type": "tuple[]"
772 }
773 ],
774 "internalType": "struct Tuple53[]",
775 "name": "",
776 "type": "tuple[]"
777 }
778 ],
779 "stateMutability": "view",
780 "type": "function"
781 },
736 {782 {
737 "inputs": [783 "inputs": [
738 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }784 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
13}13}
1414
15/// @title A contract that allows to set and delete token properties and change token property permissions.15/// @title A contract that allows to set and delete token properties and change token property permissions.
16/// @dev the ERC-165 identifier for this interface is 0x91a97a6816/// @dev the ERC-165 identifier for this interface is 0xde0695c2
17interface TokenProperties is Dummy, ERC165 {17interface TokenProperties is Dummy, ERC165 {
18 // /// @notice Set permissions for token property.
19 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
20 // /// @param key Property key.
21 // /// @param isMutable Permission to mutate property.
22 // /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
23 // /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
24 // /// @dev EVM selector for this function is: 0x222d97fa,
25 // /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
26 // function setTokenPropertyPermission(string memory key, bool isMutable, bool collectionAdmin, bool tokenOwner) external;
27
18 /// @notice Set permissions for token property.28 /// @notice Set permissions for token property.
19 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.29 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
20 /// @param key Property key.30 /// @param permissions Permissions for keys.
21 /// @param isMutable Permission to mutate property.
22 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
23 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
24 /// @dev EVM selector for this function is: 0x222d97fa,31 /// @dev EVM selector for this function is: 0xbd92983a,
25 /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)32 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
26 function setTokenPropertyPermission(33 function setTokenPropertyPermissions(Tuple43[] memory permissions) external;
27 string memory key,34
28 bool isMutable,35 /// @dev EVM selector for this function is: 0xf23d7790,
29 bool collectionAdmin,36 /// or in textual repr: tokenPropertyPermissions()
30 bool tokenOwner37 function tokenPropertyPermissions() external view returns (Tuple43[] memory);
31 ) external;
3238
33 // /// @notice Set token property value.39 // /// @notice Set token property value.
79 bytes value;85 bytes value;
80}86}
87
88enum EthTokenPermissions {
89 Mutable,
90 TokenOwner,
91 CollectionAdmin
92}
93
94/// @dev anonymous struct
95struct Tuple43 {
96 string field_0;
97 Tuple41[] field_1;
98}
99
100/// @dev anonymous struct
101struct Tuple41 {
102 EthTokenPermissions field_0;
103 bool field_1;
104}
81105
82/// @title A contract that allows you to work with collections.106/// @title A contract that allows you to work with collections.
83/// @dev the ERC-165 identifier for this interface is 0xb5e1747f107/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
13}13}
1414
15/// @title A contract that allows to set and delete token properties and change token property permissions.15/// @title A contract that allows to set and delete token properties and change token property permissions.
16/// @dev the ERC-165 identifier for this interface is 0x91a97a6816/// @dev the ERC-165 identifier for this interface is 0xde0695c2
17interface TokenProperties is Dummy, ERC165 {17interface TokenProperties is Dummy, ERC165 {
18 // /// @notice Set permissions for token property.
19 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
20 // /// @param key Property key.
21 // /// @param isMutable Permission to mutate property.
22 // /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
23 // /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
24 // /// @dev EVM selector for this function is: 0x222d97fa,
25 // /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
26 // function setTokenPropertyPermission(string memory key, bool isMutable, bool collectionAdmin, bool tokenOwner) external;
27
18 /// @notice Set permissions for token property.28 /// @notice Set permissions for token property.
19 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.29 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
20 /// @param key Property key.30 /// @param permissions Permissions for keys.
21 /// @param isMutable Permission to mutate property.
22 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
23 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
24 /// @dev EVM selector for this function is: 0x222d97fa,31 /// @dev EVM selector for this function is: 0xbd92983a,
25 /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)32 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
26 function setTokenPropertyPermission(33 function setTokenPropertyPermissions(Tuple47[] memory permissions) external;
27 string memory key,34
28 bool isMutable,35 /// @notice Get permissions for token properties.
29 bool collectionAdmin,36 /// @dev EVM selector for this function is: 0xf23d7790,
30 bool tokenOwner37 /// or in textual repr: tokenPropertyPermissions()
31 ) external;38 function tokenPropertyPermissions() external view returns (Tuple47[] memory);
3239
33 // /// @notice Set token property value.40 // /// @notice Set token property value.
34 // /// @dev Throws error if `msg.sender` has no permission to edit the property.41 // /// @dev Throws error if `msg.sender` has no permission to edit the property.
79 bytes value;86 bytes value;
80}87}
88
89enum EthTokenPermissions {
90 Mutable,
91 TokenOwner,
92 CollectionAdmin
93}
94
95/// @dev anonymous struct
96struct Tuple47 {
97 string field_0;
98 Tuple45[] field_1;
99}
100
101/// @dev anonymous struct
102struct Tuple45 {
103 EthTokenPermissions field_0;
104 bool field_1;
105}
81106
82/// @title A contract that allows you to work with collections.107/// @title A contract that allows you to work with collections.
83/// @dev the ERC-165 identifier for this interface is 0xb5e1747f108/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
modifiedtests/src/eth/events.test.tsdiffbeforeafterboth
19import {EthUniqueHelper, itEth, usingEthPlaygrounds} from './util';19import {EthUniqueHelper, itEth, usingEthPlaygrounds} from './util';
20import {IEvent, TCollectionMode} from '../util/playgrounds/types';20import {IEvent, TCollectionMode} from '../util/playgrounds/types';
21import {Pallets, requirePalletsOrSkip} from '../util';21import {Pallets, requirePalletsOrSkip} from '../util';
22import {NormalizedEvent} from './util/playgrounds/types';22import {EthTokenPermissions, NormalizedEvent} from './util/playgrounds/types';
2323
24let donor: IKeyringPair;24let donor: IKeyringPair;
25 25
119 ethEvents.push(event);119 ethEvents.push(event);
120 });120 });
121 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['PropertyPermissionSet']}]);121 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['PropertyPermissionSet']}]);
122 await collection.methods.setTokenPropertyPermission('testKey', true, true, true).send({from: owner});122 await collection.methods.setTokenPropertyPermissions([
123 ['A', [
124 [EthTokenPermissions.Mutable, true],
125 [EthTokenPermissions.TokenOwner, true],
126 [EthTokenPermissions.CollectionAdmin, true]],
127 ],
128 ]).send({from: owner});
123 await helper.wait.newBlocks(1);129 await helper.wait.newBlocks(1);
124 expect(ethEvents).to.be.like([130 expect(ethEvents).to.be.like([
125 {131 {
374 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);380 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
375 const result = await collection.methods.mint(owner).send({from: owner});381 const result = await collection.methods.mint(owner).send({from: owner});
376 const tokenId = result.events.Transfer.returnValues.tokenId;382 const tokenId = result.events.Transfer.returnValues.tokenId;
377 await collection.methods.setTokenPropertyPermission('A', true, true, true).send({from: owner});383 await collection.methods.setTokenPropertyPermissions([
384 ['A', [
385 [EthTokenPermissions.Mutable, true],
386 [EthTokenPermissions.TokenOwner, true],
387 [EthTokenPermissions.CollectionAdmin, true]],
388 ],
389 ]).send({from: owner});
378390
379391
380 const ethEvents: any = [];392 const ethEvents: any = [];
modifiedtests/src/eth/tokenProperties.test.tsdiffbeforeafterboth
20import {ITokenPropertyPermission} from '../util/playgrounds/types';20import {ITokenPropertyPermission} from '../util/playgrounds/types';
21import {Pallets} from '../util';21import {Pallets} from '../util';
22import {UniqueNFTCollection, UniqueNFToken, UniqueRFTCollection} from '../util/playgrounds/unique';22import {UniqueNFTCollection, UniqueNFToken, UniqueRFTCollection} from '../util/playgrounds/unique';
23import {EthTokenPermissions} from './util/playgrounds/types';
2324
24describe('EVM token properties', () => {25describe('EVM token properties', () => {
25 let donor: IKeyringPair;26 let donor: IKeyringPair;
32 });33 });
33 });34 });
3435
36 [
37 {mode: 'nft' as const, requiredPallets: []},
38 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
39 ].map(testCase =>
35 itEth('Can be reconfigured', async({helper}) => {40 itEth.ifWithPallets(`[${testCase.mode}] Set and get token property permissions`, testCase.requiredPallets, async({helper}) => {
36 const caller = await helper.eth.createAccountWithBalance(donor);41 const owner = await helper.eth.createAccountWithBalance(donor);
42 const caller = await helper.ethCrossAccount.createAccountWithBalance(donor);
37 for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {43 for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {
38 const collection = await helper.nft.mintCollection(alice);44 const {collectionId, collectionAddress} = await helper.eth.createCollection(testCase.mode, owner, 'A', 'B', 'C');
39 await collection.addAdmin(alice, {Ethereum: caller});
40
41 const address = helper.ethAddress.fromCollectionId(collection.collectionId);45 const collection = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);
42 const contract = helper.ethNativeContract.collection(address, 'nft', caller);46 await collection.methods.addCollectionAdminCross(caller).send({from: owner});
43 47
44 await contract.methods.setTokenPropertyPermission('testKey', mutable, collectionAdmin, tokenOwner).send({from: caller});48 await collection.methods.setTokenPropertyPermissions([
45 49 ['testKey', [
50 [EthTokenPermissions.Mutable, mutable],
51 [EthTokenPermissions.TokenOwner, tokenOwner],
52 [EthTokenPermissions.CollectionAdmin, collectionAdmin]],
53 ],
54 ]).send({from: caller.eth});
55
46 expect(await collection.getPropertyPermissions()).to.be.deep.equal([{56 expect(await helper[testCase.mode].getPropertyPermissions(collectionId)).to.be.deep.equal([{
47 key: 'testKey',57 key: 'testKey',
48 permission: {mutable, collectionAdmin, tokenOwner},58 permission: {mutable, collectionAdmin, tokenOwner},
49 }]);59 }]);
60
61 expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([
62 ['testKey', [
63 [EthTokenPermissions.Mutable.toString(), mutable],
64 [EthTokenPermissions.TokenOwner.toString(), tokenOwner],
65 [EthTokenPermissions.CollectionAdmin.toString(), collectionAdmin]],
66 ],
67 ]);
50 }68 }
51 });69 }));
70
71 [
72 {mode: 'nft' as const, requiredPallets: []},
73 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
74 ].map(testCase =>
75 itEth.ifWithPallets(`[${testCase.mode}] Set and get multiple token property permissions as owner`, testCase.requiredPallets, async({helper}) => {
76 const owner = await helper.eth.createAccountWithBalance(donor);
77
78 const {collectionId, collectionAddress} = await helper.eth.createCollection(testCase.mode, owner, 'A', 'B', 'C');
79 const collection = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);
80
81 await collection.methods.setTokenPropertyPermissions([
82 ['testKey_0', [
83 [EthTokenPermissions.Mutable, true],
84 [EthTokenPermissions.TokenOwner, true],
85 [EthTokenPermissions.CollectionAdmin, true]],
86 ],
87 ['testKey_1', [
88 [EthTokenPermissions.Mutable, true],
89 [EthTokenPermissions.TokenOwner, false],
90 [EthTokenPermissions.CollectionAdmin, true]],
91 ],
92 ['testKey_2', [
93 [EthTokenPermissions.Mutable, false],
94 [EthTokenPermissions.TokenOwner, true],
95 [EthTokenPermissions.CollectionAdmin, false]],
96 ],
97 ]).send({from: owner});
98
99 expect(await helper[testCase.mode].getPropertyPermissions(collectionId)).to.be.deep.equal([
100 {
101 key: 'testKey_0',
102 permission: {mutable: true, tokenOwner: true, collectionAdmin: true},
103 },
104 {
105 key: 'testKey_1',
106 permission: {mutable: true, tokenOwner: false, collectionAdmin: true},
107 },
108 {
109 key: 'testKey_2',
110 permission: {mutable: false, tokenOwner: true, collectionAdmin: false},
111 },
112 ]);
113
114 expect(await collection.methods.tokenPropertyPermissions().call({from: owner})).to.be.like([
115 ['testKey_0', [
116 [EthTokenPermissions.Mutable.toString(), true],
117 [EthTokenPermissions.TokenOwner.toString(), true],
118 [EthTokenPermissions.CollectionAdmin.toString(), true]],
119 ],
120 ['testKey_1', [
121 [EthTokenPermissions.Mutable.toString(), true],
122 [EthTokenPermissions.TokenOwner.toString(), false],
123 [EthTokenPermissions.CollectionAdmin.toString(), true]],
124 ],
125 ['testKey_2', [
126 [EthTokenPermissions.Mutable.toString(), false],
127 [EthTokenPermissions.TokenOwner.toString(), true],
128 [EthTokenPermissions.CollectionAdmin.toString(), false]],
129 ],
130 ]);
131
132 }));
133
134 [
135 {mode: 'nft' as const, requiredPallets: []},
136 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
137 ].map(testCase =>
138 itEth.ifWithPallets(`[${testCase.mode}] Set and get multiple token property permissions as admin`, testCase.requiredPallets, async({helper}) => {
139 const owner = await helper.eth.createAccountWithBalance(donor);
140 const caller = await helper.ethCrossAccount.createAccountWithBalance(donor);
141
142 const {collectionId, collectionAddress} = await helper.eth.createCollection(testCase.mode, owner, 'A', 'B', 'C');
143 const collection = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);
144 await collection.methods.addCollectionAdminCross(caller).send({from: owner});
145
146 await collection.methods.setTokenPropertyPermissions([
147 ['testKey_0', [
148 [EthTokenPermissions.Mutable, true],
149 [EthTokenPermissions.TokenOwner, true],
150 [EthTokenPermissions.CollectionAdmin, true]],
151 ],
152 ['testKey_1', [
153 [EthTokenPermissions.Mutable, true],
154 [EthTokenPermissions.TokenOwner, false],
155 [EthTokenPermissions.CollectionAdmin, true]],
156 ],
157 ['testKey_2', [
158 [EthTokenPermissions.Mutable, false],
159 [EthTokenPermissions.TokenOwner, true],
160 [EthTokenPermissions.CollectionAdmin, false]],
161 ],
162 ]).send({from: caller.eth});
163
164 expect(await helper[testCase.mode].getPropertyPermissions(collectionId)).to.be.deep.equal([
165 {
166 key: 'testKey_0',
167 permission: {mutable: true, tokenOwner: true, collectionAdmin: true},
168 },
169 {
170 key: 'testKey_1',
171 permission: {mutable: true, tokenOwner: false, collectionAdmin: true},
172 },
173 {
174 key: 'testKey_2',
175 permission: {mutable: false, tokenOwner: true, collectionAdmin: false},
176 },
177 ]);
178
179 expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([
180 ['testKey_0', [
181 [EthTokenPermissions.Mutable.toString(), true],
182 [EthTokenPermissions.TokenOwner.toString(), true],
183 [EthTokenPermissions.CollectionAdmin.toString(), true]],
184 ],
185 ['testKey_1', [
186 [EthTokenPermissions.Mutable.toString(), true],
187 [EthTokenPermissions.TokenOwner.toString(), false],
188 [EthTokenPermissions.CollectionAdmin.toString(), true]],
189 ],
190 ['testKey_2', [
191 [EthTokenPermissions.Mutable.toString(), false],
192 [EthTokenPermissions.TokenOwner.toString(), true],
193 [EthTokenPermissions.CollectionAdmin.toString(), false]],
194 ],
195 ]);
196
197 }));
52198
53 [199 [
54 {200 {
302 expect(actualProps).to.deep.eq(expectedProps);448 expect(actualProps).to.deep.eq(expectedProps);
303 }));449 }));
450
451 [
452 {mode: 'nft' as const, requiredPallets: []},
453 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
454 ].map(testCase =>
455 itEth.ifWithPallets(`[${testCase.mode}] Cant set token property permissions as non owner or admin`, testCase.requiredPallets, async({helper}) => {
456 const owner = await helper.eth.createAccountWithBalance(donor);
457 const caller = await helper.eth.createAccountWithBalance(donor);
458
459 const {collectionAddress} = await helper.eth.createCollection(testCase.mode, owner, 'A', 'B', 'C');
460 const collection = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);
461
462 await expect(collection.methods.setTokenPropertyPermissions([
463 ['testKey_0', [
464 [EthTokenPermissions.Mutable, true],
465 [EthTokenPermissions.TokenOwner, true],
466 [EthTokenPermissions.CollectionAdmin, true]],
467 ],
468 ]).call({from: caller})).to.be.rejectedWith('NoPermission');
469 }));
470
471 [
472 {mode: 'nft' as const, requiredPallets: []},
473 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
474 ].map(testCase =>
475 itEth.ifWithPallets(`[${testCase.mode}] Cant set token property permissions with invalid character`, testCase.requiredPallets, async({helper}) => {
476 const owner = await helper.eth.createAccountWithBalance(donor);
477
478 const {collectionAddress} = await helper.eth.createCollection(testCase.mode, owner, 'A', 'B', 'C');
479 const collection = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);
480
481 await expect(collection.methods.setTokenPropertyPermissions([
482 // "Space" is invalid character
483 ['testKey 0', [
484 [EthTokenPermissions.Mutable, true],
485 [EthTokenPermissions.TokenOwner, true],
486 [EthTokenPermissions.CollectionAdmin, true]],
487 ],
488 ]).call({from: owner})).to.be.rejectedWith('InvalidCharacterInPropertyKey');
489 }));
490
304});491});
305492
modifiedtests/src/eth/util/playgrounds/types.tsdiffbeforeafterboth
2020
21export type EthProperty = string[];21export type EthProperty = string[];
2222
2323export enum EthTokenPermissions {
24 Mutable,
25 TokenOwner,
26 CollectionAdmin
27}