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

difftreelog

CORE-302 Add EvmCollection Pallet

Trubnikov Sergey2022-04-18parent: #f15380e.patch.diff
in: master

24 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5504,6 +5504,7 @@
  "pallet-ethereum",
  "pallet-evm",
  "pallet-evm-coder-substrate",
+ "pallet-evm-collection",
  "pallet-evm-contract-helpers",
  "pallet-evm-migration",
  "pallet-evm-transaction-payment",
@@ -6075,6 +6076,28 @@
 ]
 
 [[package]]
+name = "pallet-evm-collection"
+version = "0.1.0"
+dependencies = [
+ "ethereum",
+ "evm-coder",
+ "fp-evm-mapping",
+ "frame-support",
+ "frame-system",
+ "log",
+ "pallet-common",
+ "pallet-evm",
+ "pallet-evm-coder-substrate",
+ "pallet-nonfungible",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-runtime",
+ "sp-std",
+ "up-data-structs",
+]
+
+[[package]]
 name = "pallet-evm-contract-helpers"
 version = "0.1.0"
 dependencies = [
@@ -8784,6 +8807,7 @@
  "pallet-ethereum",
  "pallet-evm",
  "pallet-evm-coder-substrate",
+ "pallet-evm-collection",
  "pallet-evm-contract-helpers",
  "pallet-evm-migration",
  "pallet-evm-transaction-payment",
@@ -12845,6 +12869,7 @@
  "pallet-ethereum",
  "pallet-evm",
  "pallet-evm-coder-substrate",
+ "pallet-evm-collection",
  "pallet-evm-contract-helpers",
  "pallet-evm-migration",
  "pallet-evm-transaction-payment",
modifiedMakefilediffbeforeafterboth
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,9 @@
 CONTRACT_HELPERS_STUBS=./pallets/evm-contract-helpers/src/stubs/
 CONTRACT_HELPERS_ABI=./tests/src/eth/util/contractHelpersAbi.json
 
+COLLECTION_STUBS=./pallets/evm-collection/src/stubs/
+COLLECTION_ABI=./tests/src/eth/collectionAbi.json
+
 TESTS_API=./tests/src/eth/api/
 
 .PHONY: regenerate_solidity
@@ -32,6 +35,10 @@
 	PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_iface OUTPUT=$(TESTS_API)/$@ ./.maintain/scripts/generate_sol.sh
 	PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_impl OUTPUT=$(CONTRACT_HELPERS_STUBS)/$@ ./.maintain/scripts/generate_sol.sh
 
+Collection.sol:
+	PACKAGE=pallet-evm-collection NAME=eth::contract_helpers_iface OUTPUT=$(TESTS_API)/$@ ./.maintain/scripts/generate_sol.sh
+	PACKAGE=pallet-evm-collection NAME=eth::contract_helpers_impl OUTPUT=$(COLLECTION_STUBS)/$@ ./.maintain/scripts/generate_sol.sh
+
 UniqueFungible: UniqueFungible.sol
 	INPUT=$(FUNGIBLE_EVM_STUBS)/$< OUTPUT=$(FUNGIBLE_EVM_STUBS)/UniqueFungible.raw ./.maintain/scripts/compile_stub.sh
 	INPUT=$(FUNGIBLE_EVM_STUBS)/$< OUTPUT=$(FUNGIBLE_EVM_ABI) ./.maintain/scripts/generate_abi.sh
@@ -44,7 +51,11 @@
 	INPUT=$(CONTRACT_HELPERS_STUBS)/$< OUTPUT=$(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw ./.maintain/scripts/compile_stub.sh
 	INPUT=$(CONTRACT_HELPERS_STUBS)/$< OUTPUT=$(CONTRACT_HELPERS_ABI) ./.maintain/scripts/generate_abi.sh
 
-evm_stubs: UniqueFungible UniqueNFT ContractHelpers
+Collection: Collection.sol
+	INPUT=$(COLLECTION_STUBS)/$< OUTPUT=$(COLLECTION_STUBS)/Collection.raw ./.maintain/scripts/compile_stub.sh
+	INPUT=$(COLLECTION_STUBS)/$< OUTPUT=$(COLLECTION_ABI) ./.maintain/scripts/generate_abi.sh
+
+evm_stubs: UniqueFungible UniqueNFT ContractHelpers Collection
 
 .PHONY: _bench
 _bench:
addedpallets/evm-collection/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-collection/Cargo.toml
@@ -0,0 +1,49 @@
+[package]
+name = "pallet-evm-collection"
+version = "0.1.0"
+license = "GPLv3"
+edition = "2021"
+
+[dependencies]
+scale-info = { version = "2.0.1", default-features = false, features = [
+    "derive",
+] }
+ethereum = { version = "0.12.0", default-features = false }
+log = { default-features = false, version = "0.4.14" }
+
+# Substrate
+frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+
+# Unique
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.21-logs" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.21-logs" }
+
+# Locals
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+pallet-common = { default-features = false, path = '../../pallets/common' }
+pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
+pallet-nonfungible = { default-features = false, path = '../../pallets/nonfungible' }
+up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '3.1.2'
+
+[features]
+default = ["std"]
+std = [
+    "frame-support/std",
+    "frame-system/std",
+    "sp-runtime/std",
+    "sp-std/std",
+    "sp-core/std",
+    "evm-coder/std",
+    "pallet-evm-coder-substrate/std",
+    "pallet-evm/std",
+]
addedpallets/evm-collection/src/eth.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-collection/src/eth.rs
@@ -0,0 +1,169 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use core::marker::PhantomData;
+use evm_coder::{abi::AbiWriter, execution::*, generate_stubgen, solidity_interface, types::*, ToLog};
+use ethereum as _;
+use pallet_common::CollectionById;
+use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
+use pallet_evm::{
+	ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure,
+	account::CrossAccountId, Pallet as PalletEvm,
+};
+use sp_core::H160;
+use up_data_structs::{
+	CreateCollectionData, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
+	MAX_COLLECTION_NAME_LENGTH,
+};
+use crate::{Config, Pallet};
+use frame_support::traits::Get;
+
+use sp_std::vec::Vec;
+use alloc::format;
+
+struct EvmCollection<T: Config>(SubstrateRecorder<T>);
+impl<T: Config> WithRecorder<T> for EvmCollection<T> {
+	fn recorder(&self) -> &SubstrateRecorder<T> {
+		&self.0
+	}
+
+	fn into_recorder(self) -> SubstrateRecorder<T> {
+		self.0
+	}
+}
+
+#[derive(ToLog)]
+pub enum CollectionEvent {
+	CollectionCreated {
+		#[indexed]
+		owner: address,
+		#[indexed]
+		collection_id: address,
+	},
+}
+
+#[solidity_interface(name = "Collection")]
+impl<T: Config> EvmCollection<T> {
+	fn create_721_collection(
+		&self,
+		caller: caller,
+		name: string,
+		description: string,
+		token_prefix: string,
+	) -> Result<address> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let name = name
+			.encode_utf16()
+			.collect::<Vec<u16>>()
+			.try_into()
+			.map_err(|_| error_feild_too_long("name", MAX_COLLECTION_NAME_LENGTH))?;
+		let description = description
+			.encode_utf16()
+			.collect::<Vec<u16>>()
+			.try_into()
+			.map_err(|_| error_feild_too_long("description", MAX_COLLECTION_DESCRIPTION_LENGTH))?;
+		let token_prefix = token_prefix
+			.into_bytes()
+			.try_into()
+			.map_err(|_| error_feild_too_long("token_prefix", MAX_TOKEN_PREFIX_LENGTH))?;
+
+		let data = CreateCollectionData {
+			name,
+			description,
+			token_prefix,
+			..Default::default()
+		};
+
+		let collection_id =
+			<pallet_nonfungible::Pallet<T>>::init_collection(caller.as_sub().clone(), data)
+				.map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
+
+		let address = pallet_common::eth::collection_id_to_address(collection_id);
+		<PalletEvm<T>>::deposit_log(
+			CollectionEvent::CollectionCreated {
+				owner: *caller.as_eth(),
+				collection_id: address,
+			}
+			.to_log(address),
+		);
+		Ok(address)
+	}
+
+	// fn set_sponsor(collection_id: address, sponsor: address) -> Result<void> {
+	// 	let collection_id =
+	// 		pallet_common::eth::map_eth_to_id(&collection_id).ok_or(Error::Revert("".into()))?;
+	// 	let mut collection = <CollectionById<T>>::get(collection_id).ok_or(Error::Revert("".into()))?;
+	// 	let sponsor = T::CrossAccountId::from_eth(sponsor);
+	// 	collection.sponsorship = SponsorshipState::Unconfirmed(sponsor.as_sub().clone());
+	// 	<CollectionById<T>>::insert(collection_id, collection);
+	// 	Ok(())
+	// }
+
+	// fn set_offchain_shema(shema: string) -> Result<void> {
+	// 	Ok(())
+	// }
+
+	// fn set_const_on_chain_schema(shema: string) -> Result<void> {
+	// 	Ok(())
+	// }
+
+	// fn set_variable_on_chain_schema(shema: string) -> Result<void> {
+	// 	Ok(())
+	// }
+
+	// fn set_limits(limits: string) -> Result<void> {
+	// 	Ok(())
+	// }
+}
+
+fn error_feild_too_long(feild: &str, bound: u32) -> Error {
+	Error::Revert(format!("{} is too long. Max length is {}.", feild, bound))
+}
+
+pub struct CollectionOnMethodCall<T: Config>(PhantomData<*const T>);
+impl<T: Config> OnMethodCall<T> for CollectionOnMethodCall<T> {
+	fn is_reserved(contract: &sp_core::H160) -> bool {
+		contract == &T::ContractAddress::get()
+	}
+
+	fn is_used(contract: &sp_core::H160) -> bool {
+		contract == &T::ContractAddress::get()
+	}
+
+	fn call(
+		source: &sp_core::H160,
+		target: &sp_core::H160,
+		gas_left: u64,
+		input: &[u8],
+		value: sp_core::U256,
+	) -> Option<PrecompileResult> {
+		// TODO: Extract to another OnMethodCall handler
+		if target != &T::ContractAddress::get() {
+			return None;
+		}
+
+		let helpers = EvmCollection::<T>(SubstrateRecorder::<T>::new(gas_left));
+		pallet_evm_coder_substrate::call(*source, helpers, value, input)
+	}
+
+	fn get_code(contract: &sp_core::H160) -> Option<Vec<u8>> {
+		(contract == &T::ContractAddress::get())
+			.then(|| include_bytes!("./stubs/Collection.raw").to_vec())
+	}
+}
+
+generate_stubgen!(collection_impl, CollectionCall<()>, true);
+generate_stubgen!(collection_iface, CollectionCall<()>, false);
addedpallets/evm-collection/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-collection/src/lib.rs
@@ -0,0 +1,53 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+extern crate alloc;
+
+use codec::{Decode, Encode, MaxEncodedLen};
+pub use pallet::*;
+pub use eth::*;
+use scale_info::TypeInfo;
+pub mod eth;
+
+#[frame_support::pallet]
+pub mod pallet {
+	pub use super::*;
+	use evm_coder::execution::Result;
+	use frame_support::pallet_prelude::*;
+	use sp_core::H160;
+
+	#[pallet::config]
+	pub trait Config:
+		frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::account::Config + pallet_nonfungible::Config
+	{
+		type ContractAddress: Get<H160>;
+	}
+
+	#[pallet::error]
+	pub enum Error<T> {
+		/// This method is only executable by owner
+		NoPermission,
+	}
+
+	#[pallet::pallet]
+	// #[pallet::generate_store(pub(super) trait Store)]
+	pub struct Pallet<T>(_);
+
+
+	impl<T: Config> Pallet<T> {}
+}
addedpallets/evm-collection/src/stubs/Collection.rawdiffbeforeafterboth

