git.delta.rocks / unique-network / refs/commits / 0d4bed32f053

difftreelog

Merge pull request #574 from UniqueNetwork/feature/eth_passthrought

Yaroslav Bolyukin2022-09-14parents: #a711701 #d8d2ace.patch.diff
in: master
Feature/eth passthrought

19 files changed

modifiedpallets/common/src/erc.rsdiffbeforeafterboth
20 solidity_interface, solidity, ToLog,20 solidity_interface, solidity, ToLog,
21 types::*,21 types::*,
22 execution::{Result, Error},22 execution::{Result, Error},
23 weight,
23};24};
24pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};25pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};
25use pallet_evm_coder_substrate::dispatch_to_evm;26use pallet_evm_coder_substrate::dispatch_to_evm;
31use alloc::format;32use alloc::format;
3233
33use crate::{34use crate::{
34 Pallet, CollectionHandle, Config, CollectionProperties,35 Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,
35 eth::{convert_cross_account_to_uint256, convert_uint256_to_cross_account},36 eth::{
37 convert_cross_account_to_uint256, convert_uint256_to_cross_account,
38 convert_cross_account_to_tuple,
39 },
40 weights::WeightInfo,
36};41};
3742
38/// Events for ethereum collection helper.43/// Events for ethereum collection helper.
69 ///74 ///
70 /// @param key Property key.75 /// @param key Property key.
71 /// @param value Propery value.76 /// @param value Propery value.
77 #[weight(<SelfWeightOf<T>>::set_collection_properties(1))]
72 fn set_collection_property(78 fn set_collection_property(
73 &mut self,79 &mut self,
74 caller: caller,80 caller: caller,
88 /// Delete collection property.94 /// Delete collection property.
89 ///95 ///
90 /// @param key Property key.96 /// @param key Property key.
97 #[weight(<SelfWeightOf<T>>::delete_collection_properties(1))]
91 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {98 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {
99 self.consume_store_reads_and_writes(1, 1)?;
100
92 let caller = T::CrossAccountId::from_eth(caller);101 let caller = T::CrossAccountId::from_eth(caller);
93 let key = <Vec<u8>>::from(key)102 let key = <Vec<u8>>::from(key)
94 .try_into()103 .try_into()
120 ///129 ///
121 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.130 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
122 fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {131 fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {
132 self.consume_store_reads_and_writes(1, 1)?;
133
123 check_is_owner_or_admin(caller, self)?;134 check_is_owner_or_admin(caller, self)?;
124135
125 let sponsor = T::CrossAccountId::from_eth(sponsor);136 let sponsor = T::CrossAccountId::from_eth(sponsor);
138 caller: caller,149 caller: caller,
139 sponsor: uint256,150 sponsor: uint256,
140 ) -> Result<void> {151 ) -> Result<void> {
152 self.consume_store_reads_and_writes(1, 1)?;
153
141 check_is_owner_or_admin(caller, self)?;154 check_is_owner_or_admin(caller, self)?;
142155
143 let sponsor = convert_uint256_to_cross_account::<T>(sponsor);156 let sponsor = convert_uint256_to_cross_account::<T>(sponsor);
146 save(self)159 save(self)
147 }160 }
148161
149 // /// Whether there is a pending sponsor.162 /// Whether there is a pending sponsor.
150 fn has_collection_pending_sponsor(&self) -> Result<bool> {163 fn has_collection_pending_sponsor(&self) -> Result<bool> {
151 Ok(matches!(164 Ok(matches!(
152 self.collection.sponsorship,165 self.collection.sponsorship,
158 ///171 ///
159 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.172 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.
160 fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {173 fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {
174 self.consume_store_writes(1)?;
175
161 let caller = T::CrossAccountId::from_eth(caller);176 let caller = T::CrossAccountId::from_eth(caller);
162 if !self177 if !self
163 .confirm_sponsorship(caller.as_sub())178 .confirm_sponsorship(caller.as_sub())
170185
171 /// Remove collection sponsor.186 /// Remove collection sponsor.
172 fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {187 fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {
188 self.consume_store_reads_and_writes(1, 1)?;
173 check_is_owner_or_admin(caller, self)?;189 check_is_owner_or_admin(caller, self)?;
174 self.remove_sponsor().map_err(dispatch_to_evm::<T>)?;190 self.remove_sponsor().map_err(dispatch_to_evm::<T>)?;
175 save(self)191 save(self)
206 /// @param value Value of the limit.222 /// @param value Value of the limit.
207 #[solidity(rename_selector = "setCollectionLimit")]223 #[solidity(rename_selector = "setCollectionLimit")]
208 fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {224 fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {
225 self.consume_store_reads_and_writes(1, 1)?;
226
209 check_is_owner_or_admin(caller, self)?;227 check_is_owner_or_admin(caller, self)?;
210 let mut limits = self.limits.clone();228 let mut limits = self.limits.clone();
211229
249 /// @param value Value of the limit.267 /// @param value Value of the limit.
250 #[solidity(rename_selector = "setCollectionLimit")]268 #[solidity(rename_selector = "setCollectionLimit")]
251 fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {269 fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {
270 self.consume_store_reads_and_writes(1, 1)?;
271
252 check_is_owner_or_admin(caller, self)?;272 check_is_owner_or_admin(caller, self)?;
253 let mut limits = self.limits.clone();273 let mut limits = self.limits.clone();
254274
275 }295 }
276296
277 /// Get contract address.297 /// Get contract address.
278 fn contract_address(&self, _caller: caller) -> Result<address> {298 fn contract_address(&self) -> Result<address> {
279 Ok(crate::eth::collection_id_to_address(self.id))299 Ok(crate::eth::collection_id_to_address(self.id))
280 }300 }
281301
286 caller: caller,306 caller: caller,
287 new_admin: uint256,307 new_admin: uint256,
288 ) -> Result<void> {308 ) -> Result<void> {
309 self.consume_store_writes(2)?;
310
289 let caller = T::CrossAccountId::from_eth(caller);311 let caller = T::CrossAccountId::from_eth(caller);
290 let new_admin = convert_uint256_to_cross_account::<T>(new_admin);312 let new_admin = convert_uint256_to_cross_account::<T>(new_admin);
291 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;313 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
299 caller: caller,321 caller: caller,
300 admin: uint256,322 admin: uint256,
301 ) -> Result<void> {323 ) -> Result<void> {
324 self.consume_store_writes(2)?;
325
302 let caller = T::CrossAccountId::from_eth(caller);326 let caller = T::CrossAccountId::from_eth(caller);
303 let admin = convert_uint256_to_cross_account::<T>(admin);327 let admin = convert_uint256_to_cross_account::<T>(admin);
304 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;328 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
308 /// Add collection admin.332 /// Add collection admin.
309 /// @param newAdmin Address of the added administrator.333 /// @param newAdmin Address of the added administrator.
310 fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {334 fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {
335 self.consume_store_writes(2)?;
336
311 let caller = T::CrossAccountId::from_eth(caller);337 let caller = T::CrossAccountId::from_eth(caller);
312 let new_admin = T::CrossAccountId::from_eth(new_admin);338 let new_admin = T::CrossAccountId::from_eth(new_admin);
313 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;339 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
318 ///344 ///
319 /// @param admin Address of the removed administrator.345 /// @param admin Address of the removed administrator.
320 fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {346 fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {
347 self.consume_store_writes(2)?;
348
321 let caller = T::CrossAccountId::from_eth(caller);349 let caller = T::CrossAccountId::from_eth(caller);
322 let admin = T::CrossAccountId::from_eth(admin);350 let admin = T::CrossAccountId::from_eth(admin);
323 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;351 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
329 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'357 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
330 #[solidity(rename_selector = "setCollectionNesting")]358 #[solidity(rename_selector = "setCollectionNesting")]
331 fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {359 fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {
360 self.consume_store_reads_and_writes(1, 1)?;
361
332 check_is_owner_or_admin(caller, self)?;362 check_is_owner_or_admin(caller, self)?;
333363
334 let mut permissions = self.collection.permissions.clone();364 let mut permissions = self.collection.permissions.clone();
358 enable: bool,388 enable: bool,
359 collections: Vec<address>,389 collections: Vec<address>,
360 ) -> Result<void> {390 ) -> Result<void> {
391 self.consume_store_reads_and_writes(1, 1)?;
392
361 if collections.is_empty() {393 if collections.is_empty() {
362 return Err("no addresses provided".into());394 return Err("no addresses provided".into());
363 }395 }
401 /// 0 for Normal433 /// 0 for Normal
402 /// 1 for AllowList434 /// 1 for AllowList
403 fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {435 fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {
436 self.consume_store_reads_and_writes(1, 1)?;
437
404 check_is_owner_or_admin(caller, self)?;438 check_is_owner_or_admin(caller, self)?;
405 let permissions = CollectionPermissions {439 let permissions = CollectionPermissions {
406 access: Some(match mode {440 access: Some(match mode {
420 save(self)454 save(self)
421 }455 }
422456
457 /// Checks that user allowed to operate with collection.
458 ///
459 /// @param user User address to check.
460 fn allowed(&self, user: address) -> Result<bool> {
461 Ok(Pallet::<T>::allowed(
462 self.id,
463 T::CrossAccountId::from_eth(user),
464 ))
465 }
466
423 /// Add the user to the allowed list.467 /// Add the user to the allowed list.
424 ///468 ///
425 /// @param user Address of a trusted user.469 /// @param user Address of a trusted user.
426 fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {470 fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
471 self.consume_store_writes(1)?;
472
427 let caller = T::CrossAccountId::from_eth(caller);473 let caller = T::CrossAccountId::from_eth(caller);
428 let user = T::CrossAccountId::from_eth(user);474 let user = T::CrossAccountId::from_eth(user);
429 <Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;475 <Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
430 Ok(())476 Ok(())
431 }477 }
432478
479 /// Add substrate user to allowed list.
480 ///
481 /// @param user User substrate address.
482 fn add_to_collection_allow_list_substrate(
483 &mut self,
484 caller: caller,
485 user: uint256,
486 ) -> Result<void> {
487 self.consume_store_writes(1)?;
488
489 let caller = T::CrossAccountId::from_eth(caller);
490 let user = convert_uint256_to_cross_account::<T>(user);
491 Pallet::<T>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
492 Ok(())
493 }
494
433 /// Remove the user from the allowed list.495 /// Remove the user from the allowed list.
434 ///496 ///
435 /// @param user Address of a removed user.497 /// @param user Address of a removed user.
436 fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {498 fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
499 self.consume_store_writes(1)?;
500
437 let caller = T::CrossAccountId::from_eth(caller);501 let caller = T::CrossAccountId::from_eth(caller);
438 let user = T::CrossAccountId::from_eth(user);502 let user = T::CrossAccountId::from_eth(user);
439 <Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;503 <Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
440 Ok(())504 Ok(())
441 }505 }
442506
507 /// Remove substrate user from allowed list.
508 ///
509 /// @param user User substrate address.
510 fn remove_from_collection_allow_list_substrate(
511 &mut self,
512 caller: caller,
513 user: uint256,
514 ) -> Result<void> {
515 self.consume_store_writes(1)?;
516
517 let caller = T::CrossAccountId::from_eth(caller);
518 let user = convert_uint256_to_cross_account::<T>(user);
519 Pallet::<T>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
520 Ok(())
521 }
522
443 /// Switch permission for minting.523 /// Switch permission for minting.
444 ///524 ///
445 /// @param mode Enable if "true".525 /// @param mode Enable if "true".
446 fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {526 fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {
527 self.consume_store_reads_and_writes(1, 1)?;
528
447 check_is_owner_or_admin(caller, self)?;529 check_is_owner_or_admin(caller, self)?;
448 let permissions = CollectionPermissions {530 let permissions = CollectionPermissions {
449 mint_mode: Some(mode),531 mint_mode: Some(mode),
481 /// Returns collection type563 /// Returns collection type
482 ///564 ///
483 /// @return `Fungible` or `NFT` or `ReFungible`565 /// @return `Fungible` or `NFT` or `ReFungible`
484 fn unique_collection_type(&mut self) -> Result<string> {566 fn unique_collection_type(&self) -> Result<string> {
485 let mode = match self.collection.mode {567 let mode = match self.collection.mode {
486 CollectionMode::Fungible(_) => "Fungible",568 CollectionMode::Fungible(_) => "Fungible",
487 CollectionMode::NFT => "NFT",569 CollectionMode::NFT => "NFT",
490 Ok(mode.into())572 Ok(mode.into())
491 }573 }
492574
575 /// Get collection owner.
576 ///
577 /// @return Tuble with sponsor address and his substrate mirror.
578 /// If address is canonical then substrate mirror is zero and vice versa.
579 fn collection_owner(&self) -> Result<(address, uint256)> {
580 Ok(convert_cross_account_to_tuple::<T>(
581 &T::CrossAccountId::from_sub(self.owner.clone()),
582 ))
583 }
584
493 /// Changes collection owner to another account585 /// Changes collection owner to another account
494 ///586 ///
495 /// @dev Owner can be changed only by current owner587 /// @dev Owner can be changed only by current owner
496 /// @param newOwner new owner account588 /// @param newOwner new owner account
497 fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {589 fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {
590 self.consume_store_writes(1)?;
591
498 let caller = T::CrossAccountId::from_eth(caller);592 let caller = T::CrossAccountId::from_eth(caller);
499 let new_owner = T::CrossAccountId::from_eth(new_owner);593 let new_owner = T::CrossAccountId::from_eth(new_owner);
500 self.set_owner_internal(caller, new_owner)594 self.set_owner_internal(caller, new_owner)
506 /// @dev Owner can be changed only by current owner600 /// @dev Owner can be changed only by current owner
507 /// @param newOwner new owner substrate account601 /// @param newOwner new owner substrate account
508 fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result<void> {602 fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result<void> {
603 self.consume_store_writes(1)?;
604
509 let caller = T::CrossAccountId::from_eth(caller);605 let caller = T::CrossAccountId::from_eth(caller);
510 let new_owner = convert_uint256_to_cross_account::<T>(new_owner);606 let new_owner = convert_uint256_to_cross_account::<T>(new_owner);
511 self.set_owner_internal(caller, new_owner)607 self.set_owner_internal(caller, new_owner)
512 .map_err(dispatch_to_evm::<T>)608 .map_err(dispatch_to_evm::<T>)
513 }609 }
610
611 // TODO: need implement AbiWriter for &Vec<T>
612 // fn collection_admins(&self) -> Result<Vec<(address, uint256)>> {
613 // let result = pallet_common::IsAdmin::<T>::iter_prefix((self.id,))
614 // .map(|(admin, _)| pallet_common::eth::convert_cross_account_to_tuple::<T>(&admin))
615 // .collect();
616 // Ok(result)
617 // }
514}618}
515619
620/// ### Note
621/// Do not forget to add: `self.consume_store_reads(1)?;`
516fn check_is_owner_or_admin<T: Config>(622fn check_is_owner_or_admin<T: Config>(
517 caller: caller,623 caller: caller,
518 collection: &CollectionHandle<T>,624 collection: &CollectionHandle<T>,
524 Ok(caller)630 Ok(caller)
525}631}
526632
633/// ### Note
634/// Do not forget to add: `self.consume_store_writes(1)?;`
527fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {635fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {
528 // TODO possibly delete for the lack of transaction
529 collection.consume_store_writes(1)?;
530 collection636 collection
531 .check_is_internal()637 .check_is_internal()
532 .map_err(dispatch_to_evm::<T>)?;638 .map_err(dispatch_to_evm::<T>)?;
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
1616
17//! The module contains a number of functions for converting and checking ethereum identifiers.17//! The module contains a number of functions for converting and checking ethereum identifiers.
1818
19use evm_coder::types::uint256;19use evm_coder::types::{uint256, address};
20pub use pallet_evm::account::{Config, CrossAccountId};20pub use pallet_evm::account::{Config, CrossAccountId};
21use sp_core::H160;21use sp_core::H160;
22use up_data_structs::CollectionId;22use up_data_structs::CollectionId;
70 T::CrossAccountId::from_sub(account_id)70 T::CrossAccountId::from_sub(account_id)
71}71}
72
73/// Convert `CrossAccountId` to `(address, uint256)`.
74pub fn convert_cross_account_to_tuple<T: Config>(
75 cross_account_id: &T::CrossAccountId,
76) -> (address, uint256)
77where
78 T::AccountId: AsRef<[u8; 32]>,
79{
80 if cross_account_id.is_canonical_substrate() {
81 let sub = convert_cross_account_to_uint256::<T>(cross_account_id);
82 (Default::default(), sub)
83 } else {
84 let eth = *cross_account_id.as_eth();
85 (eth, Default::default())
86 }
87}
7288
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
112 RmrkBoundedTheme,112 RmrkBoundedTheme,
113 RmrkNftChild,113 RmrkNftChild,
114 CollectionPermissions,114 CollectionPermissions,
115 SchemaVersion,
116};115};
117116
118pub use pallet::*;117pub use pallet::*;
202 ))201 ))
203 }202 }
203
204 /// Consume gas for reading and writing.
205 pub fn consume_store_reads_and_writes(
206 &self,
207 reads: u64,
208 writes: u64,
209 ) -> evm_coder::execution::Result<()> {
210 let weight = <T as frame_system::Config>::DbWeight::get();
211 let reads = weight.read.saturating_mul(reads);
212 let writes = weight.read.saturating_mul(writes);
213 self.recorder
214 .consume_gas(T::GasWeightMapping::weight_to_gas(
215 reads.saturating_add(writes),
216 ))
217 }
204218
205 /// Save collection to storage.219 /// Save collection to storage.
206 pub fn save(&self) -> DispatchResult {220 pub fn save(&self) -> DispatchResult {
310 }324 }
311325
312 /// Changes collection owner to another account326 /// Changes collection owner to another account
327 /// #### Store read/writes
328 /// 1 writes
313 fn set_owner_internal(329 fn set_owner_internal(
314 &mut self,330 &mut self,
315 caller: T::CrossAccountId,331 caller: T::CrossAccountId,
1292 }1308 }
12931309
1294 /// Toggle `user` participation in the `collection`'s allow list.1310 /// Toggle `user` participation in the `collection`'s allow list.
1311 /// #### Store read/writes
1312 /// 1 writes
1295 pub fn toggle_allowlist(1313 pub fn toggle_allowlist(
1296 collection: &CollectionHandle<T>,1314 collection: &CollectionHandle<T>,
1297 sender: &T::CrossAccountId,1315 sender: &T::CrossAccountId,
1312 }1330 }
13131331
1314 /// Toggle `user` participation in the `collection`'s admin list.1332 /// Toggle `user` participation in the `collection`'s admin list.
1333 /// #### Store read/writes
1334 /// 2 writes
1315 pub fn toggle_admin(1335 pub fn toggle_admin(
1316 collection: &CollectionHandle<T>,1336 collection: &CollectionHandle<T>,
1317 sender: &T::CrossAccountId,1337 sender: &T::CrossAccountId,
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
172 fn get_sponsor(&self, contract_address: address) -> Result<(address, uint256)> {172 fn get_sponsor(&self, contract_address: address) -> Result<(address, uint256)> {
173 let sponsor =173 let sponsor =
174 Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?;174 Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?;
175 let result: (address, uint256) = if sponsor.is_canonical_substrate() {
176 let sponsor = pallet_common::eth::convert_cross_account_to_uint256::<T>(&sponsor);175 Ok(pallet_common::eth::convert_cross_account_to_tuple::<T>(
177 (Default::default(), sponsor)176 &sponsor,
178 } else {177 ))
179 let sponsor = *sponsor.as_eth();
180 (sponsor, Default::default())
181 };
182 Ok(result)
183 }178 }
184179
185 /// Check tat contract has confirmed sponsor.180 /// Check tat contract has confirmed sponsor.
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
22}22}
2323
24/// @title A contract that allows you to work with collections.24/// @title A contract that allows you to work with collections.
25/// @dev the ERC-165 identifier for this interface is 0xe54be64025/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
26contract Collection is Dummy, ERC165 {26contract Collection is Dummy, ERC165 {
27 /// Set collection property.27 /// Set collection property.
28 ///28 ///
255 dummy = 0;255 dummy = 0;
256 }256 }
257
258 /// Checks that user allowed to operate with collection.
259 ///
260 /// @param user User address to check.
261 /// @dev EVM selector for this function is: 0xd63a8e11,
262 /// or in textual repr: allowed(address)
263 function allowed(address user) public view returns (bool) {
264 require(false, stub_error);
265 user;
266 dummy;
267 return false;
268 }
257269
258 /// Add the user to the allowed list.270 /// Add the user to the allowed list.
259 ///271 ///
266 dummy = 0;278 dummy = 0;
267 }279 }
280
281 /// Add substrate user to allowed list.
282 ///
283 /// @param user User substrate address.
284 /// @dev EVM selector for this function is: 0xd06ad267,
285 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
286 function addToCollectionAllowListSubstrate(uint256 user) public {
287 require(false, stub_error);
288 user;
289 dummy = 0;
290 }
268291
269 /// Remove the user from the allowed list.292 /// Remove the user from the allowed list.
270 ///293 ///
277 dummy = 0;300 dummy = 0;
278 }301 }
302
303 /// Remove substrate user from allowed list.
304 ///
305 /// @param user User substrate address.
306 /// @dev EVM selector for this function is: 0xa31913ed,
307 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
308 function removeFromCollectionAllowListSubstrate(uint256 user) public {
309 require(false, stub_error);
310 user;
311 dummy = 0;
312 }
279313
280 /// Switch permission for minting.314 /// Switch permission for minting.
281 ///315 ///
325 return "";359 return "";
326 }360 }
361
362 /// Get collection owner.
363 ///
364 /// @return Tuble with sponsor address and his substrate mirror.
365 /// If address is canonical then substrate mirror is zero and vice versa.
366 /// @dev EVM selector for this function is: 0xdf727d3b,
367 /// or in textual repr: collectionOwner()
368 function collectionOwner() public view returns (Tuple6 memory) {
369 require(false, stub_error);
370 dummy;
371 return Tuple6(0x0000000000000000000000000000000000000000, 0);
372 }
327373
328 /// Changes collection owner to another account374 /// Changes collection owner to another account
329 ///375 ///
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
99}99}
100100
101/// @title A contract that allows you to work with collections.101/// @title A contract that allows you to work with collections.
102/// @dev the ERC-165 identifier for this interface is 0xe54be640102/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
103contract Collection is Dummy, ERC165 {103contract Collection is Dummy, ERC165 {
104 /// Set collection property.104 /// Set collection property.
105 ///105 ///
332 dummy = 0;332 dummy = 0;
333 }333 }
334
335 /// Checks that user allowed to operate with collection.
336 ///
337 /// @param user User address to check.
338 /// @dev EVM selector for this function is: 0xd63a8e11,
339 /// or in textual repr: allowed(address)
340 function allowed(address user) public view returns (bool) {
341 require(false, stub_error);
342 user;
343 dummy;
344 return false;
345 }
334346
335 /// Add the user to the allowed list.347 /// Add the user to the allowed list.
336 ///348 ///
343 dummy = 0;355 dummy = 0;
344 }356 }
357
358 /// Add substrate user to allowed list.
359 ///
360 /// @param user User substrate address.
361 /// @dev EVM selector for this function is: 0xd06ad267,
362 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
363 function addToCollectionAllowListSubstrate(uint256 user) public {
364 require(false, stub_error);
365 user;
366 dummy = 0;
367 }
345368
346 /// Remove the user from the allowed list.369 /// Remove the user from the allowed list.
347 ///370 ///
354 dummy = 0;377 dummy = 0;
355 }378 }
379
380 /// Remove substrate user from allowed list.
381 ///
382 /// @param user User substrate address.
383 /// @dev EVM selector for this function is: 0xa31913ed,
384 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
385 function removeFromCollectionAllowListSubstrate(uint256 user) public {
386 require(false, stub_error);
387 user;
388 dummy = 0;
389 }
356390
357 /// Switch permission for minting.391 /// Switch permission for minting.
358 ///392 ///
402 return "";436 return "";
403 }437 }
438
439 /// Get collection owner.
440 ///
441 /// @return Tuble with sponsor address and his substrate mirror.
442 /// If address is canonical then substrate mirror is zero and vice versa.
443 /// @dev EVM selector for this function is: 0xdf727d3b,
444 /// or in textual repr: collectionOwner()
445 function collectionOwner() public view returns (Tuple17 memory) {
446 require(false, stub_error);
447 dummy;
448 return Tuple17(0x0000000000000000000000000000000000000000, 0);
449 }
404450
405 /// Changes collection owner to another account451 /// Changes collection owner to another account
406 ///452 ///
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
99}99}
100100
101/// @title A contract that allows you to work with collections.101/// @title A contract that allows you to work with collections.
102/// @dev the ERC-165 identifier for this interface is 0xe54be640102/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
103contract Collection is Dummy, ERC165 {103contract Collection is Dummy, ERC165 {
104 /// Set collection property.104 /// Set collection property.
105 ///105 ///
332 dummy = 0;332 dummy = 0;
333 }333 }
334
335 /// Checks that user allowed to operate with collection.
336 ///
337 /// @param user User address to check.
338 /// @dev EVM selector for this function is: 0xd63a8e11,
339 /// or in textual repr: allowed(address)
340 function allowed(address user) public view returns (bool) {
341 require(false, stub_error);
342 user;
343 dummy;
344 return false;
345 }
334346
335 /// Add the user to the allowed list.347 /// Add the user to the allowed list.
336 ///348 ///
343 dummy = 0;355 dummy = 0;
344 }356 }
357
358 /// Add substrate user to allowed list.
359 ///
360 /// @param user User substrate address.
361 /// @dev EVM selector for this function is: 0xd06ad267,
362 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
363 function addToCollectionAllowListSubstrate(uint256 user) public {
364 require(false, stub_error);
365 user;
366 dummy = 0;
367 }
345368
346 /// Remove the user from the allowed list.369 /// Remove the user from the allowed list.
347 ///370 ///
354 dummy = 0;377 dummy = 0;
355 }378 }
379
380 /// Remove substrate user from allowed list.
381 ///
382 /// @param user User substrate address.
383 /// @dev EVM selector for this function is: 0xa31913ed,
384 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
385 function removeFromCollectionAllowListSubstrate(uint256 user) public {
386 require(false, stub_error);
387 user;
388 dummy = 0;
389 }
356390
357 /// Switch permission for minting.391 /// Switch permission for minting.
358 ///392 ///
402 return "";436 return "";
403 }437 }
438
439 /// Get collection owner.
440 ///
441 /// @return Tuble with sponsor address and his substrate mirror.
442 /// If address is canonical then substrate mirror is zero and vice versa.
443 /// @dev EVM selector for this function is: 0xdf727d3b,
444 /// or in textual repr: collectionOwner()
445 function collectionOwner() public view returns (Tuple17 memory) {
446 require(false, stub_error);
447 dummy;
448 return Tuple17(0x0000000000000000000000000000000000000000, 0);
449 }
404450
405 /// Changes collection owner to another account451 /// Changes collection owner to another account
406 ///452 ///
modifiedtests/src/eth/allowlist.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';
17import {expect} from 'chai';18import {expect} from 'chai';
19import {isAllowlisted, normalizeAccountId} from '../util/helpers';
18import {contractHelpers, createEthAccountWithBalance, deployFlipper, itWeb3} from './util/helpers';20import {
21 contractHelpers,
22 createEthAccount,
23 createEthAccountWithBalance,
24 deployFlipper,
25 evmCollection,
26 evmCollectionHelpers,
27 getCollectionAddressFromResult,
28 itWeb3,
29} from './util/helpers';
30import {itEth, usingEthPlaygrounds} from './util/playgrounds';
1931
20describe('EVM allowlist', () => {32describe('EVM contract allowlist', () => {
21 itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {33 itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {
22 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);34 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
23 const flipper = await deployFlipper(web3, owner);35 const flipper = await deployFlipper(web3, owner);
59 });71 });
60});72});
73
74describe('EVM collection allowlist', () => {
75 let donor: IKeyringPair;
76
77 before(async function() {
78 await usingEthPlaygrounds(async (_helper, privateKey) => {
79 donor = privateKey('//Alice');
80 });
81 });
82
83 itEth('Collection allowlist can be added and removed by [eth] address', async ({helper}) => {
84 const owner = await helper.eth.createAccountWithBalance(donor);
85 const user = helper.eth.createAccount();
86
87 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
88 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
89
90 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
91 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
92 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
93
94 await collectionEvm.methods.removeFromCollectionAllowList(user).send({from: owner});
95 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
96 });
97
98 itEth('Collection allowlist can be added and removed by [sub] address', async ({helper}) => {
99 const owner = await helper.eth.createAccountWithBalance(donor);
100 const user = donor;
101
102 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
103 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
104
105 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
106 await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
107 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
108
109 await collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
110 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
111 });
112
113 itEth('Collection allowlist can not be add and remove [eth] address by not owner', async ({helper}) => {
114 const owner = await helper.eth.createAccountWithBalance(donor);
115 const notOwner = await helper.eth.createAccountWithBalance(donor);
116 const user = helper.eth.createAccount();
117
118 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
119 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
120
121 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
122 await expect(collectionEvm.methods.addToCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');
123 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
124 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
125
126 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
127 await expect(collectionEvm.methods.removeFromCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');
128 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
129 });
130
131 itEth('Collection allowlist can not be add and remove [sub] address by not owner', async ({helper}) => {
132 const owner = await helper.eth.createAccountWithBalance(donor);
133 const notOwner = await helper.eth.createAccountWithBalance(donor);
134 const user = donor;
135
136 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
137 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
138
139 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
140 await expect(collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');
141 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
142 await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
143
144 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
145 await expect(collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');
146 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
147 });
148});
61149
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
13}13}
1414
15/// @title A contract that allows you to work with collections.15/// @title A contract that allows you to work with collections.
16/// @dev the ERC-165 identifier for this interface is 0xe54be64016/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
17interface Collection is Dummy, ERC165 {17interface Collection is Dummy, ERC165 {
18 /// Set collection property.18 /// Set collection property.
19 ///19 ///
164 /// or in textual repr: setCollectionAccess(uint8)164 /// or in textual repr: setCollectionAccess(uint8)
165 function setCollectionAccess(uint8 mode) external;165 function setCollectionAccess(uint8 mode) external;
166
167 /// Checks that user allowed to operate with collection.
168 ///
169 /// @param user User address to check.
170 /// @dev EVM selector for this function is: 0xd63a8e11,
171 /// or in textual repr: allowed(address)
172 function allowed(address user) external view returns (bool);
166173
167 /// Add the user to the allowed list.174 /// Add the user to the allowed list.
168 ///175 ///
171 /// or in textual repr: addToCollectionAllowList(address)178 /// or in textual repr: addToCollectionAllowList(address)
172 function addToCollectionAllowList(address user) external;179 function addToCollectionAllowList(address user) external;
180
181 /// Add substrate user to allowed list.
182 ///
183 /// @param user User substrate address.
184 /// @dev EVM selector for this function is: 0xd06ad267,
185 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
186 function addToCollectionAllowListSubstrate(uint256 user) external;
173187
174 /// Remove the user from the allowed list.188 /// Remove the user from the allowed list.
175 ///189 ///
178 /// or in textual repr: removeFromCollectionAllowList(address)192 /// or in textual repr: removeFromCollectionAllowList(address)
179 function removeFromCollectionAllowList(address user) external;193 function removeFromCollectionAllowList(address user) external;
194
195 /// Remove substrate user from allowed list.
196 ///
197 /// @param user User substrate address.
198 /// @dev EVM selector for this function is: 0xa31913ed,
199 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
200 function removeFromCollectionAllowListSubstrate(uint256 user) external;
180201
181 /// Switch permission for minting.202 /// Switch permission for minting.
182 ///203 ///
208 /// or in textual repr: uniqueCollectionType()229 /// or in textual repr: uniqueCollectionType()
209 function uniqueCollectionType() external returns (string memory);230 function uniqueCollectionType() external returns (string memory);
231
232 /// Get collection owner.
233 ///
234 /// @return Tuble with sponsor address and his substrate mirror.
235 /// If address is canonical then substrate mirror is zero and vice versa.
236 /// @dev EVM selector for this function is: 0xdf727d3b,
237 /// or in textual repr: collectionOwner()
238 function collectionOwner() external view returns (Tuple6 memory);
210239
211 /// Changes collection owner to another account240 /// Changes collection owner to another account
212 ///241 ///
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
65}65}
6666
67/// @title A contract that allows you to work with collections.67/// @title A contract that allows you to work with collections.
68/// @dev the ERC-165 identifier for this interface is 0xe54be64068/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
69interface Collection is Dummy, ERC165 {69interface Collection is Dummy, ERC165 {
70 /// Set collection property.70 /// Set collection property.
71 ///71 ///
216 /// or in textual repr: setCollectionAccess(uint8)216 /// or in textual repr: setCollectionAccess(uint8)
217 function setCollectionAccess(uint8 mode) external;217 function setCollectionAccess(uint8 mode) external;
218
219 /// Checks that user allowed to operate with collection.
220 ///
221 /// @param user User address to check.
222 /// @dev EVM selector for this function is: 0xd63a8e11,
223 /// or in textual repr: allowed(address)
224 function allowed(address user) external view returns (bool);
218225
219 /// Add the user to the allowed list.226 /// Add the user to the allowed list.
220 ///227 ///
223 /// or in textual repr: addToCollectionAllowList(address)230 /// or in textual repr: addToCollectionAllowList(address)
224 function addToCollectionAllowList(address user) external;231 function addToCollectionAllowList(address user) external;
232
233 /// Add substrate user to allowed list.
234 ///
235 /// @param user User substrate address.
236 /// @dev EVM selector for this function is: 0xd06ad267,
237 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
238 function addToCollectionAllowListSubstrate(uint256 user) external;
225239
226 /// Remove the user from the allowed list.240 /// Remove the user from the allowed list.
227 ///241 ///
230 /// or in textual repr: removeFromCollectionAllowList(address)244 /// or in textual repr: removeFromCollectionAllowList(address)
231 function removeFromCollectionAllowList(address user) external;245 function removeFromCollectionAllowList(address user) external;
246
247 /// Remove substrate user from allowed list.
248 ///
249 /// @param user User substrate address.
250 /// @dev EVM selector for this function is: 0xa31913ed,
251 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
252 function removeFromCollectionAllowListSubstrate(uint256 user) external;
232253
233 /// Switch permission for minting.254 /// Switch permission for minting.
234 ///255 ///
260 /// or in textual repr: uniqueCollectionType()281 /// or in textual repr: uniqueCollectionType()
261 function uniqueCollectionType() external returns (string memory);282 function uniqueCollectionType() external returns (string memory);
283
284 /// Get collection owner.
285 ///
286 /// @return Tuble with sponsor address and his substrate mirror.
287 /// If address is canonical then substrate mirror is zero and vice versa.
288 /// @dev EVM selector for this function is: 0xdf727d3b,
289 /// or in textual repr: collectionOwner()
290 function collectionOwner() external view returns (Tuple17 memory);
262291
263 /// Changes collection owner to another account292 /// Changes collection owner to another account
264 ///293 ///
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
65}65}
6666
67/// @title A contract that allows you to work with collections.67/// @title A contract that allows you to work with collections.
68/// @dev the ERC-165 identifier for this interface is 0xe54be64068/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
69interface Collection is Dummy, ERC165 {69interface Collection is Dummy, ERC165 {
70 /// Set collection property.70 /// Set collection property.
71 ///71 ///
216 /// or in textual repr: setCollectionAccess(uint8)216 /// or in textual repr: setCollectionAccess(uint8)
217 function setCollectionAccess(uint8 mode) external;217 function setCollectionAccess(uint8 mode) external;
218
219 /// Checks that user allowed to operate with collection.
220 ///
221 /// @param user User address to check.
222 /// @dev EVM selector for this function is: 0xd63a8e11,
223 /// or in textual repr: allowed(address)
224 function allowed(address user) external view returns (bool);
218225
219 /// Add the user to the allowed list.226 /// Add the user to the allowed list.
220 ///227 ///
223 /// or in textual repr: addToCollectionAllowList(address)230 /// or in textual repr: addToCollectionAllowList(address)
224 function addToCollectionAllowList(address user) external;231 function addToCollectionAllowList(address user) external;
232
233 /// Add substrate user to allowed list.
234 ///
235 /// @param user User substrate address.
236 /// @dev EVM selector for this function is: 0xd06ad267,
237 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
238 function addToCollectionAllowListSubstrate(uint256 user) external;
225239
226 /// Remove the user from the allowed list.240 /// Remove the user from the allowed list.
227 ///241 ///
230 /// or in textual repr: removeFromCollectionAllowList(address)244 /// or in textual repr: removeFromCollectionAllowList(address)
231 function removeFromCollectionAllowList(address user) external;245 function removeFromCollectionAllowList(address user) external;
246
247 /// Remove substrate user from allowed list.
248 ///
249 /// @param user User substrate address.
250 /// @dev EVM selector for this function is: 0xa31913ed,
251 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
252 function removeFromCollectionAllowListSubstrate(uint256 user) external;
232253
233 /// Switch permission for minting.254 /// Switch permission for minting.
234 ///255 ///
260 /// or in textual repr: uniqueCollectionType()281 /// or in textual repr: uniqueCollectionType()
261 function uniqueCollectionType() external returns (string memory);282 function uniqueCollectionType() external returns (string memory);
283
284 /// Get collection owner.
285 ///
286 /// @return Tuble with sponsor address and his substrate mirror.
287 /// If address is canonical then substrate mirror is zero and vice versa.
288 /// @dev EVM selector for this function is: 0xdf727d3b,
289 /// or in textual repr: collectionOwner()
290 function collectionOwner() external view returns (Tuple17 memory);
262291
263 /// Changes collection owner to another account292 /// Changes collection owner to another account
264 ///293 ///
modifiedtests/src/eth/fungibleAbi.jsondiffbeforeafterboth
76 "stateMutability": "nonpayable",76 "stateMutability": "nonpayable",
77 "type": "function"77 "type": "function"
78 },78 },
79 {
80 "inputs": [
81 { "internalType": "uint256", "name": "user", "type": "uint256" }
82 ],
83 "name": "addToCollectionAllowListSubstrate",
84 "outputs": [],
85 "stateMutability": "nonpayable",
86 "type": "function"
87 },
79 {88 {
80 "inputs": [89 "inputs": [
81 { "internalType": "address", "name": "owner", "type": "address" },90 { "internalType": "address", "name": "owner", "type": "address" },
86 "stateMutability": "view",95 "stateMutability": "view",
87 "type": "function"96 "type": "function"
88 },97 },
98 {
99 "inputs": [
100 { "internalType": "address", "name": "user", "type": "address" }
101 ],
102 "name": "allowed",
103 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
104 "stateMutability": "view",
105 "type": "function"
106 },
89 {107 {
90 "inputs": [108 "inputs": [
91 { "internalType": "address", "name": "spender", "type": "address" },109 { "internalType": "address", "name": "spender", "type": "address" },
115 "stateMutability": "nonpayable",133 "stateMutability": "nonpayable",
116 "type": "function"134 "type": "function"
117 },135 },
136 {
137 "inputs": [],
138 "name": "collectionOwner",
139 "outputs": [
140 {
141 "components": [
142 { "internalType": "address", "name": "field_0", "type": "address" },
143 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
144 ],
145 "internalType": "struct Tuple6",
146 "name": "",
147 "type": "tuple"
148 }
149 ],
150 "stateMutability": "view",
151 "type": "function"
152 },
118 {153 {
119 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],154 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
120 "name": "collectionProperty",155 "name": "collectionProperty",
260 "stateMutability": "nonpayable",295 "stateMutability": "nonpayable",
261 "type": "function"296 "type": "function"
262 },297 },
298 {
299 "inputs": [
300 { "internalType": "uint256", "name": "user", "type": "uint256" }
301 ],
302 "name": "removeFromCollectionAllowListSubstrate",
303 "outputs": [],
304 "stateMutability": "nonpayable",
305 "type": "function"
306 },
263 {307 {
264 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],308 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
265 "name": "setCollectionAccess",309 "name": "setCollectionAccess",
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
107 "stateMutability": "nonpayable",107 "stateMutability": "nonpayable",
108 "type": "function"108 "type": "function"
109 },109 },
110 {
111 "inputs": [
112 { "internalType": "uint256", "name": "user", "type": "uint256" }
113 ],
114 "name": "addToCollectionAllowListSubstrate",
115 "outputs": [],
116 "stateMutability": "nonpayable",
117 "type": "function"
118 },
119 {
120 "inputs": [
121 { "internalType": "address", "name": "user", "type": "address" }
122 ],
123 "name": "allowed",
124 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
125 "stateMutability": "view",
126 "type": "function"
127 },
110 {128 {
111 "inputs": [129 "inputs": [
112 { "internalType": "address", "name": "approved", "type": "address" },130 { "internalType": "address", "name": "approved", "type": "address" },
145 "stateMutability": "nonpayable",163 "stateMutability": "nonpayable",
146 "type": "function"164 "type": "function"
147 },165 },
166 {
167 "inputs": [],
168 "name": "collectionOwner",
169 "outputs": [
170 {
171 "components": [
172 { "internalType": "address", "name": "field_0", "type": "address" },
173 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
174 ],
175 "internalType": "struct Tuple17",
176 "name": "",
177 "type": "tuple"
178 }
179 ],
180 "stateMutability": "view",
181 "type": "function"
182 },
148 {183 {
149 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],184 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
150 "name": "collectionProperty",185 "name": "collectionProperty",
374 "stateMutability": "nonpayable",409 "stateMutability": "nonpayable",
375 "type": "function"410 "type": "function"
376 },411 },
412 {
413 "inputs": [
414 { "internalType": "uint256", "name": "user", "type": "uint256" }
415 ],
416 "name": "removeFromCollectionAllowListSubstrate",
417 "outputs": [],
418 "stateMutability": "nonpayable",
419 "type": "function"
420 },
377 {421 {
378 "inputs": [422 "inputs": [
379 { "internalType": "address", "name": "from", "type": "address" },423 { "internalType": "address", "name": "from", "type": "address" },
modifiedtests/src/eth/reFungibleAbi.jsondiffbeforeafterboth
107 "stateMutability": "nonpayable",107 "stateMutability": "nonpayable",
108 "type": "function"108 "type": "function"
109 },109 },
110 {
111 "inputs": [
112 { "internalType": "uint256", "name": "user", "type": "uint256" }
113 ],
114 "name": "addToCollectionAllowListSubstrate",
115 "outputs": [],
116 "stateMutability": "nonpayable",
117 "type": "function"
118 },
119 {
120 "inputs": [
121 { "internalType": "address", "name": "user", "type": "address" }
122 ],
123 "name": "allowed",
124 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
125 "stateMutability": "view",
126 "type": "function"
127 },
110 {128 {
111 "inputs": [129 "inputs": [
112 { "internalType": "address", "name": "approved", "type": "address" },130 { "internalType": "address", "name": "approved", "type": "address" },
145 "stateMutability": "nonpayable",163 "stateMutability": "nonpayable",
146 "type": "function"164 "type": "function"
147 },165 },
166 {
167 "inputs": [],
168 "name": "collectionOwner",
169 "outputs": [
170 {
171 "components": [
172 { "internalType": "address", "name": "field_0", "type": "address" },
173 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
174 ],
175 "internalType": "struct Tuple17",
176 "name": "",
177 "type": "tuple"
178 }
179 ],
180 "stateMutability": "view",
181 "type": "function"
182 },
148 {183 {
149 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],184 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
150 "name": "collectionProperty",185 "name": "collectionProperty",
374 "stateMutability": "nonpayable",409 "stateMutability": "nonpayable",
375 "type": "function"410 "type": "function"
376 },411 },
412 {
413 "inputs": [
414 { "internalType": "uint256", "name": "user", "type": "uint256" }
415 ],
416 "name": "removeFromCollectionAllowListSubstrate",
417 "outputs": [],
418 "stateMutability": "nonpayable",
419 "type": "function"
420 },
377 {421 {
378 "inputs": [422 "inputs": [
379 { "internalType": "address", "name": "from", "type": "address" },423 { "internalType": "address", "name": "from", "type": "address" },
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
1651 });1651 });
1652}1652}
16531653
1654export async function isAllowlisted(api: ApiPromise, collectionId: number, address: string | CrossAccountId) {1654export async function isAllowlisted(api: ApiPromise, collectionId: number, address: string | CrossAccountId | IKeyringPair) {
1655 return (await api.rpc.unique.allowed(collectionId, normalizeAccountId(address))).toJSON();1655 return (await api.rpc.unique.allowed(collectionId, normalizeAccountId(address))).toJSON();
1656}1656}
16571657
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
729 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');729 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');
730 }730 }
731
732 /**
733 * Check if user is in allow list.
734 *
735 * @param collectionId ID of collection
736 * @param user Account to check
737 * @example await getAdmins(1)
738 * @returns is user in allow list
739 */
740 async allowed(collectionId: number, user: ICrossAccountId): Promise<boolean> {
741 return (await this.helper.callRpc('api.rpc.unique.allowed', [collectionId, user])).toJSON();
742 }
731743
732 /**744 /**
733 * Adds an address to allow list745 * Adds an address to allow list