difftreelog
feat evm collection creation event
in: master
39 files changed
Cargo.lockdiffbeforeafterboth5912name = "pallet-common"5912name = "pallet-common"5913version = "0.1.0"5913version = "0.1.0"5914dependencies = [5914dependencies = [5915 "ethereum",5915 "evm-coder",5916 "evm-coder",5916 "fp-evm-mapping",5917 "fp-evm-mapping",5917 "frame-benchmarking",5918 "frame-benchmarking",Makefilediffbeforeafterboth16CONTRACT_HELPERS_ABI=./tests/src/eth/util/contractHelpersAbi.json16CONTRACT_HELPERS_ABI=./tests/src/eth/util/contractHelpersAbi.json171718COLLECTION_HELPER_STUBS=./pallets/unique/src/eth/stubs/18COLLECTION_HELPER_STUBS=./pallets/unique/src/eth/stubs/19COLLECTION_HELPER_ABI=./tests/src/eth/collectionHelperAbi.json19COLLECTION_HELPER_ABI=./tests/src/eth/collectionHelpersAbi.json202021TESTS_API=./tests/src/eth/api/21TESTS_API=./tests/src/eth/api/222223.PHONY: regenerate_solidity23.PHONY: regenerate_solidity24regenerate_solidity: UniqueFungible.sol UniqueNFT.sol ContractHelpers.sol CollectionHelper.sol24regenerate_solidity: UniqueFungible.sol UniqueNFT.sol ContractHelpers.sol CollectionHelpers.sol252526UniqueFungible.sol:26UniqueFungible.sol:27 PACKAGE=pallet-fungible NAME=erc::gen_iface OUTPUT=$(TESTS_API)/$@ ./.maintain/scripts/generate_sol.sh27 PACKAGE=pallet-fungible NAME=erc::gen_iface OUTPUT=$(TESTS_API)/$@ ./.maintain/scripts/generate_sol.sh35 PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_iface OUTPUT=$(TESTS_API)/$@ ./.maintain/scripts/generate_sol.sh35 PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_iface OUTPUT=$(TESTS_API)/$@ ./.maintain/scripts/generate_sol.sh36 PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_impl OUTPUT=$(CONTRACT_HELPERS_STUBS)/$@ ./.maintain/scripts/generate_sol.sh36 PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_impl OUTPUT=$(CONTRACT_HELPERS_STUBS)/$@ ./.maintain/scripts/generate_sol.sh373738CollectionHelper.sol:38CollectionHelpers.sol:39 PACKAGE=pallet-unique NAME=eth::collection_helper_iface OUTPUT=$(TESTS_API)/$@ ./.maintain/scripts/generate_sol.sh39 PACKAGE=pallet-unique NAME=eth::collection_helper_iface OUTPUT=$(TESTS_API)/$@ ./.maintain/scripts/generate_sol.sh40 PACKAGE=pallet-unique NAME=eth::collection_helper_impl OUTPUT=$(COLLECTION_HELPER_STUBS)/$@ ./.maintain/scripts/generate_sol.sh40 PACKAGE=pallet-unique NAME=eth::collection_helper_impl OUTPUT=$(COLLECTION_HELPER_STUBS)/$@ ./.maintain/scripts/generate_sol.sh414151 INPUT=$(CONTRACT_HELPERS_STUBS)/$< OUTPUT=$(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw ./.maintain/scripts/compile_stub.sh51 INPUT=$(CONTRACT_HELPERS_STUBS)/$< OUTPUT=$(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw ./.maintain/scripts/compile_stub.sh52 INPUT=$(CONTRACT_HELPERS_STUBS)/$< OUTPUT=$(CONTRACT_HELPERS_ABI) ./.maintain/scripts/generate_abi.sh52 INPUT=$(CONTRACT_HELPERS_STUBS)/$< OUTPUT=$(CONTRACT_HELPERS_ABI) ./.maintain/scripts/generate_abi.sh535354CollectionHelper: CollectionHelper.sol54CollectionHelpers: CollectionHelpers.sol55 INPUT=$(COLLECTION_HELPER_STUBS)/$< OUTPUT=$(COLLECTION_HELPER_STUBS)/CollectionHelper.raw ./.maintain/scripts/compile_stub.sh55 INPUT=$(COLLECTION_HELPER_STUBS)/$< OUTPUT=$(COLLECTION_HELPER_STUBS)/CollectionHelpers.raw ./.maintain/scripts/compile_stub.sh56 INPUT=$(COLLECTION_HELPER_STUBS)/$< OUTPUT=$(COLLECTION_HELPER_ABI) ./.maintain/scripts/generate_abi.sh56 INPUT=$(COLLECTION_HELPER_STUBS)/$< OUTPUT=$(COLLECTION_HELPER_ABI) ./.maintain/scripts/generate_abi.sh575758evm_stubs: UniqueFungible UniqueNFT ContractHelpers CollectionHelper58evm_stubs: UniqueFungible UniqueNFT ContractHelpers CollectionHelpers595960.PHONY: _bench60.PHONY: _bench61_bench:61_bench:pallets/common/Cargo.tomldiffbeforeafterboth21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }22pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }22pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }23evm-coder = { default-features = false, path = '../../crates/evm-coder' }23evm-coder = { default-features = false, path = '../../crates/evm-coder' }24ethereum = { version = "0.12.0", default-features = false }24pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.21-logs" }25pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.21-logs" }252626serde = { version = "1.0.130", default-features = false }27serde = { version = "1.0.130", default-features = false }pallets/common/src/dispatch.rsdiffbeforeafterboth56}56}575758pub trait CollectionDispatch<T: Config> {58pub trait CollectionDispatch<T: Config> {59 fn create(sender: T::AccountId, data: CreateCollectionData<T::AccountId>) -> DispatchResult;59 fn create(60 sender: T::CrossAccountId,61 data: CreateCollectionData<T::AccountId>,62 ) -> DispatchResult;60 fn destroy(sender: T::CrossAccountId, handle: CollectionHandle<T>) -> DispatchResult;63 fn destroy(sender: T::CrossAccountId, handle: CollectionHandle<T>) -> DispatchResult;6164pallets/common/src/erc.rsdiffbeforeafterboth15// 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/>.161617use evm_coder::{17use evm_coder::{18 solidity_interface, solidity,18 solidity_interface, solidity, ToLog,19 types::*,19 types::*,20 execution::{Result, Error},20 execution::{Result, Error},21};21};282829use crate::{Pallet, CollectionHandle, Config, CollectionProperties};29use crate::{Pallet, CollectionHandle, Config, CollectionProperties};3031#[derive(ToLog)]32pub enum CollectionHelpersEvents {33 CollectionCreated {34 #[indexed]35 owner: address,36 #[indexed]37 collection_id: address,38 },39}304031/// Does not always represent a full collection, for RFT it is either41/// Does not always represent a full collection, for RFT it is either32/// collection (Implementing ERC721), or specific collection token (Implementing ERC20)42/// collection (Implementing ERC721), or specific collection token (Implementing ERC20)pallets/common/src/lib.rsdiffbeforeafterboth21use core::ops::{Deref, DerefMut};21use core::ops::{Deref, DerefMut};22use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};22use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};23use sp_std::vec::Vec;23use sp_std::vec::Vec;24use pallet_evm::account::CrossAccountId;24use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};25use evm_coder::ToLog;25use frame_support::{26use frame_support::{26 dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight, PostDispatchInfo},27 dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight, PostDispatchInfo},27 ensure,28 ensure,28 traits::{Imbalance, Get, Currency, WithdrawReasons, ExistenceRequirement},29 traits::{Imbalance, Get, Currency, WithdrawReasons, ExistenceRequirement},29 BoundedVec,30 weights::Pays,30 weights::Pays,31 transactional,31 transactional,32};32};54 CreateItemExData,54 CreateItemExData,55 SponsoringRateLimit,55 SponsoringRateLimit,56 budget::Budget,56 budget::Budget,57 COLLECTION_FIELD_LIMIT,58 PhantomType,57 PhantomType,59 Property,58 Property,60 Properties,59 Properties,220 pub trait Config:219 pub trait Config:221 frame_system::Config + pallet_evm_coder_substrate::Config + TypeInfo + account::Config220 frame_system::Config221 + pallet_evm_coder_substrate::Config222 + pallet_evm::Config223 + TypeInfo224 + account::Config222 {225 {232 type CollectionDispatch: CollectionDispatch<Self>;235 type CollectionDispatch: CollectionDispatch<Self>;233236234 type TreasuryAccountId: Get<Self::AccountId>;237 type TreasuryAccountId: Get<Self::AccountId>;238 type ContractAddress: Get<H160>;235239236 type EvmTokenAddressMapping: TokenAddressMapping<H160>;240 type EvmTokenAddressMapping: TokenAddressMapping<H160>;237 type CrossTokenAddressMapping: TokenAddressMapping<Self::CrossAccountId>;241 type CrossTokenAddressMapping: TokenAddressMapping<Self::CrossAccountId>;722726723impl<T: Config> Pallet<T> {727impl<T: Config> Pallet<T> {724 pub fn init_collection(728 pub fn init_collection(725 owner: T::AccountId,729 owner: T::CrossAccountId,726 data: CreateCollectionData<T::AccountId>,730 data: CreateCollectionData<T::AccountId>,727 ) -> Result<CollectionId, DispatchError> {731 ) -> Result<CollectionId, DispatchError> {728 {732 {748 // =========752 // =========749753750 let collection = Collection {754 let collection = Collection {751 owner: owner.clone(),755 owner: owner.as_sub().clone(),752 name: data.name,756 name: data.name,753 mode: data.mode.clone(),757 mode: data.mode.clone(),754 description: data.description,758 description: data.description,794 ),798 ),795 );799 );796 <T as Config>::Currency::settle(800 <T as Config>::Currency::settle(797 &owner,801 &owner.as_sub(),798 imbalance,802 imbalance,799 WithdrawReasons::TRANSFER,803 WithdrawReasons::TRANSFER,800 ExistenceRequirement::KeepAlive,804 ExistenceRequirement::KeepAlive,806 <Pallet<T>>::deposit_event(Event::CollectionCreated(id, data.mode.id(), owner.clone()));810 <Pallet<T>>::deposit_event(Event::CollectionCreated(811 id,812 data.mode.id(),813 owner.as_sub().clone(),814 ));815 <PalletEvm<T>>::deposit_log(816 erc::CollectionHelpersEvents::CollectionCreated {817 owner: *owner.as_eth(),818 collection_id: eth::collection_id_to_address(id),819 }820 .to_log(T::ContractAddress::get()),821 );807 <CollectionById<T>>::insert(id, collection);822 <CollectionById<T>>::insert(id, collection);808 Ok(id)823 Ok(id)809 }824 }pallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth66 }66 }676768 #[pallet::config]68 #[pallet::config]69 pub trait Config: frame_system::Config {69 pub trait Config: frame_system::Config + pallet_evm::Config {}70 type GasWeightMapping: pallet_evm::GasWeightMapping;71 }727073 #[pallet::pallet]71 #[pallet::pallet]74 pub struct Pallet<T>(_);72 pub struct Pallet<T>(_);pallets/fungible/src/lib.rsdiffbeforeafterboth134134135impl<T: Config> Pallet<T> {135impl<T: Config> Pallet<T> {136 pub fn init_collection(136 pub fn init_collection(137 owner: T::AccountId,137 owner: T::CrossAccountId,138 data: CreateCollectionData<T::AccountId>,138 data: CreateCollectionData<T::AccountId>,139 ) -> Result<CollectionId, DispatchError> {139 ) -> Result<CollectionId, DispatchError> {140 <PalletCommon<T>>::init_collection(owner, data)140 <PalletCommon<T>>::init_collection(owner, data)pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth127 }127 }128}128}129129130// Selector: f5652829130// Selector: c894dc35131contract Collection is Dummy, ERC165 {131contract Collection is Dummy, ERC165 {132 // Selector: setCollectionProperty(string,bytes) 2f073f66132 // Selector: setCollectionProperty(string,bytes) 2f073f66133 function setCollectionProperty(string memory key, bytes memory value)133 function setCollectionProperty(string memory key, bytes memory value)173 dummy = 0;173 dummy = 0;174 }174 }175175176 // Selector: setLimit(string,string) bf4d2014176 // Selector: setLimit(string,uint32) 68db30ca177 function setLimit(string memory limit, string memory value) public {177 function setLimit(string memory limit, uint32 value) public {178 require(false, stub_error);178 require(false, stub_error);179 limit;179 limit;180 value;180 value;181 dummy = 0;181 dummy = 0;182 }182 }183184 // Selector: setLimit(string,bool) ea67e4c2185 function setLimit(string memory limit, bool value) public {186 require(false, stub_error);187 limit;188 value;189 dummy = 0;190 }183191184 // Selector: contractAddress() f6b4dfb4192 // Selector: contractAddress() f6b4dfb4185 function contractAddress() public view returns (address) {193 function contractAddress() public view returns (address) {pallets/nonfungible/src/lib.rsdiffbeforeafterboth295// unchecked calls skips any permission checks295// unchecked calls skips any permission checks296impl<T: Config> Pallet<T> {296impl<T: Config> Pallet<T> {297 pub fn init_collection(297 pub fn init_collection(298 owner: T::AccountId,298 owner: T::CrossAccountId,299 data: CreateCollectionData<T::AccountId>,299 data: CreateCollectionData<T::AccountId>,300 ) -> Result<CollectionId, DispatchError> {300 ) -> Result<CollectionId, DispatchError> {301 <PalletCommon<T>>::init_collection(owner, data)301 <PalletCommon<T>>::init_collection(owner, data)pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth330 }330 }331}331}332333// Selector: c894dc35334contract Collection is Dummy, ERC165 {335 // Selector: setCollectionProperty(string,bytes) 2f073f66336 function setCollectionProperty(string memory key, bytes memory value)337 public338 {339 require(false, stub_error);340 key;341 value;342 dummy = 0;343 }344345 // Selector: deleteCollectionProperty(string) 7b7debce346 function deleteCollectionProperty(string memory key) public {347 require(false, stub_error);348 key;349 dummy = 0;350 }351352 // Throws error if key not found353 //354 // Selector: collectionProperty(string) cf24fd6d355 function collectionProperty(string memory key)356 public357 view358 returns (bytes memory)359 {360 require(false, stub_error);361 key;362 dummy;363 return hex"";364 }365366 // Selector: ethSetSponsor(address) 8f9af356367 function ethSetSponsor(address sponsor) public {368 require(false, stub_error);369 sponsor;370 dummy = 0;371 }372373 // Selector: ethConfirmSponsorship() a8580d1a374 function ethConfirmSponsorship() public {375 require(false, stub_error);376 dummy = 0;377 }378379 // Selector: setLimit(string,uint32) 68db30ca380 function setLimit(string memory limit, uint32 value) public {381 require(false, stub_error);382 limit;383 value;384 dummy = 0;385 }386387 // Selector: setLimit(string,bool) ea67e4c2388 function setLimit(string memory limit, bool value) public {389 require(false, stub_error);390 limit;391 value;392 dummy = 0;393 }394395 // Selector: contractAddress() f6b4dfb4396 function contractAddress() public view returns (address) {397 require(false, stub_error);398 dummy;399 return 0x0000000000000000000000000000000000000000;400 }401}332402333// Selector: d74d154f403// Selector: d74d154f334contract ERC721UniqueExtensions is Dummy, ERC165 {404contract ERC721UniqueExtensions is Dummy, ERC165 {380 }450 }381}451}382383// Selector: f5652829384contract Collection is Dummy, ERC165 {385 // Selector: setCollectionProperty(string,bytes) 2f073f66386 function setCollectionProperty(string memory key, bytes memory value)387 public388 {389 require(false, stub_error);390 key;391 value;392 dummy = 0;393 }394395 // Selector: deleteCollectionProperty(string) 7b7debce396 function deleteCollectionProperty(string memory key) public {397 require(false, stub_error);398 key;399 dummy = 0;400 }401402 // Throws error if key not found403 //404 // Selector: collectionProperty(string) cf24fd6d405 function collectionProperty(string memory key)406 public407 view408 returns (bytes memory)409 {410 require(false, stub_error);411 key;412 dummy;413 return hex"";414 }415416 // Selector: ethSetSponsor(address) 8f9af356417 function ethSetSponsor(address sponsor) public {418 require(false, stub_error);419 sponsor;420 dummy = 0;421 }422423 // Selector: ethConfirmSponsorship() a8580d1a424 function ethConfirmSponsorship() public {425 require(false, stub_error);426 dummy = 0;427 }428429 // Selector: setLimit(string,string) bf4d2014430 function setLimit(string memory limit, string memory value) public {431 require(false, stub_error);432 limit;433 value;434 dummy = 0;435 }436437 // Selector: contractAddress() f6b4dfb4438 function contractAddress() public view returns (address) {439 require(false, stub_error);440 dummy;441 return 0x0000000000000000000000000000000000000000;442 }443}444452445contract UniqueNFT is453contract UniqueNFT is446 Dummy,454 Dummy,pallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth140 };140 };141141142 let collection_id_res = <PalletNft<T>>::init_collection(sender.clone(), data);142 let collection_id_res =143 <PalletNft<T>>::init_collection(T::CrossAccountId::from_sub(sender.clone()), data);143144144 if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {145 if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {145 return Err(<Error<T>>::NoAvailableCollectionId.into());146 return Err(<Error<T>>::NoAvailableCollectionId.into());pallets/proxy-rmrk-equip/src/lib.rsdiffbeforeafterboth94 ..Default::default()94 ..Default::default()95 };95 };969697 let collection_id_res = <PalletNft<T>>::init_collection(sender.clone(), data);97 let collection_id_res = <PalletNft<T>>::init_collection(cross_sender.clone(), data);989899 if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {99 if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {100 return Err(<Error<T>>::NoAvailableBaseId.into());100 return Err(<Error<T>>::NoAvailableBaseId.into());pallets/refungible/src/lib.rsdiffbeforeafterboth197// unchecked calls skips any permission checks197// unchecked calls skips any permission checks198impl<T: Config> Pallet<T> {198impl<T: Config> Pallet<T> {199 pub fn init_collection(199 pub fn init_collection(200 owner: T::AccountId,200 owner: T::CrossAccountId,201 data: CreateCollectionData<T::AccountId>,201 data: CreateCollectionData<T::AccountId>,202 ) -> Result<CollectionId, DispatchError> {202 ) -> Result<CollectionId, DispatchError> {203 <PalletCommon<T>>::init_collection(owner, data)203 <PalletCommon<T>>::init_collection(owner, data)pallets/unique/src/eth/mod.rsdiffbeforeafterboth26use frame_support::traits::Get;26use frame_support::traits::Get;27use pallet_common::{CollectionById, erc::token_uri_key};27use pallet_common::{28 CollectionById,29 erc::{token_uri_key, CollectionHelpersEvents},30};28use crate::{SelfWeightOf, Config, weights::WeightInfo};31use crate::{SelfWeightOf, Config, weights::WeightInfo};293230use sp_std::vec::Vec;33use sp_std::vec::Vec;31use alloc::format;34use alloc::format;323533struct EvmCollectionHelper<T: Config>(SubstrateRecorder<T>);36struct EvmCollectionHelpers<T: Config>(SubstrateRecorder<T>);34impl<T: Config> WithRecorder<T> for EvmCollectionHelper<T> {37impl<T: Config> WithRecorder<T> for EvmCollectionHelpers<T> {35 fn recorder(&self) -> &SubstrateRecorder<T> {38 fn recorder(&self) -> &SubstrateRecorder<T> {36 &self.039 &self.037 }40 }41 }44 }42}45}434644#[solidity_interface(name = "CollectionHelper")]47#[solidity_interface(name = "CollectionHelpers", events(CollectionHelpersEvents))]45impl<T: Config + pallet_nonfungible::Config> EvmCollectionHelper<T> {48impl<T: Config + pallet_nonfungible::Config> EvmCollectionHelpers<T> {46 #[weight(<SelfWeightOf<T>>::create_collection())]49 #[weight(<SelfWeightOf<T>>::create_collection())]47 fn create_nonfungible_collection(50 fn create_nonfungible_collection(48 &self,51 &self,90 };93 };919492 let collection_id =95 let collection_id = <pallet_nonfungible::Pallet<T>>::init_collection(caller.clone(), data)93 <pallet_nonfungible::Pallet<T>>::init_collection(caller.as_sub().clone(), data)94 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;96 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;959796 let address = pallet_common::eth::collection_id_to_address(collection_id);98 let address = pallet_common::eth::collection_id_to_address(collection_id);107 }109 }108}110}109111110pub struct CollectionHelperOnMethodCall<T: Config>(PhantomData<*const T>);112pub struct CollectionHelpersOnMethodCall<T: Config>(PhantomData<*const T>);111impl<T: Config + pallet_nonfungible::Config> OnMethodCall<T> for CollectionHelperOnMethodCall<T> {113impl<T: Config + pallet_nonfungible::Config> OnMethodCall<T> for CollectionHelpersOnMethodCall<T> {112 fn is_reserved(contract: &sp_core::H160) -> bool {114 fn is_reserved(contract: &sp_core::H160) -> bool {113 contract == &T::ContractAddress::get()115 contract == &T::ContractAddress::get()114 }116 }128 return None;130 return None;129 }131 }130132131 let helpers = EvmCollectionHelper::<T>(SubstrateRecorder::<T>::new(gas_left));133 let helpers = EvmCollectionHelpers::<T>(SubstrateRecorder::<T>::new(gas_left));132 pallet_evm_coder_substrate::call(*source, helpers, value, input)134 pallet_evm_coder_substrate::call(*source, helpers, value, input)133 }135 }134136135 fn get_code(contract: &sp_core::H160) -> Option<Vec<u8>> {137 fn get_code(contract: &sp_core::H160) -> Option<Vec<u8>> {136 (contract == &T::ContractAddress::get())138 (contract == &T::ContractAddress::get())137 .then(|| include_bytes!("./stubs/CollectionHelper.raw").to_vec())139 .then(|| include_bytes!("./stubs/CollectionHelpers.raw").to_vec())138 }140 }139}141}140142141generate_stubgen!(collection_helper_impl, CollectionHelperCall<()>, true);143generate_stubgen!(collection_helper_impl, CollectionHelpersCall<()>, true);142generate_stubgen!(collection_helper_iface, CollectionHelperCall<()>, false);144generate_stubgen!(collection_helper_iface, CollectionHelpersCall<()>, false);143145144fn error_feild_too_long(feild: &str, bound: u32) -> Error {146fn error_feild_too_long(feild: &str, bound: u32) -> Error {145 Error::Revert(format!("{} is too long. Max length is {}.", feild, bound))147 Error::Revert(format!("{} is too long. Max length is {}.", feild, bound))pallets/unique/src/eth/stubs/CollectionHelper.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelper.soldiffbeforeafterbothno changes
pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterbothno changes
pallets/unique/src/lib.rsdiffbeforeafterboth30 ensure,30 ensure,31 weights::{Weight},31 weights::{Weight},32 transactional,32 transactional,33 pallet_prelude::{DispatchResultWithPostInfo, ConstU32, Get},33 pallet_prelude::{DispatchResultWithPostInfo, ConstU32},34 BoundedVec,34 BoundedVec,35};35};36use sp_core::H160;37use scale_info::TypeInfo;36use scale_info::TypeInfo;38use frame_system::{self as system, ensure_signed};37use frame_system::{self as system, ensure_signed};39use sp_runtime::{sp_std::prelude::Vec};38use sp_runtime::{sp_std::prelude::Vec};75 /// Weight information for extrinsics in this pallet.74 /// Weight information for extrinsics in this pallet.76 type WeightInfo: WeightInfo;75 type WeightInfo: WeightInfo;77 type CommonWeightInfo: CommonWeightInfo<Self::CrossAccountId>;76 type CommonWeightInfo: CommonWeightInfo<Self::CrossAccountId>;78 type ContractAddress: Get<H160>;79}77}807881decl_event! {79decl_event! {287285288 // =========286 // =========289287290 T::CollectionDispatch::create(sender, data)?;288 T::CollectionDispatch::create(T::CrossAccountId::from_sub(sender), data)?;291289292 Ok(())290 Ok(())293 }291 }runtime/common/src/dispatch.rsdiffbeforeafterboth30 + pallet_nonfungible::Config30 + pallet_nonfungible::Config31 + pallet_refungible::Config,31 + pallet_refungible::Config,32{32{33 fn create(sender: T::AccountId, data: CreateCollectionData<T::AccountId>) -> DispatchResult {33 fn create(34 sender: T::CrossAccountId,35 data: CreateCollectionData<T::AccountId>,36 ) -> DispatchResult {34 let _id = match data.mode {37 let _id = match data.mode {35 CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data)?,38 CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data)?,runtime/opal/src/lib.rsdiffbeforeafterboth306 pallet_evm_migration::OnMethodCall<Self>,306 pallet_evm_migration::OnMethodCall<Self>,307 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,307 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,308 CollectionDispatchT<Self>,308 CollectionDispatchT<Self>,309 pallet_unique::eth::CollectionHelperOnMethodCall<Self>,309 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,310 );310 );311 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;311 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;312 type ChainId = ChainId;312 type ChainId = ChainId;822);822);823823824impl pallet_evm_coder_substrate::Config for Runtime {824impl pallet_evm_coder_substrate::Config for Runtime {}825 type GasWeightMapping = FixedGasWeightMapping;826}827825828impl pallet_xcm::Config for Runtime {826impl pallet_xcm::Config for Runtime {885883886 type EvmTokenAddressMapping = EvmTokenAddressMapping;884 type EvmTokenAddressMapping = EvmTokenAddressMapping;887 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;885 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;886 type ContractAddress = EvmCollectionHelpersAddress;888}887}889888890impl pallet_structure::Config for Runtime {889impl pallet_structure::Config for Runtime {917 type Event = Event;916 type Event = Event;918 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;917 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;919 type CommonWeightInfo = CommonWeights<Self>;918 type CommonWeightInfo = CommonWeights<Self>;920 type ContractAddress = EvmCollectionHelperAddress;921}919}922920923parameter_types! {921parameter_types! {980 ]);978 ]);981979982 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f980 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f983 pub const EvmCollectionHelperAddress: H160 = H160([981 pub const EvmCollectionHelpersAddress: H160 = H160([984 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,982 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,985 ]);983 ]);986}984}runtime/quartz/src/lib.rsdiffbeforeafterboth285 pallet_evm_migration::OnMethodCall<Self>,285 pallet_evm_migration::OnMethodCall<Self>,286 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,286 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,287 CollectionDispatchT<Self>,287 CollectionDispatchT<Self>,288 pallet_unique::eth::CollectionHelperOnMethodCall<Self>,288 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,289 );289 );290 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;290 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;291 type ChainId = ChainId;291 type ChainId = ChainId;801);801);802802803impl pallet_evm_coder_substrate::Config for Runtime {803impl pallet_evm_coder_substrate::Config for Runtime {}804 type GasWeightMapping = FixedGasWeightMapping;805}806804807impl pallet_xcm::Config for Runtime {805impl pallet_xcm::Config for Runtime {864862865 type EvmTokenAddressMapping = EvmTokenAddressMapping;863 type EvmTokenAddressMapping = EvmTokenAddressMapping;866 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;864 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;865 type ContractAddress = EvmCollectionHelpersAddress;867}866}868867869impl pallet_structure::Config for Runtime {868impl pallet_structure::Config for Runtime {900 type Event = Event;899 type Event = Event;901 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;900 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;902 type CommonWeightInfo = CommonWeights<Self>;901 type CommonWeightInfo = CommonWeights<Self>;903 type ContractAddress = EvmCollectionHelperAddress;904}902}905903906parameter_types! {904parameter_types! {963 ]);961 ]);964 962 965 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f963 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f966 pub const EvmCollectionHelperAddress: H160 = H160([964 pub const EvmCollectionHelpersAddress: H160 = H160([967 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,965 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,968 ]);966 ]);969}967}runtime/tests/src/lib.rsdiffbeforeafterboth209 type TransactionValidityHack = ();209 type TransactionValidityHack = ();210}210}211impl pallet_evm_coder_substrate::Config for Test {211impl pallet_evm_coder_substrate::Config for Test {}212 type GasWeightMapping = ();213}214212215impl pallet_common::Config for Test {213impl pallet_common::Config for Test {222 type CollectionDispatch = CollectionDispatchT<Self>;220 type CollectionDispatch = CollectionDispatchT<Self>;223 type EvmTokenAddressMapping = EvmTokenAddressMapping;221 type EvmTokenAddressMapping = EvmTokenAddressMapping;224 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;222 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;223 type ContractAddress = EvmCollectionHelpersAddress;225}224}226225227impl pallet_evm::account::Config for Test {226impl pallet_evm::account::Config for Test {247246248parameter_types! {247parameter_types! {249 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f248 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f250 pub const EvmCollectionHelperAddress: H160 = H160([249 pub const EvmCollectionHelpersAddress: H160 = H160([251 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,250 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,252 ]);251 ]);253}252}256 type Event = ();255 type Event = ();257 type WeightInfo = ();256 type WeightInfo = ();258 type CommonWeightInfo = CommonWeights<Self>;257 type CommonWeightInfo = CommonWeights<Self>;259 type ContractAddress = EvmCollectionHelperAddress;260}258}261259262// Build genesis storage according to the mock runtime.260// Build genesis storage according to the mock runtime.runtime/unique/src/lib.rsdiffbeforeafterboth290 pallet_evm_migration::OnMethodCall<Self>,290 pallet_evm_migration::OnMethodCall<Self>,291 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,291 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,292 CollectionDispatchT<Self>,292 CollectionDispatchT<Self>,293 pallet_unique::eth::CollectionHelperOnMethodCall<Self>,293 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,294 );294 );295 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;295 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;296 type ChainId = ChainId;296 type ChainId = ChainId;806);806);807807808impl pallet_evm_coder_substrate::Config for Runtime {808impl pallet_evm_coder_substrate::Config for Runtime {}809 type GasWeightMapping = FixedGasWeightMapping;810}811809812impl pallet_xcm::Config for Runtime {810impl pallet_xcm::Config for Runtime {869867870 type EvmTokenAddressMapping = EvmTokenAddressMapping;868 type EvmTokenAddressMapping = EvmTokenAddressMapping;871 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;869 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;870 type ContractAddress = EvmCollectionHelpersAddress;872}871}873872874impl pallet_structure::Config for Runtime {873impl pallet_structure::Config for Runtime {905 type Event = Event;904 type Event = Event;906 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;905 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;907 type CommonWeightInfo = CommonWeights<Self>;906 type CommonWeightInfo = CommonWeights<Self>;908 type ContractAddress = EvmCollectionHelperAddress;909}907}910908911parameter_types! {909parameter_types! {968 ]);966 ]);969 967 970 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f968 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f971 pub const EvmCollectionHelperAddress: H160 = H160([969 pub const EvmCollectionHelpersAddress: H160 = H160([972 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,970 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,973 ]);971 ]);974}972}tests/src/eth/api/CollectionHelper.soldiffbeforeafterbothno changes
tests/src/eth/api/CollectionHelpers.soldiffbeforeafterbothno changes
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth65 returns (uint256);65 returns (uint256);66}66}676768// Selector: f565282968// Selector: c894dc3569interface Collection is Dummy, ERC165 {69interface Collection is Dummy, ERC165 {70 // Selector: setCollectionProperty(string,bytes) 2f073f6670 // Selector: setCollectionProperty(string,bytes) 2f073f6671 function setCollectionProperty(string memory key, bytes memory value)71 function setCollectionProperty(string memory key, bytes memory value)88 // Selector: ethConfirmSponsorship() a8580d1a88 // Selector: ethConfirmSponsorship() a8580d1a89 function ethConfirmSponsorship() external;89 function ethConfirmSponsorship() external;909091 // Selector: setLimit(string,string) bf4d201491 // Selector: setLimit(string,uint32) 68db30ca92 function setLimit(string memory limit, string memory value) external;92 function setLimit(string memory limit, uint32 value) external;9394 // Selector: setLimit(string,bool) ea67e4c295 function setLimit(string memory limit, bool value) external;939694 // Selector: contractAddress() f6b4dfb497 // Selector: contractAddress() f6b4dfb495 function contractAddress() external view returns (address);98 function contractAddress() external view returns (address);tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth191 function totalSupply() external view returns (uint256);191 function totalSupply() external view returns (uint256);192}192}193194// Selector: c894dc35195interface Collection is Dummy, ERC165 {196 // Selector: setCollectionProperty(string,bytes) 2f073f66197 function setCollectionProperty(string memory key, bytes memory value)198 external;199200 // Selector: deleteCollectionProperty(string) 7b7debce201 function deleteCollectionProperty(string memory key) external;202203 // Throws error if key not found204 //205 // Selector: collectionProperty(string) cf24fd6d206 function collectionProperty(string memory key)207 external208 view209 returns (bytes memory);210211 // Selector: ethSetSponsor(address) 8f9af356212 function ethSetSponsor(address sponsor) external;213214 // Selector: ethConfirmSponsorship() a8580d1a215 function ethConfirmSponsorship() external;216217 // Selector: setLimit(string,uint32) 68db30ca218 function setLimit(string memory limit, uint32 value) external;219220 // Selector: setLimit(string,bool) ea67e4c2221 function setLimit(string memory limit, bool value) external;222223 // Selector: contractAddress() f6b4dfb4224 function contractAddress() external view returns (address);225}193226194// Selector: d74d154f227// Selector: d74d154f195interface ERC721UniqueExtensions is Dummy, ERC165 {228interface ERC721UniqueExtensions is Dummy, ERC165 {213 returns (bool);246 returns (bool);214}247}215216// Selector: f5652829217interface Collection is Dummy, ERC165 {218 // Selector: setCollectionProperty(string,bytes) 2f073f66219 function setCollectionProperty(string memory key, bytes memory value)220 external;221222 // Selector: deleteCollectionProperty(string) 7b7debce223 function deleteCollectionProperty(string memory key) external;224225 // Throws error if key not found226 //227 // Selector: collectionProperty(string) cf24fd6d228 function collectionProperty(string memory key)229 external230 view231 returns (bytes memory);232233 // Selector: ethSetSponsor(address) 8f9af356234 function ethSetSponsor(address sponsor) external;235236 // Selector: ethConfirmSponsorship() a8580d1a237 function ethConfirmSponsorship() external;238239 // Selector: setLimit(string,string) bf4d2014240 function setLimit(string memory limit, string memory value) external;241242 // Selector: contractAddress() f6b4dfb4243 function contractAddress() external view returns (address);244}245248246interface UniqueNFT is249interface UniqueNFT is247 Dummy,250 Dummy,tests/src/eth/collectionHelperAbi.jsondiffbeforeafterbothno changes
tests/src/eth/collectionHelpersAbi.jsondiffbeforeafterbothno changes
tests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth29 normalizeEvents,29 normalizeEvents,30 subToEth,30 subToEth,31 executeEthTxOnSub,31 executeEthTxOnSub,32 evmCollectionHelper,32 evmCollectionHelpers,33 getCollectionAddressFromResult,33 getCollectionAddressFromResult,34 evmCollection,34 evmCollection,35} from './util/helpers';35} from './util/helpers';224 //TODO: CORE-302 add eth methods224 //TODO: CORE-302 add eth methods225 itWeb3.skip('Sponsoring evm address from substrate collection', async ({api, web3}) => {225 itWeb3.skip('Sponsoring evm address from substrate collection', async ({api, web3}) => {226 const owner = await createEthAccountWithBalance(api, web3);226 const owner = await createEthAccountWithBalance(api, web3);227 const collectionHelper = evmCollectionHelper(web3, owner);227 const collectionHelpers = evmCollectionHelpers(web3, owner);228 let result = await collectionHelper.methods.create721Collection('Sponsor collection', '1', '1').send();228 let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();229 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);229 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);230 const sponsor = await createEthAccountWithBalance(api, web3);230 const sponsor = await createEthAccountWithBalance(api, web3);231 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);231 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);tests/src/eth/createCollection.test.tsdiffbeforeafterboth18import {expect} from 'chai';18import {expect} from 'chai';19import {getCreatedCollectionCount, getDetailedCollectionInfo} from '../util/helpers';19import {getCreatedCollectionCount, getDetailedCollectionInfo} from '../util/helpers';20import {20import {21 evmCollectionHelper,21 evmCollectionHelpers,22 collectionIdToAddress,22 collectionIdToAddress,23 createEthAccount,23 createEthAccount,24 createEthAccountWithBalance,24 createEthAccountWithBalance,30describe('Create collection from EVM', () => {30describe('Create collection from EVM', () => {31 itWeb3('Create collection', async ({api, web3}) => {31 itWeb3('Create collection', async ({api, web3}) => {32 const owner = await createEthAccountWithBalance(api, web3);32 const owner = await createEthAccountWithBalance(api, web3);33 const helper = evmCollectionHelper(web3, owner);33 const helper = evmCollectionHelpers(web3, owner);34 const collectionName = 'CollectionEVM';34 const collectionName = 'CollectionEVM';35 const description = 'Some description';35 const description = 'Some description';36 const tokenPrefix = 'token prefix';36 const tokenPrefix = 'token prefix';37 37 38 const collectionCountBefore = await getCreatedCollectionCount(api);38 const collectionCountBefore = await getCreatedCollectionCount(api);39 const result = await helper.methods39 const result = await helper.methods40 .create721Collection(collectionName, description, tokenPrefix)40 .createNonfungibleCollection(collectionName, description, tokenPrefix)41 .send();41 .send();42 const collectionCountAfter = await getCreatedCollectionCount(api);42 const collectionCountAfter = await getCreatedCollectionCount(api);43 43 515152 itWeb3('Check collection address exist', async ({api, web3}) => {52 itWeb3('Check collection address exist', async ({api, web3}) => {53 const owner = await createEthAccountWithBalance(api, web3);53 const owner = await createEthAccountWithBalance(api, web3);54 const collectionHelper = evmCollectionHelper(web3, owner);54 const collectionHelpers = evmCollectionHelpers(web3, owner);55 55 56 const expectedCollectionId = await getCreatedCollectionCount(api) + 1;56 const expectedCollectionId = await getCreatedCollectionCount(api) + 1;57 const expectedCollectionAddress = collectionIdToAddress(expectedCollectionId);57 const expectedCollectionAddress = collectionIdToAddress(expectedCollectionId);58 expect(await collectionHelper.methods58 expect(await collectionHelpers.methods59 .isCollectionExist(expectedCollectionAddress)59 .isCollectionExist(expectedCollectionAddress)60 .call()).to.be.false;60 .call()).to.be.false;616162 await collectionHelper.methods62 await collectionHelpers.methods63 .create721Collection('A', 'A', 'A')63 .createNonfungibleCollection('A', 'A', 'A')64 .send();64 .send();65 65 66 expect(await collectionHelper.methods66 expect(await collectionHelpers.methods67 .isCollectionExist(expectedCollectionAddress)67 .isCollectionExist(expectedCollectionAddress)68 .call()).to.be.true;68 .call()).to.be.true;69 });69 });70 70 71 itWeb3('Set sponsorship', async ({api, web3}) => {71 itWeb3('Set sponsorship', async ({api, web3}) => {72 const owner = await createEthAccountWithBalance(api, web3);72 const owner = await createEthAccountWithBalance(api, web3);73 const collectionHelper = evmCollectionHelper(web3, owner);73 const collectionHelpers = evmCollectionHelpers(web3, owner);74 let result = await collectionHelper.methods.create721Collection('Sponsor collection', '1', '1').send();74 let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();75 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);75 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);76 const sponsor = await createEthAccountWithBalance(api, web3);76 const sponsor = await createEthAccountWithBalance(api, web3);77 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);77 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);898990 itWeb3('Set limits', async ({api, web3}) => {90 itWeb3('Set limits', async ({api, web3}) => {91 const owner = await createEthAccountWithBalance(api, web3);91 const owner = await createEthAccountWithBalance(api, web3);92 const collectionHelper = evmCollectionHelper(web3, owner);92 const collectionHelpers = evmCollectionHelpers(web3, owner);93 const result = await collectionHelper.methods.create721Collection('Const collection', '5', '5').send();93 const result = await collectionHelpers.methods.createNonfungibleCollection('Const collection', '5', '5').send();94 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);94 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);95 const limits = {95 const limits = {96 accountTokenOwnershipLimit: 1000,96 accountTokenOwnershipLimit: 1000,105 };105 };106106107 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);107 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);108 await collectionEvm.methods.setLimit('accountTokenOwnershipLimit', limits.accountTokenOwnershipLimit.toString()).send();108 await collectionEvm.methods['setLimit(string,uint32)']('accountTokenOwnershipLimit', limits.accountTokenOwnershipLimit).send();109 await collectionEvm.methods.setLimit('sponsoredDataSize', limits.sponsoredDataSize.toString()).send();109 await collectionEvm.methods['setLimit(string,uint32)']('sponsoredDataSize', limits.sponsoredDataSize).send();110 await collectionEvm.methods.setLimit('sponsoredDataRateLimit', limits.sponsoredDataRateLimit.toString()).send();110 await collectionEvm.methods['setLimit(string,uint32)']('sponsoredDataRateLimit', limits.sponsoredDataRateLimit).send();111 await collectionEvm.methods.setLimit('tokenLimit', limits.tokenLimit.toString()).send();111 await collectionEvm.methods['setLimit(string,uint32)']('tokenLimit', limits.tokenLimit).send();112 await collectionEvm.methods.setLimit('sponsorTransferTimeout', limits.sponsorTransferTimeout.toString()).send();112 await collectionEvm.methods['setLimit(string,uint32)']('sponsorTransferTimeout', limits.sponsorTransferTimeout).send();113 await collectionEvm.methods.setLimit('sponsorApproveTimeout', limits.sponsorApproveTimeout.toString()).send();113 await collectionEvm.methods['setLimit(string,uint32)']('sponsorApproveTimeout', limits.sponsorApproveTimeout).send();114 await collectionEvm.methods.setLimit('ownerCanTransfer', limits.ownerCanTransfer.toString()).send();114 await collectionEvm.methods['setLimit(string,bool)']('ownerCanTransfer', limits.ownerCanTransfer).send();115 await collectionEvm.methods.setLimit('ownerCanDestroy', limits.ownerCanDestroy.toString()).send();115 await collectionEvm.methods['setLimit(string,bool)']('ownerCanDestroy', limits.ownerCanDestroy).send();116 await collectionEvm.methods.setLimit('transfersEnabled', limits.transfersEnabled.toString()).send();116 await collectionEvm.methods['setLimit(string,bool)']('transfersEnabled', limits.transfersEnabled).send();117 117 118 const collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;118 const collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;119 expect(collectionSub.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.be.eq(limits.accountTokenOwnershipLimit);119 expect(collectionSub.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.be.eq(limits.accountTokenOwnershipLimit);130 itWeb3('Collection address exist', async ({api, web3}) => {130 itWeb3('Collection address exist', async ({api, web3}) => {131 const owner = await createEthAccountWithBalance(api, web3);131 const owner = await createEthAccountWithBalance(api, web3);132 const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';132 const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';133 const collectionHelper = evmCollectionHelper(web3, owner);133 const collectionHelpers = evmCollectionHelpers(web3, owner);134 expect(await collectionHelper.methods134 expect(await collectionHelpers.methods135 .isCollectionExist(collectionAddressForNonexistentCollection).call())135 .isCollectionExist(collectionAddressForNonexistentCollection).call())136 .to.be.false;136 .to.be.false;137 137 138 const result = await collectionHelper.methods.create721Collection('Collection address exist', '7', '7').send();138 const result = await collectionHelpers.methods.createNonfungibleCollection('Collection address exist', '7', '7').send();139 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);139 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);140 expect(await collectionHelper.methods140 expect(await collectionHelpers.methods141 .isCollectionExist(collectionIdAddress).call())141 .isCollectionExist(collectionIdAddress).call())142 .to.be.true;142 .to.be.true;143 });143 });146describe('(!negative tests!) Create collection from EVM', () => {146describe('(!negative tests!) Create collection from EVM', () => {147 itWeb3('(!negative test!) Create collection (bad lengths)', async ({api, web3}) => {147 itWeb3('(!negative test!) Create collection (bad lengths)', async ({api, web3}) => {148 const owner = await createEthAccountWithBalance(api, web3);148 const owner = await createEthAccountWithBalance(api, web3);149 const helper = evmCollectionHelper(web3, owner);149 const helper = evmCollectionHelpers(web3, owner);150 {150 {151 const MAX_NAME_LENGHT = 64;151 const MAX_NAME_LENGHT = 64;152 const collectionName = 'A'.repeat(MAX_NAME_LENGHT + 1);152 const collectionName = 'A'.repeat(MAX_NAME_LENGHT + 1);153 const description = 'A';153 const description = 'A';154 const tokenPrefix = 'A';154 const tokenPrefix = 'A';155 155 156 await expect(helper.methods156 await expect(helper.methods157 .create721Collection(collectionName, description, tokenPrefix)157 .createNonfungibleCollection(collectionName, description, tokenPrefix)158 .call()).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGHT);158 .call()).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGHT);159 159 160 }160 }164 const description = 'A'.repeat(MAX_DESCRIPTION_LENGHT + 1);164 const description = 'A'.repeat(MAX_DESCRIPTION_LENGHT + 1);165 const tokenPrefix = 'A';165 const tokenPrefix = 'A';166 await expect(helper.methods166 await expect(helper.methods167 .create721Collection(collectionName, description, tokenPrefix)167 .createNonfungibleCollection(collectionName, description, tokenPrefix)168 .call()).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGHT);168 .call()).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGHT);169 }169 }170 { 170 { 173 const description = 'A';173 const description = 'A';174 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGHT + 1);174 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGHT + 1);175 await expect(helper.methods175 await expect(helper.methods176 .create721Collection(collectionName, description, tokenPrefix)176 .createNonfungibleCollection(collectionName, description, tokenPrefix)177 .call()).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGHT);177 .call()).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGHT);178 }178 }179 });179 });180 180 181 itWeb3('(!negative test!) Create collection (no funds)', async ({web3}) => {181 itWeb3('(!negative test!) Create collection (no funds)', async ({web3}) => {182 const owner = await createEthAccount(web3);182 const owner = await createEthAccount(web3);183 const helper = evmCollectionHelper(web3, owner);183 const helper = evmCollectionHelpers(web3, owner);184 const collectionName = 'A';184 const collectionName = 'A';185 const description = 'A';185 const description = 'A';186 const tokenPrefix = 'A';186 const tokenPrefix = 'A';187 187 188 await expect(helper.methods188 await expect(helper.methods189 .create721Collection(collectionName, description, tokenPrefix)189 .createNonfungibleCollection(collectionName, description, tokenPrefix)190 .call()).to.be.rejectedWith('NotSufficientFounds');190 .call()).to.be.rejectedWith('NotSufficientFounds');191 });191 });192192193 itWeb3('(!negative test!) Check owner', async ({api, web3}) => {193 itWeb3('(!negative test!) Check owner', async ({api, web3}) => {194 const owner = await createEthAccountWithBalance(api, web3);194 const owner = await createEthAccountWithBalance(api, web3);195 const notOwner = await createEthAccount(web3);195 const notOwner = await createEthAccount(web3);196 const collectionHelper = evmCollectionHelper(web3, owner);196 const collectionHelpers = evmCollectionHelpers(web3, owner);197 const result = await collectionHelper.methods.create721Collection('A', 'A', 'A').send();197 const result = await collectionHelpers.methods.createNonfungibleCollection('A', 'A', 'A').send();198 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);198 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);199 const contractEvmFromNotOwner = evmCollection(web3, notOwner, collectionIdAddress);199 const contractEvmFromNotOwner = evmCollection(web3, notOwner, collectionIdAddress);200 const EXPECTED_ERROR = 'NoPermission';200 const EXPECTED_ERROR = 'NoPermission';218218219 itWeb3('(!negative test!) Set limits', async ({api, web3}) => {219 itWeb3('(!negative test!) Set limits', async ({api, web3}) => {220 const owner = await createEthAccountWithBalance(api, web3);220 const owner = await createEthAccountWithBalance(api, web3);221 const collectionHelper = evmCollectionHelper(web3, owner);221 const collectionHelpers = evmCollectionHelpers(web3, owner);222 const result = await collectionHelper.methods.create721Collection('Schema collection', 'A', 'A').send();222 const result = await collectionHelpers.methods.createNonfungibleCollection('Schema collection', 'A', 'A').send();223 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);223 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);224 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);224 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);225 await expect(collectionEvm.methods225 await expect(collectionEvm.methods226 .setLimit('badLimit', 'true')226 .setLimit('badLimit', 'true')227 .call()).to.be.rejectedWith('Unknown limit "badLimit"');227 .call()).to.be.rejectedWith('Unknown boolean limit "badLimit"');228 await expect(collectionEvm.methods229 .setLimit('sponsoredDataSize', 'badValue')230 .call()).to.be.rejectedWith('Int value "badValue" parse error:');231 await expect(collectionEvm.methods232 .setLimit('ownerCanTransfer', 'badValue')233 .call()).to.be.rejectedWith('Bool value "badValue" parse error:');234 });228 });235});229});tests/src/eth/fungibleAbi.jsondiffbeforeafterboth152 {152 {153 "inputs": [153 "inputs": [154 { "internalType": "string", "name": "limit", "type": "string" },154 { "internalType": "string", "name": "limit", "type": "string" },155 { "internalType": "string", "name": "value", "type": "string" }155 { "internalType": "uint32", "name": "value", "type": "uint32" }156 ],156 ],157 "name": "setLimit",157 "name": "setLimit",158 "outputs": [],158 "outputs": [],159 "stateMutability": "nonpayable",159 "stateMutability": "nonpayable",160 "type": "function"160 "type": "function"161 },161 },162 {163 "inputs": [164 { "internalType": "string", "name": "limit", "type": "string" },165 { "internalType": "bool", "name": "value", "type": "bool" }166 ],167 "name": "setLimit",168 "outputs": [],169 "stateMutability": "nonpayable",170 "type": "function"171 },162 {172 {163 "inputs": [173 "inputs": [164 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }174 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }tests/src/eth/nonFungible.test.tsdiffbeforeafterboth161617import privateKey from '../substrate/privateKey';17import privateKey from '../substrate/privateKey';18import {approveExpectSuccess, burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE} from '../util/helpers';18import {approveExpectSuccess, burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE} from '../util/helpers';19import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelper, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth} from './util/helpers';19import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth} from './util/helpers';20import nonFungibleAbi from './nonFungibleAbi.json';20import nonFungibleAbi from './nonFungibleAbi.json';21import {expect} from 'chai';21import {expect} from 'chai';22import {submitTransactionAsync} from '../substrate/substrate-api';22import {submitTransactionAsync} from '../substrate/substrate-api';76describe('NFT: Plain calls', () => {76describe('NFT: Plain calls', () => {77 itWeb3('Can perform mint()', async ({web3, api}) => {77 itWeb3('Can perform mint()', async ({web3, api}) => {78 const owner = await createEthAccountWithBalance(api, web3);78 const owner = await createEthAccountWithBalance(api, web3);79 const helper = evmCollectionHelper(web3, owner);79 const helper = evmCollectionHelpers(web3, owner);80 let result = await helper.methods.create721Collection('Mint collection', '6', '6').send();80 let result = await helper.methods.createNonfungibleCollection('Mint collection', '6', '6').send();81 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);81 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);82 const receiver = createEthAccount(web3);82 const receiver = createEthAccount(web3);83 const contract = evmCollection(web3, owner, collectionIdAddress);83 const contract = evmCollection(web3, owner, collectionIdAddress);tests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth326 {326 {327 "inputs": [327 "inputs": [328 { "internalType": "string", "name": "limit", "type": "string" },328 { "internalType": "string", "name": "limit", "type": "string" },329 { "internalType": "string", "name": "value", "type": "string" }329 { "internalType": "uint32", "name": "value", "type": "uint32" }330 ],330 ],331 "name": "setLimit",331 "name": "setLimit",332 "outputs": [],332 "outputs": [],333 "stateMutability": "nonpayable",333 "stateMutability": "nonpayable",334 "type": "function"334 "type": "function"335 },335 },336 {337 "inputs": [338 { "internalType": "string", "name": "limit", "type": "string" },339 { "internalType": "bool", "name": "value", "type": "bool" }340 ],341 "name": "setLimit",342 "outputs": [],343 "stateMutability": "nonpayable",344 "type": "function"345 },336 {346 {337 "inputs": [347 "inputs": [338 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },348 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },tests/src/eth/util/helpers.tsdiffbeforeafterboth29import privateKey from '../../substrate/privateKey';29import privateKey from '../../substrate/privateKey';30import contractHelpersAbi from './contractHelpersAbi.json';30import contractHelpersAbi from './contractHelpersAbi.json';31import nonFungibleAbi from '../nonFungibleAbi.json';31import nonFungibleAbi from '../nonFungibleAbi.json';32import collectionHelperAbi from '../collectionHelperAbi.json';32import collectionHelpersAbi from '../collectionHelpersAbi.json';33import getBalance from '../../substrate/get-balance';33import getBalance from '../../substrate/get-balance';34import waitNewBlocks from '../../substrate/wait-new-blocks';34import waitNewBlocks from '../../substrate/wait-new-blocks';353569}69}707071export async function getCollectionAddressFromResult(api: ApiPromise, result: any) {71export async function getCollectionAddressFromResult(api: ApiPromise, result: any) {72 const collectionIdAddress = normalizeAddress(result.events[0].raw.topics[2]);72 const collectionIdAddress = normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);73 const collectionId = collectionIdFromAddress(collectionIdAddress); 73 const collectionId = collectionIdFromAddress(collectionIdAddress); 74 const collection = (await getDetailedCollectionInfo(api, collectionId))!;74 const collection = (await getDetailedCollectionInfo(api, collectionId))!;75 return {collectionIdAddress, collectionId, collection};75 return {collectionIdAddress, collectionId, collection};297 * @param caller - eth address297 * @param caller - eth address298 * @returns 298 * @returns 299 */299 */300export function evmCollectionHelper(web3: Web3, caller: string) {300export function evmCollectionHelpers(web3: Web3, caller: string) {301 return new web3.eth.Contract(collectionHelperAbi as any, '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f', {from: caller, ...GAS_ARGS});301 return new web3.eth.Contract(collectionHelpersAbi as any, '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f', {from: caller, ...GAS_ARGS});302}302}303303304/** 304/**