binary blob — no preview

addedpallets/evm-collection/src/stubs/Collection.soldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-collection/src/stubs/Collection.sol
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+contract Dummy {
+	uint8 dummy;
+	string stub_error = "this contract is implemented in native";
+}
+
+contract ERC165 is Dummy {
+	function supportsInterface(bytes4 interfaceID)
+		external
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		interfaceID;
+		return true;
+	}
+}
+
+// Selector: ee5467a8
+contract Collection is Dummy, ERC165 {
+	// Selector: contractOwner(address) 5152b14c
+	function contractOwner(address contractAddress)
+		public
+		view
+		returns (address)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+
+	// Selector: sponsoringEnabled(address) 6027dc61
+	function sponsoringEnabled(address contractAddress)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return false;
+	}
+
+	// Deprecated
+	//
+	// Selector: toggleSponsoring(address,bool) fcac6d86
+	function toggleSponsoring(address contractAddress, bool enabled) public {
+		require(false, stub_error);
+		contractAddress;
+		enabled;
+		dummy = 0;
+	}
+
+	// Selector: setSponsoringMode(address,uint8) fde8a560
+	function setSponsoringMode(address contractAddress, uint8 mode) public {
+		require(false, stub_error);
+		contractAddress;
+		mode;
+		dummy = 0;
+	}
+
+	// Selector: sponsoringMode(address) b70c7267
+	function sponsoringMode(address contractAddress)
+		public
+		view
+		returns (uint8)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return 0;
+	}
+
+	// Selector: setSponsoringRateLimit(address,uint32) 77b6c908
+	function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)
+		public
+	{
+		require(false, stub_error);
+		contractAddress;
+		rateLimit;
+		dummy = 0;
+	}
+
+	// Selector: getSponsoringRateLimit(address) 610cfabd
+	function getSponsoringRateLimit(address contractAddress)
+		public
+		view
+		returns (uint32)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return 0;
+	}
+
+	// Selector: allowed(address,address) 5c658165
+	function allowed(address contractAddress, address user)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		user;
+		dummy;
+		return false;
+	}
+
+	// Selector: allowlistEnabled(address) c772ef6c
+	function allowlistEnabled(address contractAddress)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return false;
+	}
+
+	// Selector: toggleAllowlist(address,bool) 36de20f5
+	function toggleAllowlist(address contractAddress, bool enabled) public {
+		require(false, stub_error);
+		contractAddress;
+		enabled;
+		dummy = 0;
+	}
+
+	// Selector: toggleAllowed(address,address,bool) 4706cc1c
+	function toggleAllowed(
+		address contractAddress,
+		address user,
+		bool allowed
+	) public {
+		require(false, stub_error);
+		contractAddress;
+		user;
+		allowed;
+		dummy = 0;
+	}
+
+	// Selector: create721Collection(string,string,string) 951c0151
+	function create721Collection(
+		string memory name,
+		string memory description,
+		string memory tokenPrefix
+	) public view returns (address) {
+		require(false, stub_error);
+		name;
+		description;
+		tokenPrefix;
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+}
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -20,20 +20,15 @@
 use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
 use pallet_evm::{
 	ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure,
-	account::CrossAccountId, Pallet as PalletEvm
+	account::CrossAccountId
 };
 use sp_core::H160;
