difftreelog
Merge pull request #574 from UniqueNetwork/feature/eth_passthrought
in: master
Feature/eth passthrought
19 files changed
pallets/common/src/erc.rsdiffbeforeafterboth20 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;323333use 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};374238/// 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)?;10092 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)?;133123 check_is_owner_or_admin(caller, self)?;134 check_is_owner_or_admin(caller, self)?;124135125 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)?;153141 check_is_owner_or_admin(caller, self)?;154 check_is_owner_or_admin(caller, self)?;142155143 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 }148161149 // /// 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)?;175161 let caller = T::CrossAccountId::from_eth(caller);176 let caller = T::CrossAccountId::from_eth(caller);162 if !self177 if !self163 .confirm_sponsorship(caller.as_sub())178 .confirm_sponsorship(caller.as_sub())170185171 /// 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)?;226209 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();211229249 /// @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)?;271252 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();254274275 }295 }276296277 /// 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 }281301286 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)?;310289 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)?;325302 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)?;336311 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)?;348321 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)?;361332 check_is_owner_or_admin(caller, self)?;362 check_is_owner_or_admin(caller, self)?;333363334 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)?;392361 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 Normal402 /// 1 for AllowList434 /// 1 for AllowList403 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)?;437404 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 }422456457 /// 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 }466423 /// 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)?;472427 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 }432478479 /// 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)?;488489 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 }494433 /// 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)?;500437 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 }442506507 /// 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)?;516517 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 }522443 /// 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)?;528447 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 type482 ///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 }492574575 /// 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 }584493 /// Changes collection owner to another account585 /// Changes collection owner to another account494 ///586 ///495 /// @dev Owner can be changed only by current owner587 /// @dev Owner can be changed only by current owner496 /// @param newOwner new owner account588 /// @param newOwner new owner account497 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)?;591498 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 owner507 /// @param newOwner new owner substrate account601 /// @param newOwner new owner substrate account508 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)?;604509 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 }610611 // 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}515619620/// ### Note621/// 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}526632633/// ### Note634/// 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 transaction529 collection.consume_store_writes(1)?;530 collection636 collection531 .check_is_internal()637 .check_is_internal()532 .map_err(dispatch_to_evm::<T>)?;638 .map_err(dispatch_to_evm::<T>)?;pallets/common/src/eth.rsdiffbeforeafterboth161617//! 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.181819use 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}7273/// Convert `CrossAccountId` to `(address, uint256)`.74pub fn convert_cross_account_to_tuple<T: Config>(75 cross_account_id: &T::CrossAccountId,76) -> (address, uint256)77where78 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}7288pallets/common/src/lib.rsdiffbeforeafterboth112 RmrkBoundedTheme,112 RmrkBoundedTheme,113 RmrkNftChild,113 RmrkNftChild,114 CollectionPermissions,114 CollectionPermissions,115 SchemaVersion,116};115};117116118pub use pallet::*;117pub use pallet::*;202 ))201 ))203 }202 }203204 /// 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.recorder214 .consume_gas(T::GasWeightMapping::weight_to_gas(215 reads.saturating_add(writes),216 ))217 }204218205 /// Save collection to storage.219 /// Save collection to storage.206 pub fn save(&self) -> DispatchResult {220 pub fn save(&self) -> DispatchResult {310 }324 }311325312 /// Changes collection owner to another account326 /// Changes collection owner to another account327 /// #### Store read/writes328 /// 1 writes313 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 }129313091294 /// Toggle `user` participation in the `collection`'s allow list.1310 /// Toggle `user` participation in the `collection`'s allow list.1311 /// #### Store read/writes1312 /// 1 writes1295 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 }131313311314 /// Toggle `user` participation in the `collection`'s admin list.1332 /// Toggle `user` participation in the `collection`'s admin list.1333 /// #### Store read/writes1334 /// 2 writes1315 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,pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth172 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 }184179185 /// Check tat contract has confirmed sponsor.180 /// Check tat contract has confirmed sponsor.pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth22}22}232324/// @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 0x9f70d4e026contract 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 }257258 /// 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 }257269258 /// 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 }280281 /// 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 }268291269 /// 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 }302303 /// 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 }279313280 /// Switch permission for minting.314 /// Switch permission for minting.281 ///315 ///325 return "";359 return "";326 }360 }361362 /// 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 }327373328 /// Changes collection owner to another account374 /// Changes collection owner to another account329 ///375 ///pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth99}99}100100101/// @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 0x9f70d4e0103contract 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 }334335 /// 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 }334346335 /// 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 }357358 /// 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 }345368346 /// 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 }379380 /// 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 }356390357 /// Switch permission for minting.391 /// Switch permission for minting.358 ///392 ///402 return "";436 return "";403 }437 }438439 /// 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 }404450405 /// Changes collection owner to another account451 /// Changes collection owner to another account406 ///452 ///pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth99}99}100100101/// @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 0x9f70d4e0103contract 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 }334335 /// 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 }334346335 /// 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 }357358 /// 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 }345368346 /// 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 }379380 /// 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 }356390357 /// Switch permission for minting.391 /// Switch permission for minting.358 ///392 ///402 return "";436 return "";403 }437 }438439 /// 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 }404450405 /// Changes collection owner to another account451 /// Changes collection owner to another account406 ///452 ///tests/src/eth/allowlist.test.tsdiffbeforeafterboth14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License15// 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/>.161617import {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';193120describe('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});7374describe('EVM collection allowlist', () => {75 let donor: IKeyringPair;7677 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 });9798 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 });112113 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 });130131 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});61149tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth13}13}141415/// @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 0x9f70d4e017interface 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;166167 /// 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);166173167 /// 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;180181 /// 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;173187174 /// 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;194195 /// 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;180201181 /// 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);231232 /// 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);210239211 /// Changes collection owner to another account240 /// Changes collection owner to another account212 ///241 ///tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth65}65}666667/// @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 0x9f70d4e069interface 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;218219 /// 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);218225219 /// 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;232233 /// 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;225239226 /// 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;246247 /// 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;232253233 /// 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);283284 /// 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);262291263 /// Changes collection owner to another account292 /// Changes collection owner to another account264 ///293 ///tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth65}65}666667/// @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 0x9f70d4e069interface 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;218219 /// 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);218225219 /// 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;232233 /// 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;225239226 /// 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;246247 /// 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;232253233 /// 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);283284 /// 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);262291263 /// Changes collection owner to another account292 /// Changes collection owner to another account264 ///293 ///tests/src/eth/fungibleAbi.jsondiffbeforeafterboth76 "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",tests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth107 "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" },tests/src/eth/reFungibleAbi.jsondiffbeforeafterboth107 "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" },tests/src/util/helpers.tsdiffbeforeafterboth1651 });1651 });1652}1652}165316531654export 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}16571657tests/src/util/playgrounds/unique.tsdiffbeforeafterboth729 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 }731732 /**733 * Check if user is in allow list.734 * 735 * @param collectionId ID of collection736 * @param user Account to check737 * @example await getAdmins(1)738 * @returns is user in allow list739 */740 async allowed(collectionId: number, user: ICrossAccountId): Promise<boolean> {741 return (await this.helper.callRpc('api.rpc.unique.allowed', [collectionId, user])).toJSON();742 }731743732 /**744 /**733 * Adds an address to allow list745 * Adds an address to allow list