-use up_data_structs::{
-	CreateCollectionData, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
-	MAX_COLLECTION_NAME_LENGTH,
-};
 use crate::{
 	AllowlistEnabled, Config, Owner, Pallet, SponsorBasket, SponsoringRateLimit, SponsoringModeT,
 };
 use frame_support::traits::Get;
 use up_sponsorship::SponsorshipHandler;
 use sp_std::vec::Vec;
-use alloc::format;
 
 struct ContractHelpers<T: Config>(SubstrateRecorder<T>);
 impl<T: Config> WithRecorder<T> for ContractHelpers<T> {
@@ -142,56 +137,6 @@
 		<Pallet<T>>::toggle_allowed(contract_address, user, allowed);
 		Ok(())
 	}
-
-	fn create_721_collection(
-		&self,
-		caller: caller,
-		name: string,
-		description: string,
-		token_prefix: string,
-	) -> Result<address> {
-		let caller = T::CrossAccountId::from_eth(caller);
-		let name = name
-			.encode_utf16()
-			.collect::<Vec<u16>>()
-			.try_into()
-			.map_err(|_| error_feild_too_long("name", MAX_COLLECTION_NAME_LENGTH))?;
-		let description = description
-			.encode_utf16()
-			.collect::<Vec<u16>>()
-			.try_into()
-			.map_err(|_| error_feild_too_long("description", MAX_COLLECTION_DESCRIPTION_LENGTH))?;
-		let token_prefix = token_prefix
-			.into_bytes()
-			.try_into()
-			.map_err(|_| error_feild_too_long("token_prefix", MAX_TOKEN_PREFIX_LENGTH))?;
-
-		let data = CreateCollectionData {
-			name,
-			description,
-			token_prefix,
-			..Default::default()
-		};
-
-		let collection_id =
-			<pallet_nonfungible::Pallet<T>>::init_collection(caller.as_sub().clone(), data)
-				.map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
-
-		let address = pallet_common::eth::collection_id_to_address(collection_id);
-
-		<PalletEvm<T>>::deposit_log(
-			ContractHelperEvent::CollectionCreated {
-				owner: *caller.as_eth(),
-				collection_id: address,
-			}
-			.to_log(address),
-		);
-		Ok(address)
-	}
-}
-
-fn error_feild_too_long(feild: &str, bound: u32) -> Error {
-	Error::Revert(format!("{} is too long. Max length is {}.", feild, bound))
 }
 
 pub struct HelpersOnMethodCall<T: Config>(PhantomData<*const T>);
modifiedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/lib.rs
+++ b/pallets/evm-contract-helpers/src/lib.rs
@@ -16,9 +16,6 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
-#[macro_use(format)]
-extern crate alloc;
-
 use codec::{Decode, Encode, MaxEncodedLen};
 pub use pallet::*;
 pub use eth::*;
addedpallets/evm-contract-helpers/src/stubs/Collection.soldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-contract-helpers/src/stubs/Collection.sol
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+contract Dummy {
+	uint8 dummy;
+	string stub_error = "this contract is implemented in native";
+}
+
+contract ERC165 is Dummy {
+	function supportsInterface(bytes4 interfaceID)
+		external
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		interfaceID;
+		return true;
+	}
+}
+
+// Selector: 61f17ed8
+contract ContractHelpers is Dummy, ERC165 {
+	// Selector: contractOwner(address) 5152b14c
+	function contractOwner(address contractAddress)
+		public
+		view
+		returns (address)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+
+	// Selector: sponsoringEnabled(address) 6027dc61
+	function sponsoringEnabled(address contractAddress)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return false;
+	}
+
+	// Deprecated
+	//
+	// Selector: toggleSponsoring(address,bool) fcac6d86
+	function toggleSponsoring(address contractAddress, bool enabled) public {
+		require(false, stub_error);
+		contractAddress;
+		enabled;
+		dummy = 0;
+	}
+
+	// Selector: setSponsoringMode(address,uint8) fde8a560
+	function setSponsoringMode(address contractAddress, uint8 mode) public {
+		require(false, stub_error);
+		contractAddress;
+		mode;
+		dummy = 0;
+	}
+
+	// Selector: sponsoringMode(address) b70c7267
+	function sponsoringMode(address contractAddress)
+		public
+		view
+		returns (uint8)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return 0;
+	}
+
+	// Selector: setSponsoringRateLimit(address,uint32) 77b6c908
+	function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)
+		public
+	{
+		require(false, stub_error);
+		contractAddress;
+		rateLimit;
+		dummy = 0;
+	}
+
+	// Selector: getSponsoringRateLimit(address) 610cfabd
+	function getSponsoringRateLimit(address contractAddress)
+		public
+		view
+		returns (uint32)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return 0;
+	}
+
+	// Selector: allowed(address,address) 5c658165
+	function allowed(address contractAddress, address user)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		user;
+		dummy;
+		return false;
+	}
+
+	// Selector: allowlistEnabled(address) c772ef6c
+	function allowlistEnabled(address contractAddress)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return false;
+	}
+
+	// Selector: toggleAllowlist(address,bool) 36de20f5
+	function toggleAllowlist(address contractAddress, bool enabled) public {
+		require(false, stub_error);
+		contractAddress;
+		enabled;
+		dummy = 0;
+	}
+
+	// Selector: toggleAllowed(address,address,bool) 4706cc1c
+	function toggleAllowed(
+		address contractAddress,
+		address user,
+		bool allowed
+	) public {
+		require(false, stub_error);
+		contractAddress;
+		user;
+		allowed;
+		dummy = 0;
+	}
+
+	// Selector: create721Collection(string,string,string) 951c0151
+	function create721Collection(
+		string memory name,
+		string memory description,
+		string memory tokenPrefix
+	) public view returns (address) {
+		require(false, stub_error);
+		name;
+		description;
+		tokenPrefix;
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+
+	// Selector: setSponsor(address,address) f01fba93
+	function setSponsor(address collectionId, address sponsor) public pure {
+		require(false, stub_error);
+		collectionId;
+		sponsor;
+	}
+
+	// Selector: setOffchainShema(string) c3aa408b
+	function setOffchainShema(string memory shema) public pure {
+		require(false, stub_error);
+		shema;
+	}
+
+	// Selector: setConstOnChainSchema(string) b284d8df
+	function setConstOnChainSchema(string memory shema) public pure {
+		require(false, stub_error);
+		shema;
+	}
+
+	// Selector: setVariableOnChainSchema(string) 7c5f0fea
+	function setVariableOnChainSchema(string memory shema) public pure {
+		require(false, stub_error);
+		shema;
+	}
+
+	// Selector: setLimits(string) 72cb345d
+	function setLimits(string memory limits) public pure {
+		require(false, stub_error);
+		limits;
+	}
+}
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
+++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
@@ -21,7 +21,7 @@
 	}
 }
 
-// Selector: ee5467a8
+// Selector: 7b4866f9
 contract ContractHelpers is Dummy, ERC165 {
 	// Selector: contractOwner(address) 5152b14c
 	function contractOwner(address contractAddress)
@@ -143,19 +143,5 @@
 		user;
 		allowed;
 		dummy = 0;
-	}
-
-	// Selector: create721Collection(string,string,string) 951c0151
-	function create721Collection(
-		string memory name,
-		string memory description,
-		string memory tokenPrefix
-	) public view returns (address) {
-		require(false, stub_error);
-		name;
-		description;
-		tokenPrefix;
-		dummy;
-		return 0x0000000000000000000000000000000000000000;
 	}
 }
modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -74,6 +74,7 @@
     'pallet-evm/std',
     'pallet-evm-migration/std',
     'pallet-evm-contract-helpers/std',
+    'pallet-evm-collection/std',
     'pallet-evm-transaction-payment/std',
     'pallet-evm-coder-substrate/std',
     'pallet-ethereum/std',
@@ -417,6 +418,7 @@
 pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.21", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }
 pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false }
 pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
+pallet-evm-collection = { path = '../../pallets/evm-collection', default-features = false }
 pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
 pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
 pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.21-logs" }
modifiedruntime/opal/src/lib.rsdiffbeforeafterboth
--- a/runtime/opal/src/lib.rs
+++ b/runtime/opal/src/lib.rs
@@ -49,7 +49,7 @@
 // A few exports that help ease life for downstream crates.
 pub use pallet_balances::Call as BalancesCall;
 pub use pallet_evm::{
-	EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,
+	EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _, OnMethodCall,
 };
 pub use frame_support::{
 	construct_runtime, match_types,
@@ -306,6 +306,7 @@
 		pallet_evm_migration::OnMethodCall<Self>,
 		pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
 		CollectionDispatchT<Self>,
+		pallet_evm_collection::CollectionOnMethodCall<Self>,
 	);
 	type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
 	type ChainId = ChainId;
@@ -974,6 +975,11 @@
 	pub const HelpersContractAddress: H160 = H160([
 		0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
 	]);
+	
+	// 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
+	pub const EvmCollectionAddress: H160 = H160([
+		0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
+	]);
 }
 
 impl pallet_evm_contract_helpers::Config for Runtime {
@@ -981,6 +987,10 @@
 	type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
 }
 
+impl pallet_evm_collection::Config for Runtime {
+	type ContractAddress = EvmCollectionAddress;
+}
+
 construct_runtime!(
 	pub enum Runtime where
 		Block = Block,
@@ -1033,6 +1043,7 @@
 		EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
 		EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
 		EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
+		EvmCollection: pallet_evm_collection::{Pallet} = 154,
 	}
 );
 
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -74,6 +74,7 @@
     'pallet-evm/std',
     'pallet-evm-migration/std',
     'pallet-evm-contract-helpers/std',
+    'pallet-evm-collection/std',
     'pallet-evm-transaction-payment/std',
     'pallet-evm-coder-substrate/std',
     'pallet-ethereum/std',
@@ -422,6 +423,7 @@
 pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.21", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }
 pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false }
 pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
+pallet-evm-collection = { path = '../../pallets/evm-collection', default-features = false }
 pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
 pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
 pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.21-logs" }
modifiedruntime/quartz/src/lib.rsdiffbeforeafterboth
79};79};
80use smallvec::smallvec;80use smallvec::smallvec;
81use codec::{Encode, Decode};81use codec::{Encode, Decode};
82use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping};82use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall};
83use fp_rpc::TransactionStatus;83use fp_rpc::TransactionStatus;
84use sp_runtime::{84use sp_runtime::{
85 traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating},85 traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating},
278 pallet_evm_migration::OnMethodCall<Self>,278 pallet_evm_migration::OnMethodCall<Self>,
279 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,279 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
280 CollectionDispatchT<Self>,280 CollectionDispatchT<Self>,
281 pallet_evm_collection::CollectionOnMethodCall<Self>,
281 );282 );
282 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;283 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
283 type ChainId = ChainId;284 type ChainId = ChainId;
952 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,953 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
953 ]);954 ]);
955
956 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
957 pub const EvmCollectionAddress: H160 = H160([
958 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
959 ]);
954}960}
955961
956impl pallet_evm_contract_helpers::Config for Runtime {962impl pallet_evm_contract_helpers::Config for Runtime {
957 type ContractAddress = HelpersContractAddress;963 type ContractAddress = HelpersContractAddress;
958 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;964 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
959}965}
966
967impl pallet_evm_collection::Config for Runtime {
968 type ContractAddress = EvmCollectionAddress;
969}
960970
961construct_runtime!(971construct_runtime!(
962 pub enum Runtime where972 pub enum Runtime where
1010 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,1020 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
1011 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,1021 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
1012 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,1022 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
1023 EvmCollection: pallet_evm_collection::{Pallet} = 154,
1013 }1024 }
1014);1025);
10151026
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -75,6 +75,7 @@
     'pallet-evm/std',
     'pallet-evm-migration/std',
     'pallet-evm-contract-helpers/std',
+    'pallet-evm-collection/std',
     'pallet-evm-transaction-payment/std',
     'pallet-evm-coder-substrate/std',
     'pallet-ethereum/std',
@@ -414,6 +415,7 @@
 pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.21", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }
 pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false }
 pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
+pallet-evm-collection = { path = '../../pallets/evm-collection', default-features = false }
 pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
 pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
 pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.21-logs" }
modifiedruntime/unique/src/lib.rsdiffbeforeafterboth
--- a/runtime/unique/src/lib.rs
+++ b/runtime/unique/src/lib.rs
@@ -49,7 +49,7 @@
 // A few exports that help ease life for downstream crates.
 pub use pallet_balances::Call as BalancesCall;
 pub use pallet_evm::{
-	EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,
+	EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _, OnMethodCall,
 };
 pub use frame_support::{
 	construct_runtime, match_types,
@@ -282,6 +282,7 @@
 		pallet_evm_migration::OnMethodCall<Self>,
 		pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
 		CollectionDispatchT<Self>,
+		pallet_evm_collection::CollectionOnMethodCall<Self>,
 	);
 	type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
 	type ChainId = ChainId;
@@ -956,6 +957,11 @@
 	pub const HelpersContractAddress: H160 = H160([
 		0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
 	]);
+		
+	// 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
+	pub const EvmCollectionAddress: H160 = H160([
+		0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
+	]);
 }
 
 impl pallet_evm_contract_helpers::Config for Runtime {
@@ -963,6 +969,10 @@
 	type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
 }
 
+impl pallet_evm_collection::Config for Runtime {
+	type ContractAddress = EvmCollectionAddress;
+}
+
 construct_runtime!(
 	pub enum Runtime where
 		Block = Block,
@@ -1015,6 +1025,7 @@
 		EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
 		EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
 		EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
+		EvmCollection: pallet_evm_collection::{Pallet} = 154,
 	}
 );
 
addedtests/src/eth/api/Collection.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/api/Collection.sol
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+interface Dummy {
+
+}
+
+interface ERC165 is Dummy {
+	function supportsInterface(bytes4 interfaceID) external view returns (bool);
+}
+
+// Selector: ee5467a8
+interface Collection is Dummy, ERC165 {
+	// Selector: contractOwner(address) 5152b14c
+	function contractOwner(address contractAddress)
+		external
+		view
+		returns (address);
+
+	// Selector: sponsoringEnabled(address) 6027dc61
+	function sponsoringEnabled(address contractAddress)
+		external
+		view
+		returns (bool);
+
+	// Deprecated
+	//
+	// Selector: toggleSponsoring(address,bool) fcac6d86
+	function toggleSponsoring(address contractAddress, bool enabled) external;
+
+	// Selector: setSponsoringMode(address,uint8) fde8a560
+	function setSponsoringMode(address contractAddress, uint8 mode) external;
+
+	// Selector: sponsoringMode(address) b70c7267
+	function sponsoringMode(address contractAddress)
+		external
+		view
+		returns (uint8);
+
+	// Selector: setSponsoringRateLimit(address,uint32) 77b6c908
+	function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)
+		external;
+
+	// Selector: getSponsoringRateLimit(address) 610cfabd
+	function getSponsoringRateLimit(address contractAddress)
+		external
+		view
+		returns (uint32);
+
+	// Selector: allowed(address,address) 5c658165
+	function allowed(address contractAddress, address user)
+		external
+		view
+		returns (bool);
+
+	// Selector: allowlistEnabled(address) c772ef6c
+	function allowlistEnabled(address contractAddress)
+		external
+		view
+		returns (bool);
+
+	// Selector: toggleAllowlist(address,bool) 36de20f5
+	function toggleAllowlist(address contractAddress, bool enabled) external;
+
+	// Selector: toggleAllowed(address,address,bool) 4706cc1c
+	function toggleAllowed(
+		address contractAddress,
+		address user,
+		bool allowed
+	) external;
+
+	// Selector: create721Collection(string,string,string) 951c0151
+	function create721Collection(
+		string memory name,
+		string memory description,
+		string memory tokenPrefix
+	) external view returns (address);
+}
modifiedtests/src/eth/api/ContractHelpers.soldiffbeforeafterboth
--- a/tests/src/eth/api/ContractHelpers.sol
+++ b/tests/src/eth/api/ContractHelpers.sol
@@ -12,7 +12,7 @@
 	function supportsInterface(bytes4 interfaceID) external view returns (bool);
 }
 
-// Selector: ee5467a8
+// Selector: 7b4866f9
 interface ContractHelpers is Dummy, ERC165 {
 	// Selector: contractOwner(address) 5152b14c
 	function contractOwner(address contractAddress)
@@ -71,11 +71,4 @@
 		address user,
 		bool allowed
 	) external;
-
-	// Selector: create721Collection(string,string,string) 951c0151
-	function create721Collection(
-		string memory name,
-		string memory description,
-		string memory tokenPrefix
-	) external view returns (address);
 }
addedtests/src/eth/collectionAbi.jsondiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/collectionAbi.json
@@ -0,0 +1,172 @@
+[
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      },
+      { "internalType": "address", "name": "user", "type": "address" }
+    ],
+    "name": "allowed",
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      }
+    ],
+    "name": "allowlistEnabled",
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      }
+    ],
+    "name": "contractOwner",
+    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "string", "name": "name", "type": "string" },
+      { "internalType": "string", "name": "description", "type": "string" },
+      { "internalType": "string", "name": "tokenPrefix", "type": "string" }
+    ],
+    "name": "create721Collection",
+    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      }
+    ],
+    "name": "getSponsoringRateLimit",
+    "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      },
+      { "internalType": "uint8", "name": "mode", "type": "uint8" }
+    ],
+    "name": "setSponsoringMode",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      },
+      { "internalType": "uint32", "name": "rateLimit", "type": "uint32" }
+    ],
+    "name": "setSponsoringRateLimit",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      }
+    ],
+    "name": "sponsoringEnabled",
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      }
+    ],
+    "name": "sponsoringMode",
+    "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }
+    ],
+    "name": "supportsInterface",
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      },
+      { "internalType": "address", "name": "user", "type": "address" },
+      { "internalType": "bool", "name": "allowed", "type": "bool" }
+    ],
+    "name": "toggleAllowed",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      },
+      { "internalType": "bool", "name": "enabled", "type": "bool" }
+    ],
+    "name": "toggleAllowlist",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      {
+        "internalType": "address",
+        "name": "contractAddress",
+        "type": "address"
+      },
+      { "internalType": "bool", "name": "enabled", "type": "bool" }
+    ],
+    "name": "toggleSponsoring",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  }
+]
modifiedtests/src/eth/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/eth/createCollection.test.ts
+++ b/tests/src/eth/createCollection.test.ts
@@ -16,12 +16,12 @@
 
 import {expect} from 'chai';
 import {getCreatedCollectionCount, getDetailedCollectionInfo} from '../util/helpers';
-import {collectionIdFromAddress, contractHelpers, createEthAccountWithBalance, itWeb3} from './util/helpers';
+import {collectionHelper, collectionIdFromAddress, contractHelpers, createEthAccountWithBalance, itWeb3} from './util/helpers';
 
 describe('Create collection from EVM', () => {
   itWeb3('Create collection', async ({api, web3}) => {
     const owner = await createEthAccountWithBalance(api, web3);
-    const helpers = contractHelpers(web3, owner);
+    const helpers = collectionHelper(web3, owner);
     const collectionName = 'CollectionEVM';
     const description = 'Some description';
     const tokenPrefix = 'token prefix';
modifiedtests/src/eth/util/contractHelpersAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/util/contractHelpersAbi.json
+++ b/tests/src/eth/util/contractHelpersAbi.json
@@ -41,17 +41,6 @@
   },
   {
     "inputs": [
-      { "internalType": "string", "name": "name", "type": "string" },
-      { "internalType": "string", "name": "description", "type": "string" },
-      { "internalType": "string", "name": "tokenPrefix", "type": "string" }
-    ],
-    "name": "create721Collection",
-    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
-    "stateMutability": "view",
-    "type": "function"
-  },
-  {
-    "inputs": [
       {
         "internalType": "address",
         "name": "contractAddress",
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/eth/util/helpers.ts
+++ b/tests/src/eth/util/helpers.ts
@@ -28,6 +28,7 @@
 import config from '../../config';
 import privateKey from '../../substrate/privateKey';
 import contractHelpersAbi from './contractHelpersAbi.json';
+import collectionAbi from '../collectionAbi.json';
 import getBalance from '../../substrate/get-balance';
 import waitNewBlocks from '../../substrate/wait-new-blocks';
 
@@ -273,6 +274,16 @@
   return new web3.eth.Contract(contractHelpersAbi as any, '0x842899ECF380553E8a4de75bF534cdf6fBF64049', {from: caller, ...GAS_ARGS});
 }
 
+/** 
+ * pallet evm_collection
+ * @param web3 
+ * @param caller - eth address
+ * @returns 
+ */
+export function collectionHelper(web3: Web3, caller: string) {
+  return new web3.eth.Contract(collectionAbi as any, '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f', {from: caller, ...GAS_ARGS});
+}
+
 /**
  * Execute ethereum method call using substrate account
  * @param to target contract